mirror of
https://github.com/bitwarden/browser
synced 2026-01-31 00:33:33 +00:00
feat: include callee information
This commit is contained in:
@@ -838,6 +838,7 @@ export default class MainBackground {
|
||||
this.apiService,
|
||||
this.stateProvider,
|
||||
this.configService,
|
||||
this.logService,
|
||||
);
|
||||
|
||||
this.pinService = new PinService(
|
||||
|
||||
@@ -668,6 +668,7 @@ export class ServiceContainer {
|
||||
this.apiService,
|
||||
this.stateProvider,
|
||||
this.configService,
|
||||
this.logService,
|
||||
customUserAgent,
|
||||
);
|
||||
|
||||
|
||||
@@ -1641,6 +1641,7 @@ const safeProviders: SafeProvider[] = [
|
||||
ApiServiceAbstraction,
|
||||
StateProvider,
|
||||
ConfigService,
|
||||
LogService,
|
||||
],
|
||||
}),
|
||||
safeProvider({
|
||||
|
||||
@@ -20,6 +20,7 @@ import { UserId } from "../../../types/guid";
|
||||
import { UserKey } from "../../../types/key";
|
||||
import { ConfigService } from "../../abstractions/config/config.service";
|
||||
import { Environment, EnvironmentService } from "../../abstractions/environment.service";
|
||||
import { LogService } from "../../abstractions/log.service";
|
||||
import { PlatformUtilsService } from "../../abstractions/platform-utils.service";
|
||||
import { SdkClientFactory } from "../../abstractions/sdk/sdk-client-factory";
|
||||
import { SdkLoadService } from "../../abstractions/sdk/sdk-load.service";
|
||||
@@ -49,6 +50,7 @@ describe("DefaultSdkService", () => {
|
||||
let service!: DefaultSdkService;
|
||||
let accountService!: FakeAccountService;
|
||||
let fakeStateProvider!: FakeStateProvider;
|
||||
let logService!: MockProxy<LogService>;
|
||||
let apiService!: MockProxy<ApiService>;
|
||||
|
||||
beforeEach(async () => {
|
||||
@@ -64,6 +66,7 @@ describe("DefaultSdkService", () => {
|
||||
const mockUserId = Utils.newGuid() as UserId;
|
||||
accountService = mockAccountServiceWith(mockUserId);
|
||||
fakeStateProvider = new FakeStateProvider(accountService);
|
||||
logService = mock<LogService>();
|
||||
configService = mock<ConfigService>();
|
||||
|
||||
configService.serverConfig$ = new BehaviorSubject(null);
|
||||
@@ -82,6 +85,7 @@ describe("DefaultSdkService", () => {
|
||||
apiService,
|
||||
fakeStateProvider,
|
||||
configService,
|
||||
logService,
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -23,11 +23,8 @@ import { KeyService, KdfConfigService, KdfConfig, KdfType } from "@bitwarden/key
|
||||
import {
|
||||
PasswordManagerClient,
|
||||
ClientSettings,
|
||||
EventDefinition,
|
||||
FieldValue,
|
||||
DeviceType as SdkDeviceType,
|
||||
Span,
|
||||
SpanDefinition,
|
||||
TokenProvider,
|
||||
TracingLevel,
|
||||
UnsignedSharedKey,
|
||||
@@ -40,6 +37,7 @@ import { EncString } from "../../../key-management/crypto/models/enc-string";
|
||||
import { SecurityStateService } from "../../../key-management/security-state/abstractions/security-state.service";
|
||||
import { OrganizationId, UserId } from "../../../types/guid";
|
||||
import { Environment, EnvironmentService } from "../../abstractions/environment.service";
|
||||
import { LogService } from "../../abstractions/log.service";
|
||||
import { PlatformUtilsService } from "../../abstractions/platform-utils.service";
|
||||
import { SdkClientFactory } from "../../abstractions/sdk/sdk-client-factory";
|
||||
import { SdkLoadService } from "../../abstractions/sdk/sdk-load.service";
|
||||
@@ -55,34 +53,34 @@ import { StateProvider } from "../../state";
|
||||
|
||||
import { initializeState } from "./client-managed-state";
|
||||
|
||||
const UserClientSpan = SdkLoadService.WithSdk(
|
||||
() =>
|
||||
new SpanDefinition("userClient$", "DefaultSdkService", TracingLevel.Info, [
|
||||
"userId",
|
||||
"hasOverride",
|
||||
]),
|
||||
);
|
||||
// const UserClientSpan = SdkLoadService.WithSdk(
|
||||
// () =>
|
||||
// new SpanDefinition("userClient$", "DefaultSdkService", TracingLevel.Info, [
|
||||
// "userId",
|
||||
// "hasOverride",
|
||||
// ]),
|
||||
// );
|
||||
|
||||
const InitializeClientSpan = SdkLoadService.WithSdk(
|
||||
// TODO: We can remove userId because it's already in the parent span
|
||||
() => new SpanDefinition("initializeClient", "DefaultSdkService", TracingLevel.Info, ["userId"]),
|
||||
);
|
||||
// const InitializeClientSpan = SdkLoadService.WithSdk(
|
||||
// // TODO: We can remove userId because it's already in the parent span
|
||||
// () => new SpanDefinition("initializeClient", "DefaultSdkService", TracingLevel.Info, ["userId"]),
|
||||
// );
|
||||
|
||||
const UserCryptoInitializedEvent = SdkLoadService.WithSdk(
|
||||
() => new EventDefinition("User crypto initialized", "DefaultSdkService", TracingLevel.Info, []),
|
||||
);
|
||||
// const UserCryptoInitializedEvent = SdkLoadService.WithSdk(
|
||||
// () => new EventDefinition("User crypto initialized", "DefaultSdkService", TracingLevel.Info, []),
|
||||
// );
|
||||
|
||||
const OrgCryptoInitializedEvent = SdkLoadService.WithSdk(
|
||||
() => new EventDefinition("Org crypto initialized", "DefaultSdkService", TracingLevel.Info, []),
|
||||
);
|
||||
// const OrgCryptoInitializedEvent = SdkLoadService.WithSdk(
|
||||
// () => new EventDefinition("Org crypto initialized", "DefaultSdkService", TracingLevel.Info, []),
|
||||
// );
|
||||
|
||||
const ClientStateInitializedEvent = SdkLoadService.WithSdk(
|
||||
() => new EventDefinition("Client state initialized", "DefaultSdkService", TracingLevel.Info, []),
|
||||
);
|
||||
// const ClientStateInitializedEvent = SdkLoadService.WithSdk(
|
||||
// () => new EventDefinition("Client state initialized", "DefaultSdkService", TracingLevel.Info, []),
|
||||
// );
|
||||
|
||||
const FeatureFlagsLoadedEvent = SdkLoadService.WithSdk(
|
||||
() => new EventDefinition("Feature flags loaded", "DefaultSdkService", TracingLevel.Info, []),
|
||||
);
|
||||
// const FeatureFlagsLoadedEvent = SdkLoadService.WithSdk(
|
||||
// () => new EventDefinition("Feature flags loaded", "DefaultSdkService", TracingLevel.Info, []),
|
||||
// );
|
||||
|
||||
// A symbol that represents an overridden client that is explicitly set to undefined,
|
||||
// blocking the creation of an internal client for that user.
|
||||
@@ -142,11 +140,14 @@ export class DefaultSdkService implements SdkService {
|
||||
private apiService: ApiService,
|
||||
private stateProvider: StateProvider,
|
||||
private configService: ConfigService,
|
||||
private logService: LogService,
|
||||
private userAgent: string | null = null,
|
||||
) {}
|
||||
|
||||
userClient$(userId: UserId): Observable<Rc<PasswordManagerClient>> {
|
||||
const span = UserClientSpan.requiredValue.enter([new FieldValue("userId", userId)]);
|
||||
const span = this.logService.span("userClient$", TracingLevel.Info, [
|
||||
new FieldValue("userId", userId),
|
||||
]);
|
||||
return this.sdkClientOverrides.pipe(
|
||||
takeWhile((clients) => clients[userId] !== UnsetClient, false),
|
||||
map((clients) => {
|
||||
@@ -320,7 +321,10 @@ export class DefaultSdkService implements SdkService {
|
||||
orgKeys: Record<OrganizationId, EncString>,
|
||||
parent: Span,
|
||||
) {
|
||||
using span = (await InitializeClientSpan).enter_with_parent(parent, [
|
||||
// using span = (await InitializeClientSpan).enter_with_parent(parent, [
|
||||
// new FieldValue("userId", userId),
|
||||
// ]);
|
||||
using span = this.logService.span("initializeClient", TracingLevel.Info, [
|
||||
new FieldValue("userId", userId),
|
||||
]);
|
||||
|
||||
@@ -340,7 +344,14 @@ export class DefaultSdkService implements SdkService {
|
||||
},
|
||||
accountCryptographicState: accountCryptographicState,
|
||||
});
|
||||
span.event(await UserCryptoInitializedEvent, `User crypto initialized for user`);
|
||||
// span.event(await UserCryptoInitializedEvent, `User crypto initialized for user`);
|
||||
this.logService.event(
|
||||
span,
|
||||
"cryptoInitialized",
|
||||
`User crypto initialized for user`,
|
||||
TracingLevel.Info,
|
||||
[],
|
||||
);
|
||||
|
||||
// We initialize the org crypto even if the org_keys are
|
||||
// null to make sure any existing org keys are cleared.
|
||||
@@ -349,14 +360,32 @@ export class DefaultSdkService implements SdkService {
|
||||
Object.entries(orgKeys).map(([k, v]) => [asUuid(k), v.toJSON() as UnsignedSharedKey]),
|
||||
),
|
||||
});
|
||||
span.event(await OrgCryptoInitializedEvent, `Org crypto initialized for user`);
|
||||
this.logService.event(
|
||||
span,
|
||||
"orgCryptoInitialized",
|
||||
`Org crypto initialized for user`,
|
||||
TracingLevel.Info,
|
||||
[],
|
||||
);
|
||||
|
||||
// Initialize the SDK managed database and the client managed repositories.
|
||||
await initializeState(userId, client.platform().state(), this.stateProvider);
|
||||
span.event(await ClientStateInitializedEvent, "Client state initialized");
|
||||
this.logService.event(
|
||||
span,
|
||||
"clientStateInitialized",
|
||||
`Client state initialized`,
|
||||
TracingLevel.Info,
|
||||
[],
|
||||
);
|
||||
|
||||
await this.loadFeatureFlags(client);
|
||||
span.event(await FeatureFlagsLoadedEvent, "Feature flags loaded");
|
||||
this.logService.event(
|
||||
span,
|
||||
"featureFlagsLoaded",
|
||||
`Feature flags loaded`,
|
||||
TracingLevel.Info,
|
||||
[],
|
||||
);
|
||||
}
|
||||
|
||||
private async loadFeatureFlags(client: PasswordManagerClient) {
|
||||
|
||||
@@ -1,14 +1,81 @@
|
||||
// import { parse } from "stacktrace-parser";
|
||||
import StackTrace from "stacktrace-js";
|
||||
|
||||
import {
|
||||
EventDefinition,
|
||||
FieldValue,
|
||||
Span,
|
||||
SpanDefinition,
|
||||
TracingLevel,
|
||||
} from "@bitwarden/sdk-internal";
|
||||
|
||||
import { LogLevel } from "./log-level";
|
||||
import { LogService } from "./log.service";
|
||||
|
||||
export class ConsoleLogService implements LogService {
|
||||
protected timersMap: Map<string, [number, number]> = new Map();
|
||||
protected spanDefinitions = new Map<string, SpanDefinition>();
|
||||
protected eventDefinitions = new Map<string, EventDefinition>();
|
||||
|
||||
constructor(
|
||||
protected isDev: boolean,
|
||||
protected filter: ((level: LogLevel) => boolean) | null = null,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Creates a new span.
|
||||
* @param name Name of the span to create. Must be unique in the application.
|
||||
* // TODO: Consider creating the name as we do state KeyDefinitions.
|
||||
*/
|
||||
span(name: string, level: TracingLevel, fields: FieldValue[]): Span {
|
||||
let definition = this.spanDefinitions.get(name);
|
||||
if (!definition) {
|
||||
// TODO: A better way to get the caller info would be to use Webpack to modify
|
||||
// the code calling logService.span(...) at compile time to inject the file, line, and function name.
|
||||
const stack = StackTrace.getSync();
|
||||
const callee = stack[1];
|
||||
definition = new SpanDefinition(
|
||||
name,
|
||||
"",
|
||||
level,
|
||||
fields.map((f) => f.name),
|
||||
callee.fileName,
|
||||
callee.lineNumber,
|
||||
callee.functionName,
|
||||
);
|
||||
this.spanDefinitions.set(name, definition);
|
||||
}
|
||||
return definition.enter(fields);
|
||||
}
|
||||
|
||||
event(
|
||||
span: Span,
|
||||
name: string,
|
||||
message: string,
|
||||
level: TracingLevel,
|
||||
fields: FieldValue[],
|
||||
): void {
|
||||
let definition = this.eventDefinitions.get(name);
|
||||
if (!definition) {
|
||||
// TODO: A better way to get the caller info would be to use Webpack to modify
|
||||
// the code calling logService.event(...) at compile time to inject the file, line, and function name.
|
||||
const stack = StackTrace.getSync();
|
||||
const callee = stack[1];
|
||||
|
||||
definition = new EventDefinition(
|
||||
name,
|
||||
callee.functionName ?? "",
|
||||
level,
|
||||
fields.map((f) => f.name),
|
||||
callee.fileName,
|
||||
callee.lineNumber,
|
||||
callee.functionName,
|
||||
);
|
||||
this.eventDefinitions.set(name, definition);
|
||||
}
|
||||
span.event(definition, message);
|
||||
}
|
||||
|
||||
debug(message?: any, ...optionalParams: any[]) {
|
||||
if (!this.isDev) {
|
||||
return;
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
import type { FieldValue, Span, TracingLevel } from "@bitwarden/sdk-internal";
|
||||
|
||||
import { LogLevel } from "./log-level";
|
||||
|
||||
export abstract class LogService {
|
||||
abstract span(name: string, level: TracingLevel, fields: FieldValue[]): Span;
|
||||
abstract event(
|
||||
span: Span,
|
||||
name: string,
|
||||
message: string,
|
||||
level: TracingLevel,
|
||||
fields: FieldValue[],
|
||||
): void;
|
||||
abstract debug(message?: any, ...optionalParams: any[]): void;
|
||||
abstract info(message?: any, ...optionalParams: any[]): void;
|
||||
abstract warning(message?: any, ...optionalParams: any[]): void;
|
||||
|
||||
55
package-lock.json
generated
55
package-lock.json
generated
@@ -67,6 +67,7 @@
|
||||
"qrious": "4.0.2",
|
||||
"rxjs": "7.8.1",
|
||||
"semver": "7.7.3",
|
||||
"stacktrace-js": "2.0.2",
|
||||
"tabbable": "6.3.0",
|
||||
"tldts": "7.0.19",
|
||||
"ts-node": "10.9.2",
|
||||
@@ -20910,6 +20911,15 @@
|
||||
"is-arrayish": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/error-stack-parser": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.1.4.tgz",
|
||||
"integrity": "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"stackframe": "^1.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-abstract": {
|
||||
"version": "1.24.0",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz",
|
||||
@@ -37379,6 +37389,15 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/stack-generator": {
|
||||
"version": "2.0.10",
|
||||
"resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-2.0.10.tgz",
|
||||
"integrity": "sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"stackframe": "^1.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/stack-utils": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
|
||||
@@ -37400,6 +37419,42 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/stackframe": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz",
|
||||
"integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/stacktrace-gps": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-3.1.2.tgz",
|
||||
"integrity": "sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"source-map": "0.5.6",
|
||||
"stackframe": "^1.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/stacktrace-gps/node_modules/source-map": {
|
||||
"version": "0.5.6",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
|
||||
"integrity": "sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/stacktrace-js": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-2.0.2.tgz",
|
||||
"integrity": "sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"error-stack-parser": "^2.0.6",
|
||||
"stack-generator": "^2.0.5",
|
||||
"stacktrace-gps": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/stat-mode": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz",
|
||||
|
||||
@@ -157,8 +157,8 @@
|
||||
"@angular/platform-browser": "20.3.15",
|
||||
"@angular/platform-browser-dynamic": "20.3.15",
|
||||
"@angular/router": "20.3.15",
|
||||
"@bitwarden/sdk-internal": "0.2.0-main.409",
|
||||
"@bitwarden/commercial-sdk-internal": "0.2.0-main.409",
|
||||
"@bitwarden/sdk-internal": "0.2.0-main.409",
|
||||
"@electron/fuses": "1.8.0",
|
||||
"@emotion/css": "11.13.5",
|
||||
"@koa/multer": "4.0.0",
|
||||
@@ -201,6 +201,7 @@
|
||||
"qrious": "4.0.2",
|
||||
"rxjs": "7.8.1",
|
||||
"semver": "7.7.3",
|
||||
"stacktrace-js": "2.0.2",
|
||||
"tabbable": "6.3.0",
|
||||
"tldts": "7.0.19",
|
||||
"ts-node": "10.9.2",
|
||||
|
||||
Reference in New Issue
Block a user