Skip to content

Commit ab0145c

Browse files
chore: load opentelemetry modules on demand (#619)
1 parent beeeaa6 commit ab0145c

File tree

16 files changed

+130
-109
lines changed

16 files changed

+130
-109
lines changed

apps/mail-bridge/tracing.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { setupOpentelemetry } from '@u22n/otel';
1+
import { opentelemetryEnabled } from '@u22n/otel';
22
import { name, version } from './package.json';
33

4-
setupOpentelemetry({ name, version });
4+
if (opentelemetryEnabled) {
5+
const { setupOpentelemetry } = await import('@u22n/otel/setup');
6+
setupOpentelemetry({ name, version });
7+
}

apps/mail-bridge/tsup.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { defineConfig } from 'tsup';
22

33
export default defineConfig({
4-
entry: ['app.ts', './tracing.ts'],
4+
entry: ['app.ts', 'tracing.ts'],
55
outDir: '.output',
66
format: 'esm',
77
target: 'esnext',

apps/platform/tracing.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { setupOpentelemetry } from '@u22n/otel';
1+
import { opentelemetryEnabled } from '@u22n/otel';
22
import { name, version } from './package.json';
33

4-
setupOpentelemetry({ name, version });
4+
if (opentelemetryEnabled) {
5+
const { setupOpentelemetry } = await import('@u22n/otel/setup');
6+
setupOpentelemetry({ name, version });
7+
}

apps/platform/tsup.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { defineConfig } from 'tsup';
22

33
export default defineConfig({
4-
entry: ['app.ts', './tracing.ts'],
4+
entry: ['app.ts', 'tracing.ts'],
55
outDir: '.output',
66
format: 'esm',
77
target: 'esnext',

apps/storage/tracing.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { setupOpentelemetry } from '@u22n/otel';
1+
import { opentelemetryEnabled } from '@u22n/otel';
22
import { name, version } from './package.json';
33

4-
setupOpentelemetry({ name, version });
4+
if (opentelemetryEnabled) {
5+
const { setupOpentelemetry } = await import('@u22n/otel/setup');
6+
setupOpentelemetry({ name, version });
7+
}

apps/storage/tsup.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { defineConfig } from 'tsup';
22

33
export default defineConfig({
4-
entry: ['app.ts', './tracing.ts'],
4+
entry: ['app.ts', 'tracing.ts'],
55
outDir: '.output',
66
format: 'esm',
77
target: 'esnext',

apps/web/src/instrumentation.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
export async function register() {
22
if (process.env.NEXT_RUNTIME === 'nodejs') {
3-
const { name, version } = await import('../package.json');
4-
const { setupOpentelemetry } = await import('@u22n/otel');
5-
setupOpentelemetry({ name, version });
3+
const { opentelemetryEnabled } = await import('@u22n/otel');
4+
5+
if (opentelemetryEnabled) {
6+
const { name, version } = await import('../package.json');
7+
const { setupOpentelemetry } = await import('@u22n/otel/setup');
8+
setupOpentelemetry({ name, version });
9+
}
610
}
711
}

apps/worker/tracing.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { setupOpentelemetry } from '@u22n/otel';
1+
import { opentelemetryEnabled } from '@u22n/otel';
22
import { name, version } from './package.json';
33

4-
setupOpentelemetry({ name, version });
4+
if (opentelemetryEnabled) {
5+
const { setupOpentelemetry } = await import('@u22n/otel/setup');
6+
setupOpentelemetry({ name, version });
7+
}

apps/worker/tsup.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { defineConfig } from 'tsup';
22

33
export default defineConfig({
4-
entry: ['app.ts', './tracing.ts'],
4+
entry: ['app.ts', 'tracing.ts'],
55
outDir: '.output',
66
format: 'esm',
77
target: 'esnext',

packages/database/index.ts

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,40 @@
11
import { drizzle } from 'drizzle-orm/planetscale-serverless';
22
import { Client, Connection } from '@planetscale/database';
3-
import { getTracer } from '@u22n/otel/helpers';
3+
import { opentelemetryEnabled } from '@u22n/otel';
44
import * as schema from './schema';
55
import { env } from './env';
66

7-
const databaseTracer = getTracer('database');
7+
if (opentelemetryEnabled) {
8+
const { getTracer } = await import('@u22n/otel/helpers');
9+
const databaseTracer = getTracer('database');
810

9-
// eslint-disable-next-line @typescript-eslint/unbound-method
10-
const originalExecute = Connection.prototype.execute;
11+
// eslint-disable-next-line @typescript-eslint/unbound-method
12+
const originalExecute = Connection.prototype.execute;
1113

12-
Connection.prototype.execute = async function (query, args, options) {
13-
return databaseTracer.startActiveSpan(`Database Query`, async (span) => {
14-
if (span) {
15-
span.addEvent('database.query.start');
16-
span.setAttribute('database.statement', query);
17-
if (Array.isArray(args)) {
18-
span.setAttribute(
19-
'database.values',
20-
args.map((v: string) => v.toString())
21-
);
14+
Connection.prototype.execute = async function (query, args, options) {
15+
return databaseTracer.startActiveSpan(`Database Query`, async (span) => {
16+
if (span) {
17+
span.addEvent('database.query.start');
18+
span.setAttribute('database.statement', query);
19+
if (Array.isArray(args)) {
20+
span.setAttribute(
21+
'database.values',
22+
args.map((v: string) => v.toString())
23+
);
24+
}
2225
}
23-
}
24-
const result = await originalExecute
25-
// @ts-expect-error, don't care about types here
26-
.call(this, query, args, options)
27-
.catch((err: Error) => {
28-
span?.recordException(err);
29-
throw err;
30-
});
31-
span?.addEvent('database.query.end');
32-
return result;
33-
});
34-
};
26+
const result = await originalExecute
27+
// @ts-expect-error, don't care about types here
28+
.call(this, query, args, options)
29+
.catch((err: Error) => {
30+
span?.recordException(err);
31+
throw err;
32+
});
33+
span?.addEvent('database.query.end');
34+
return result;
35+
});
36+
};
37+
}
3538

3639
const client = new Client({
3740
host: env.DB_PLANETSCALE_HOST,

packages/otel/exports.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
export { trace } from '@opentelemetry/api';
21
export { flatten, unflatten } from 'flat';

packages/otel/helpers.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
import type { Span } from '@opentelemetry/api';
2-
import { trace } from '@opentelemetry/api';
3-
import { env } from './env';
2+
import { opentelemetryEnabled } from '.';
3+
4+
// Import OpenTelemetry API only if it's enabled
5+
const { trace } = opentelemetryEnabled
6+
? await import('@opentelemetry/api')
7+
: { trace: undefined };
48

59
export function getTracer(name: string) {
6-
if (!env.OTEL_ENABLED)
10+
if (!trace)
711
return {
812
startActiveSpan: <Fn>(name: string, fn: (span?: Span) => Fn) => fn()
913
};
1014

1115
const tracer = trace.getTracer(name);
1216
return {
1317
startActiveSpan<Fn>(name: string, fn: (span?: Span) => Fn) {
14-
if (!env.OTEL_ENABLED) return fn();
1518
return tracer.startActiveSpan(name, (span) => {
1619
const result = fn(span);
1720
if (result instanceof Promise) {
@@ -26,7 +29,7 @@ export function getTracer(name: string) {
2629
}
2730

2831
export function inActiveSpan<Fn>(fn: (span?: Span) => Fn) {
29-
if (!env.OTEL_ENABLED) return fn();
32+
if (!trace) return fn();
3033
const span = trace.getActiveSpan();
3134
return fn(span);
3235
}

packages/otel/hono.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@ function formatHeaders(headers: Record<string, string> | Headers) {
66
}
77

88
export const opentelemetry = (name?: string) => {
9-
// eslint-disable-next-line @typescript-eslint/unbound-method
10-
const { startActiveSpan } = getTracer(name ?? 'hono');
9+
const tracer = getTracer(name ?? 'hono');
1110
return createMiddleware<{ Variables: { requestId: string } }>((c, next) =>
1211
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
1312
inActiveSpan(async (parent) => {
1413
parent?.updateName(`HTTP ${c.req.method} ${c.req.path}`);
1514
if (c.req.method === 'OPTIONS') return next();
16-
return startActiveSpan(`Hono Handler`, async (span) => {
15+
return tracer.startActiveSpan(`Hono Handler`, async (span) => {
1716
span?.addEvent('hono.start');
1817
span?.setAttributes({
1918
'hono.req.headers': formatHeaders(c.req.header())

packages/otel/index.ts

Lines changed: 1 addition & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,2 @@
1-
import {
2-
NodeTracerProvider,
3-
BatchSpanProcessor
4-
} from '@opentelemetry/sdk-trace-node';
5-
import {
6-
BatchLogRecordProcessor,
7-
LoggerProvider
8-
} from '@opentelemetry/sdk-logs';
9-
import { WinstonInstrumentation } from '@opentelemetry/instrumentation-winston';
10-
import { UndiciInstrumentation } from '@opentelemetry/instrumentation-undici';
11-
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
12-
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
13-
import { registerInstrumentations } from '@opentelemetry/instrumentation';
14-
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
15-
import { Resource } from '@opentelemetry/resources';
16-
import { logs } from '@opentelemetry/api-logs';
171
import { env } from './env';
18-
19-
export const setupOpentelemetry = ({
20-
name,
21-
version
22-
}: {
23-
name: string;
24-
version: string;
25-
}) => {
26-
if (!env.OTEL_ENABLED) return;
27-
28-
const resource = new Resource({
29-
'service.name': name,
30-
'service.version': version
31-
});
32-
33-
const traceProvider = new NodeTracerProvider({ resource });
34-
traceProvider.addSpanProcessor(
35-
new BatchSpanProcessor(
36-
new OTLPTraceExporter({
37-
url: env.OTEL_EXPORTER_TRACES_ENDPOINT
38-
})
39-
)
40-
);
41-
traceProvider.register();
42-
43-
const loggerProvider = new LoggerProvider({ resource });
44-
loggerProvider.addLogRecordProcessor(
45-
new BatchLogRecordProcessor(
46-
new OTLPLogExporter({
47-
url: env.OTEL_EXPORTER_LOGS_ENDPOINT
48-
})
49-
)
50-
);
51-
logs.setGlobalLoggerProvider(loggerProvider);
52-
53-
registerInstrumentations({
54-
instrumentations: [
55-
new UndiciInstrumentation(),
56-
new HttpInstrumentation(),
57-
new WinstonInstrumentation()
58-
]
59-
});
60-
};
2+
export const opentelemetryEnabled = env.OTEL_ENABLED;

packages/otel/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"type": "module",
55
"exports": {
66
".": "./index.ts",
7+
"./setup": "./setup.ts",
78
"./hono": "./hono.ts",
89
"./exports": "./exports.ts",
910
"./logger": "./logger.ts",

packages/otel/setup.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import {
2+
BatchSpanProcessor,
3+
NodeTracerProvider
4+
} from '@opentelemetry/sdk-trace-node';
5+
import {
6+
BatchLogRecordProcessor,
7+
LoggerProvider
8+
} from '@opentelemetry/sdk-logs';
9+
import { WinstonInstrumentation } from '@opentelemetry/instrumentation-winston';
10+
import { UndiciInstrumentation } from '@opentelemetry/instrumentation-undici';
11+
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
12+
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
13+
import { registerInstrumentations } from '@opentelemetry/instrumentation';
14+
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
15+
import { Resource } from '@opentelemetry/resources';
16+
import { logs } from '@opentelemetry/api-logs';
17+
import { env } from './env';
18+
19+
export const setupOpentelemetry = ({
20+
name,
21+
version
22+
}: {
23+
name: string;
24+
version: string;
25+
}) => {
26+
const resource = new Resource({
27+
'service.name': name,
28+
'service.version': version
29+
});
30+
31+
const traceProvider = new NodeTracerProvider({ resource });
32+
traceProvider.addSpanProcessor(
33+
new BatchSpanProcessor(
34+
new OTLPTraceExporter({
35+
url: env.OTEL_EXPORTER_TRACES_ENDPOINT
36+
})
37+
)
38+
);
39+
traceProvider.register();
40+
41+
const loggerProvider = new LoggerProvider({ resource });
42+
loggerProvider.addLogRecordProcessor(
43+
new BatchLogRecordProcessor(
44+
new OTLPLogExporter({
45+
url: env.OTEL_EXPORTER_LOGS_ENDPOINT
46+
})
47+
)
48+
);
49+
logs.setGlobalLoggerProvider(loggerProvider);
50+
51+
registerInstrumentations({
52+
instrumentations: [
53+
new UndiciInstrumentation(),
54+
new HttpInstrumentation(),
55+
new WinstonInstrumentation()
56+
]
57+
});
58+
};

0 commit comments

Comments
 (0)