Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/telemetry/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
},
"dependencies": {
"@firebase/component": "0.7.0",
"@opentelemetry/api": "1.9.0",
"@opentelemetry/api-logs": "0.203.0",
"@opentelemetry/exporter-logs-otlp-http": "0.203.0",
"@opentelemetry/resources": "2.0.1",
Expand All @@ -54,7 +55,8 @@
},
"license": "Apache-2.0",
"devDependencies": {
"@firebase/app": "0.14.1",
"@firebase/app": "0.14.2",
"@opentelemetry/sdk-trace-web": "2.1.0",
"@rollup/plugin-json": "6.1.0",
"rollup": "2.79.2",
"rollup-plugin-replace": "2.2.0",
Expand Down
45 changes: 41 additions & 4 deletions packages/telemetry/src/api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,18 @@
import { expect } from 'chai';
import { LoggerProvider } from '@opentelemetry/sdk-logs';
import { Telemetry } from './public-types';
import { trace } from '@opentelemetry/api';
import { Logger, LogRecord, SeverityNumber } from '@opentelemetry/api-logs';
import {
InMemorySpanExporter,
SimpleSpanProcessor,
WebTracerProvider
} from '@opentelemetry/sdk-trace-web';
import { captureError, flush } from './api';

const PROJECT_ID = 'my-project';
const APP_ID = 'my-appid';

const emittedLogs: LogRecord[] = [];

const fakeLoggerProvider = {
Expand All @@ -43,8 +52,8 @@ const fakeTelemetry: Telemetry = {
name: 'DEFAULT',
automaticDataCollectionEnabled: true,
options: {
projectId: 'my-project',
appId: 'my-appid'
projectId: PROJECT_ID,
appId: APP_ID
}
},
loggerProvider: fakeLoggerProvider
Expand Down Expand Up @@ -97,7 +106,7 @@ describe('Top level API', () => {
const log = emittedLogs[0];
expect(log.severityNumber).to.equal(SeverityNumber.ERROR);
expect(log.body).to.equal('a string error');
expect(log.attributes).to.be.undefined;
expect(log.attributes).to.deep.equal({});
});

it('should capture an unknown error type correctly', () => {
Expand All @@ -107,7 +116,35 @@ describe('Top level API', () => {
const log = emittedLogs[0];
expect(log.severityNumber).to.equal(SeverityNumber.ERROR);
expect(log.body).to.equal('Unknown error type: number');
expect(log.attributes).to.be.undefined;
expect(log.attributes).to.deep.equal({});
});

it('should propagate trace context', async () => {
const provider = new WebTracerProvider({
spanProcessors: [new SimpleSpanProcessor(new InMemorySpanExporter())]
});
provider.register();

trace.getTracer('test-tracer').startActiveSpan('test-span', span => {
const error = new Error('This is a test error');
error.stack = '...stack trace...';
error.name = 'TestError';

span.spanContext().traceId = 'my-trace';
span.spanContext().spanId = 'my-span';

captureError(fakeTelemetry, error);
span.end();
});

await provider.shutdown();

expect(emittedLogs[0].attributes).to.deep.equal({
'error.type': 'TestError',
'error.stack': '...stack trace...',
'logging.googleapis.com/trace': `projects/${PROJECT_ID}/traces/my-trace`,
'logging.googleapis.com/spanId': `my-span`
});
});
});

Expand Down
29 changes: 25 additions & 4 deletions packages/telemetry/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import { _getProvider, FirebaseApp, getApp } from '@firebase/app';
import { TELEMETRY_TYPE } from './constants';
import { Telemetry } from './public-types';
import { Provider } from '@firebase/component';
import { SeverityNumber } from '@opentelemetry/api-logs';
import { AnyValueMap, SeverityNumber } from '@opentelemetry/api-logs';
import { trace } from '@opentelemetry/api';
import { TelemetryService } from './service';

declare module '@firebase/component' {
Expand Down Expand Up @@ -63,24 +64,44 @@ export function getTelemetry(app: FirebaseApp = getApp()): Telemetry {
*/
export function captureError(telemetry: Telemetry, error: unknown): void {
const logger = telemetry.loggerProvider.getLogger('error-logger');

const activeSpanContext = trace.getActiveSpan()?.spanContext();
const traceAttributes = {} as AnyValueMap;
if (telemetry.app.options.projectId && activeSpanContext?.traceId) {
traceAttributes[
'logging.googleapis.com/trace'
] = `projects/${telemetry.app.options.projectId}/traces/${activeSpanContext.traceId}`;
if (activeSpanContext?.spanId) {
traceAttributes['logging.googleapis.com/spanId'] =
activeSpanContext.spanId;
}
}

if (error instanceof Error) {
logger.emit({
severityNumber: SeverityNumber.ERROR,
body: error.message,
attributes: {
'error.type': error.name || 'Error',
'error.stack': error.stack || 'No stack trace available'
'error.stack': error.stack || 'No stack trace available',
...traceAttributes
}
});
} else if (typeof error === 'string') {
logger.emit({
severityNumber: SeverityNumber.ERROR,
body: error
body: error,
attributes: {
...traceAttributes
}
});
} else {
logger.emit({
severityNumber: SeverityNumber.ERROR,
body: `Unknown error type: ${typeof error}`
body: `Unknown error type: ${typeof error}`,
attributes: {
...traceAttributes
}
});
}
}
Expand Down
34 changes: 33 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2515,7 +2515,7 @@
dependencies:
"@opentelemetry/api" "^1.3.0"

"@opentelemetry/api@^1.3.0", "@opentelemetry/api@~1.9.0":
"@opentelemetry/api@1.9.0", "@opentelemetry/api@^1.3.0", "@opentelemetry/api@~1.9.0":
version "1.9.0"
resolved "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe"
integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==
Expand All @@ -2527,6 +2527,13 @@
dependencies:
"@opentelemetry/semantic-conventions" "^1.29.0"

"@opentelemetry/[email protected]":
version "2.1.0"
resolved "https://registry.npmjs.org/@opentelemetry/core/-/core-2.1.0.tgz#5539f04eb9e5245e000b0c3f77bdfaa07557e3a7"
integrity sha512-RMEtHsxJs/GiHHxYT58IY57UXAQTuUnZVco6ymDEqTNlJKTimM4qPUPVe8InNFyBjhHBEAx4k3Q8LtNayBsbUQ==
dependencies:
"@opentelemetry/semantic-conventions" "^1.29.0"

"@opentelemetry/[email protected]":
version "0.203.0"
resolved "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.203.0.tgz#cdecb5c5b39561aa8520c8bb78347c6e11c91a81"
Expand Down Expand Up @@ -2567,6 +2574,14 @@
"@opentelemetry/core" "2.0.1"
"@opentelemetry/semantic-conventions" "^1.29.0"

"@opentelemetry/[email protected]":
version "2.1.0"
resolved "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.1.0.tgz#11772e732af4f27953cf55567a6630d8b4d8282d"
integrity sha512-1CJjf3LCvoefUOgegxi8h6r4B/wLSzInyhGP2UmIBYNlo4Qk5CZ73e1eEyWmfXvFtm1ybkmfb2DqWvspsYLrWw==
dependencies:
"@opentelemetry/core" "2.1.0"
"@opentelemetry/semantic-conventions" "^1.29.0"

"@opentelemetry/[email protected]":
version "0.203.0"
resolved "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.203.0.tgz#01bc7c0549929d2864af2ab0ba23fd5ce02b5b0a"
Expand All @@ -2593,6 +2608,23 @@
"@opentelemetry/resources" "2.0.1"
"@opentelemetry/semantic-conventions" "^1.29.0"

"@opentelemetry/[email protected]":
version "2.1.0"
resolved "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.1.0.tgz#9d31474824e9ed215f94bf71260d5321f64d402a"
integrity sha512-uTX9FBlVQm4S2gVQO1sb5qyBLq/FPjbp+tmGoxu4tIgtYGmBYB44+KX/725RFDe30yBSaA9Ml9fqphe1hbUyLQ==
dependencies:
"@opentelemetry/core" "2.1.0"
"@opentelemetry/resources" "2.1.0"
"@opentelemetry/semantic-conventions" "^1.29.0"

"@opentelemetry/[email protected]":
version "2.1.0"
resolved "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-2.1.0.tgz#5765729ad975a8611eb863d40778d644eda4ae54"
integrity sha512-2F6ZuZFmJg4CdhRPP8+60DkvEwGLCiU3ffAkgnnqe/ALGEBqGa0HrZaNWFGprXWVivrYHpXhr7AEfasgLZD71g==
dependencies:
"@opentelemetry/core" "2.1.0"
"@opentelemetry/sdk-trace-base" "2.1.0"

"@opentelemetry/[email protected]", "@opentelemetry/semantic-conventions@^1.29.0":
version "1.36.0"
resolved "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.36.0.tgz#149449bd4df4d0464220915ad4164121e0d75d4d"
Expand Down
Loading