Skip to content

Commit

Permalink
chore: load opentelemetry modules on demand (#619)
Browse files Browse the repository at this point in the history
  • Loading branch information
BlankParticle authored Jul 28, 2024
1 parent beeeaa6 commit ab0145c
Show file tree
Hide file tree
Showing 16 changed files with 130 additions and 109 deletions.
7 changes: 5 additions & 2 deletions apps/mail-bridge/tracing.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { setupOpentelemetry } from '@u22n/otel';
import { opentelemetryEnabled } from '@u22n/otel';
import { name, version } from './package.json';

setupOpentelemetry({ name, version });
if (opentelemetryEnabled) {
const { setupOpentelemetry } = await import('@u22n/otel/setup');
setupOpentelemetry({ name, version });
}
2 changes: 1 addition & 1 deletion apps/mail-bridge/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineConfig } from 'tsup';

export default defineConfig({
entry: ['app.ts', './tracing.ts'],
entry: ['app.ts', 'tracing.ts'],
outDir: '.output',
format: 'esm',
target: 'esnext',
Expand Down
7 changes: 5 additions & 2 deletions apps/platform/tracing.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { setupOpentelemetry } from '@u22n/otel';
import { opentelemetryEnabled } from '@u22n/otel';
import { name, version } from './package.json';

setupOpentelemetry({ name, version });
if (opentelemetryEnabled) {
const { setupOpentelemetry } = await import('@u22n/otel/setup');
setupOpentelemetry({ name, version });
}
2 changes: 1 addition & 1 deletion apps/platform/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineConfig } from 'tsup';

export default defineConfig({
entry: ['app.ts', './tracing.ts'],
entry: ['app.ts', 'tracing.ts'],
outDir: '.output',
format: 'esm',
target: 'esnext',
Expand Down
7 changes: 5 additions & 2 deletions apps/storage/tracing.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { setupOpentelemetry } from '@u22n/otel';
import { opentelemetryEnabled } from '@u22n/otel';
import { name, version } from './package.json';

setupOpentelemetry({ name, version });
if (opentelemetryEnabled) {
const { setupOpentelemetry } = await import('@u22n/otel/setup');
setupOpentelemetry({ name, version });
}
2 changes: 1 addition & 1 deletion apps/storage/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineConfig } from 'tsup';

export default defineConfig({
entry: ['app.ts', './tracing.ts'],
entry: ['app.ts', 'tracing.ts'],
outDir: '.output',
format: 'esm',
target: 'esnext',
Expand Down
10 changes: 7 additions & 3 deletions apps/web/src/instrumentation.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
const { name, version } = await import('../package.json');
const { setupOpentelemetry } = await import('@u22n/otel');
setupOpentelemetry({ name, version });
const { opentelemetryEnabled } = await import('@u22n/otel');

if (opentelemetryEnabled) {
const { name, version } = await import('../package.json');
const { setupOpentelemetry } = await import('@u22n/otel/setup');
setupOpentelemetry({ name, version });
}
}
}
7 changes: 5 additions & 2 deletions apps/worker/tracing.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { setupOpentelemetry } from '@u22n/otel';
import { opentelemetryEnabled } from '@u22n/otel';
import { name, version } from './package.json';

setupOpentelemetry({ name, version });
if (opentelemetryEnabled) {
const { setupOpentelemetry } = await import('@u22n/otel/setup');
setupOpentelemetry({ name, version });
}
2 changes: 1 addition & 1 deletion apps/worker/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineConfig } from 'tsup';

export default defineConfig({
entry: ['app.ts', './tracing.ts'],
entry: ['app.ts', 'tracing.ts'],
outDir: '.output',
format: 'esm',
target: 'esnext',
Expand Down
55 changes: 29 additions & 26 deletions packages/database/index.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,40 @@
import { drizzle } from 'drizzle-orm/planetscale-serverless';
import { Client, Connection } from '@planetscale/database';
import { getTracer } from '@u22n/otel/helpers';
import { opentelemetryEnabled } from '@u22n/otel';
import * as schema from './schema';
import { env } from './env';

const databaseTracer = getTracer('database');
if (opentelemetryEnabled) {
const { getTracer } = await import('@u22n/otel/helpers');
const databaseTracer = getTracer('database');

// eslint-disable-next-line @typescript-eslint/unbound-method
const originalExecute = Connection.prototype.execute;
// eslint-disable-next-line @typescript-eslint/unbound-method
const originalExecute = Connection.prototype.execute;

Connection.prototype.execute = async function (query, args, options) {
return databaseTracer.startActiveSpan(`Database Query`, async (span) => {
if (span) {
span.addEvent('database.query.start');
span.setAttribute('database.statement', query);
if (Array.isArray(args)) {
span.setAttribute(
'database.values',
args.map((v: string) => v.toString())
);
Connection.prototype.execute = async function (query, args, options) {
return databaseTracer.startActiveSpan(`Database Query`, async (span) => {
if (span) {
span.addEvent('database.query.start');
span.setAttribute('database.statement', query);
if (Array.isArray(args)) {
span.setAttribute(
'database.values',
args.map((v: string) => v.toString())
);
}
}
}
const result = await originalExecute
// @ts-expect-error, don't care about types here
.call(this, query, args, options)
.catch((err: Error) => {
span?.recordException(err);
throw err;
});
span?.addEvent('database.query.end');
return result;
});
};
const result = await originalExecute
// @ts-expect-error, don't care about types here
.call(this, query, args, options)
.catch((err: Error) => {
span?.recordException(err);
throw err;
});
span?.addEvent('database.query.end');
return result;
});
};
}

const client = new Client({
host: env.DB_PLANETSCALE_HOST,
Expand Down
1 change: 0 additions & 1 deletion packages/otel/exports.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export { trace } from '@opentelemetry/api';
export { flatten, unflatten } from 'flat';
13 changes: 8 additions & 5 deletions packages/otel/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import type { Span } from '@opentelemetry/api';
import { trace } from '@opentelemetry/api';
import { env } from './env';
import { opentelemetryEnabled } from '.';

// Import OpenTelemetry API only if it's enabled
const { trace } = opentelemetryEnabled
? await import('@opentelemetry/api')
: { trace: undefined };

export function getTracer(name: string) {
if (!env.OTEL_ENABLED)
if (!trace)
return {
startActiveSpan: <Fn>(name: string, fn: (span?: Span) => Fn) => fn()
};

const tracer = trace.getTracer(name);
return {
startActiveSpan<Fn>(name: string, fn: (span?: Span) => Fn) {
if (!env.OTEL_ENABLED) return fn();
return tracer.startActiveSpan(name, (span) => {
const result = fn(span);
if (result instanceof Promise) {
Expand All @@ -26,7 +29,7 @@ export function getTracer(name: string) {
}

export function inActiveSpan<Fn>(fn: (span?: Span) => Fn) {
if (!env.OTEL_ENABLED) return fn();
if (!trace) return fn();
const span = trace.getActiveSpan();
return fn(span);
}
5 changes: 2 additions & 3 deletions packages/otel/hono.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ function formatHeaders(headers: Record<string, string> | Headers) {
}

export const opentelemetry = (name?: string) => {
// eslint-disable-next-line @typescript-eslint/unbound-method
const { startActiveSpan } = getTracer(name ?? 'hono');
const tracer = getTracer(name ?? 'hono');
return createMiddleware<{ Variables: { requestId: string } }>((c, next) =>
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
inActiveSpan(async (parent) => {
parent?.updateName(`HTTP ${c.req.method} ${c.req.path}`);
if (c.req.method === 'OPTIONS') return next();
return startActiveSpan(`Hono Handler`, async (span) => {
return tracer.startActiveSpan(`Hono Handler`, async (span) => {
span?.addEvent('hono.start');
span?.setAttributes({
'hono.req.headers': formatHeaders(c.req.header())
Expand Down
60 changes: 1 addition & 59 deletions packages/otel/index.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,2 @@
import {
NodeTracerProvider,
BatchSpanProcessor
} from '@opentelemetry/sdk-trace-node';
import {
BatchLogRecordProcessor,
LoggerProvider
} from '@opentelemetry/sdk-logs';
import { WinstonInstrumentation } from '@opentelemetry/instrumentation-winston';
import { UndiciInstrumentation } from '@opentelemetry/instrumentation-undici';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
import { Resource } from '@opentelemetry/resources';
import { logs } from '@opentelemetry/api-logs';
import { env } from './env';

export const setupOpentelemetry = ({
name,
version
}: {
name: string;
version: string;
}) => {
if (!env.OTEL_ENABLED) return;

const resource = new Resource({
'service.name': name,
'service.version': version
});

const traceProvider = new NodeTracerProvider({ resource });
traceProvider.addSpanProcessor(
new BatchSpanProcessor(
new OTLPTraceExporter({
url: env.OTEL_EXPORTER_TRACES_ENDPOINT
})
)
);
traceProvider.register();

const loggerProvider = new LoggerProvider({ resource });
loggerProvider.addLogRecordProcessor(
new BatchLogRecordProcessor(
new OTLPLogExporter({
url: env.OTEL_EXPORTER_LOGS_ENDPOINT
})
)
);
logs.setGlobalLoggerProvider(loggerProvider);

registerInstrumentations({
instrumentations: [
new UndiciInstrumentation(),
new HttpInstrumentation(),
new WinstonInstrumentation()
]
});
};
export const opentelemetryEnabled = env.OTEL_ENABLED;
1 change: 1 addition & 0 deletions packages/otel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"type": "module",
"exports": {
".": "./index.ts",
"./setup": "./setup.ts",
"./hono": "./hono.ts",
"./exports": "./exports.ts",
"./logger": "./logger.ts",
Expand Down
58 changes: 58 additions & 0 deletions packages/otel/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {
BatchSpanProcessor,
NodeTracerProvider
} from '@opentelemetry/sdk-trace-node';
import {
BatchLogRecordProcessor,
LoggerProvider
} from '@opentelemetry/sdk-logs';
import { WinstonInstrumentation } from '@opentelemetry/instrumentation-winston';
import { UndiciInstrumentation } from '@opentelemetry/instrumentation-undici';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
import { Resource } from '@opentelemetry/resources';
import { logs } from '@opentelemetry/api-logs';
import { env } from './env';

export const setupOpentelemetry = ({
name,
version
}: {
name: string;
version: string;
}) => {
const resource = new Resource({
'service.name': name,
'service.version': version
});

const traceProvider = new NodeTracerProvider({ resource });
traceProvider.addSpanProcessor(
new BatchSpanProcessor(
new OTLPTraceExporter({
url: env.OTEL_EXPORTER_TRACES_ENDPOINT
})
)
);
traceProvider.register();

const loggerProvider = new LoggerProvider({ resource });
loggerProvider.addLogRecordProcessor(
new BatchLogRecordProcessor(
new OTLPLogExporter({
url: env.OTEL_EXPORTER_LOGS_ENDPOINT
})
)
);
logs.setGlobalLoggerProvider(loggerProvider);

registerInstrumentations({
instrumentations: [
new UndiciInstrumentation(),
new HttpInstrumentation(),
new WinstonInstrumentation()
]
});
};

0 comments on commit ab0145c

Please sign in to comment.