otel-express-collector 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,20 @@
1
+ # OpenTelemetry Express Collector
2
+
3
+ A comprehensive OpenTelemetry instrumentation package for Node.js Express microservices.
4
+
5
+ ## Features
6
+
7
+ - **Automatic Instrumentation**: HTTP requests, database queries, and more
8
+ - **Structured Logging**: Winston integration with OpenTelemetry export
9
+ - **Metrics Collection**: HTTP, database, business, and system metrics
10
+ - **Distributed Tracing**: End-to-end trace correlation
11
+ - **Health Checks**: Built-in health, readiness, and liveness endpoints
12
+ - **Decorators**: Easy method-level tracing with decorators
13
+ - **TypeScript Support**: Full type definitions
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install otel-express-collector
19
+ # or
20
+ yarn add otel-express-collector
@@ -0,0 +1,35 @@
1
+ import { LoggerProvider } from '@opentelemetry/sdk-logs';
2
+ import { CollectorConfig } from './types';
3
+ interface ResolvedCollectorConfig {
4
+ serviceName: string;
5
+ serviceVersion: string;
6
+ otlpEndpoint: string;
7
+ tracesEndpoint: string;
8
+ metricsEndpoint: string;
9
+ logsEndpoint: string;
10
+ enableTracing: boolean;
11
+ enableMetrics: boolean;
12
+ enableLogging: boolean;
13
+ enableConsoleExport: boolean;
14
+ metricExportInterval: number;
15
+ logBatchSize: number;
16
+ resourceAttributes: Record<string, string | number | boolean>;
17
+ instrumentations: string[];
18
+ }
19
+ export declare class OpenTelemetryCollector {
20
+ private sdk;
21
+ private loggerProvider;
22
+ private isInitialized;
23
+ private isStarted;
24
+ private config;
25
+ constructor(config: CollectorConfig);
26
+ private initialize;
27
+ private getInstrumentations;
28
+ start(): Promise<void>;
29
+ shutdown(): Promise<void>;
30
+ isRunning(): boolean;
31
+ getLoggerProvider(): LoggerProvider | null;
32
+ getConfig(): Readonly<ResolvedCollectorConfig>;
33
+ }
34
+ export {};
35
+ //# sourceMappingURL=collector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,cAAc,EAIf,MAAM,yBAAyB,CAAC;AASjC,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAK1C,UAAU,uBAAuB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IAEvB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IAErB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,mBAAmB,EAAE,OAAO,CAAC;IAE7B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IAErB,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IAC9D,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,qBAAa,sBAAsB;IACjC,OAAO,CAAC,GAAG,CAAwB;IACnC,OAAO,CAAC,cAAc,CAA+B;IAErD,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO,CAAC,MAAM,CAA0B;gBAE5B,MAAM,EAAE,eAAe;YAuCrB,UAAU;IA0ExB,OAAO,CAAC,mBAAmB;IAgBd,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB/B,SAAS,IAAI,OAAO;IAIpB,iBAAiB,IAAI,cAAc,GAAG,IAAI;IAK1C,SAAS,IAAI,QAAQ,CAAC,uBAAuB,CAAC;CAGtD"}
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenTelemetryCollector = void 0;
4
+ const sdk_node_1 = require("@opentelemetry/sdk-node");
5
+ const exporter_trace_otlp_grpc_1 = require("@opentelemetry/exporter-trace-otlp-grpc");
6
+ const exporter_metrics_otlp_grpc_1 = require("@opentelemetry/exporter-metrics-otlp-grpc");
7
+ const exporter_logs_otlp_grpc_1 = require("@opentelemetry/exporter-logs-otlp-grpc");
8
+ const sdk_trace_base_1 = require("@opentelemetry/sdk-trace-base");
9
+ const sdk_metrics_1 = require("@opentelemetry/sdk-metrics");
10
+ const sdk_logs_1 = require("@opentelemetry/sdk-logs");
11
+ const api_logs_1 = require("@opentelemetry/api-logs");
12
+ const auto_instrumentations_node_1 = require("@opentelemetry/auto-instrumentations-node");
13
+ const resources_1 = require("@opentelemetry/resources");
14
+ const api_1 = require("@opentelemetry/api");
15
+ class OpenTelemetryCollector {
16
+ constructor(config) {
17
+ this.sdk = null;
18
+ this.loggerProvider = null;
19
+ this.isInitialized = false;
20
+ this.isStarted = false;
21
+ if (!config.serviceName)
22
+ throw new Error('serviceName is required');
23
+ if (!config.serviceVersion)
24
+ throw new Error('serviceVersion is required');
25
+ const otlpEndpoint = config.otlpEndpoint ?? 'http://localhost:4317';
26
+ this.config = {
27
+ serviceName: config.serviceName,
28
+ serviceVersion: config.serviceVersion,
29
+ otlpEndpoint,
30
+ tracesEndpoint: config.tracesEndpoint ?? otlpEndpoint,
31
+ metricsEndpoint: config.metricsEndpoint ?? otlpEndpoint,
32
+ logsEndpoint: config.logsEndpoint ?? otlpEndpoint,
33
+ enableTracing: config.enableTracing ?? true,
34
+ enableMetrics: config.enableMetrics ?? true,
35
+ enableLogging: config.enableLogging ?? true,
36
+ enableConsoleExport: config.enableConsoleExport ?? false,
37
+ metricExportInterval: config.metricExportInterval ?? 60000,
38
+ logBatchSize: config.logBatchSize ?? 512,
39
+ resourceAttributes: config.resourceAttributes ?? {},
40
+ instrumentations: config.instrumentations ?? [],
41
+ };
42
+ if (process.env.NODE_ENV === 'development' ||
43
+ this.config.enableConsoleExport) {
44
+ api_1.diag.setLogger(new api_1.DiagConsoleLogger(), api_1.DiagLogLevel.DEBUG);
45
+ }
46
+ }
47
+ /* =========================
48
+ INITIALIZATION
49
+ ========================= */
50
+ async initialize() {
51
+ if (this.isInitialized)
52
+ return;
53
+ // ✅ DOC-ALIGNED RESOURCE ATTRIBUTES (PLAIN STRINGS)
54
+ const resource = (0, resources_1.resourceFromAttributes)({
55
+ 'service.name': this.config.serviceName,
56
+ 'service.version': this.config.serviceVersion,
57
+ 'deployment.environment': process.env.NODE_ENV ?? 'development',
58
+ 'process.runtime.name': 'nodejs',
59
+ 'process.runtime.version': process.version,
60
+ ...this.config.resourceAttributes,
61
+ });
62
+ /* -------- Traces & Metrics -------- */
63
+ this.sdk = new sdk_node_1.NodeSDK({
64
+ resource,
65
+ traceExporter: this.config.enableTracing
66
+ ? this.config.enableConsoleExport
67
+ ? new sdk_trace_base_1.ConsoleSpanExporter()
68
+ : new exporter_trace_otlp_grpc_1.OTLPTraceExporter({ url: this.config.tracesEndpoint })
69
+ : undefined,
70
+ metricReader: this.config.enableMetrics
71
+ ? new sdk_metrics_1.PeriodicExportingMetricReader({
72
+ exporter: this.config.enableConsoleExport
73
+ ? new sdk_metrics_1.ConsoleMetricExporter()
74
+ : new exporter_metrics_otlp_grpc_1.OTLPMetricExporter({ url: this.config.metricsEndpoint }),
75
+ exportIntervalMillis: this.config.metricExportInterval,
76
+ })
77
+ : undefined,
78
+ instrumentations: this.getInstrumentations(),
79
+ });
80
+ /* -------- Logs (SDK-LOGS DOC-ALIGNED) -------- */
81
+ if (this.config.enableLogging) {
82
+ const logExporter = this.config.enableConsoleExport
83
+ ? new sdk_logs_1.ConsoleLogRecordExporter()
84
+ : new exporter_logs_otlp_grpc_1.OTLPLogExporter({ url: this.config.logsEndpoint });
85
+ this.loggerProvider = new sdk_logs_1.LoggerProvider({
86
+ resource,
87
+ loggerConfigurator: (0, sdk_logs_1.createLoggerConfigurator)([
88
+ {
89
+ pattern: '*',
90
+ config: {
91
+ minimumSeverity: api_logs_1.SeverityNumber.INFO,
92
+ traceBased: false,
93
+ },
94
+ },
95
+ ]),
96
+ processors: [
97
+ new sdk_logs_1.BatchLogRecordProcessor(logExporter, {
98
+ maxExportBatchSize: this.config.logBatchSize,
99
+ }),
100
+ ],
101
+ });
102
+ // REQUIRED by @opentelemetry/sdk-logs docs
103
+ api_logs_1.logs.setGlobalLoggerProvider(this.loggerProvider);
104
+ }
105
+ await this.sdk.start();
106
+ this.isInitialized = true;
107
+ this.isStarted = true;
108
+ console.log(`[otel] Started for ${this.config.serviceName}`);
109
+ }
110
+ /* =========================
111
+ INSTRUMENTATIONS
112
+ ========================= */
113
+ getInstrumentations() {
114
+ return [
115
+ (0, auto_instrumentations_node_1.getNodeAutoInstrumentations)({
116
+ '@opentelemetry/instrumentation-http': { enabled: true },
117
+ '@opentelemetry/instrumentation-express': {
118
+ enabled: true,
119
+ ignoreLayers: ['/health', '/metrics'],
120
+ },
121
+ }),
122
+ ];
123
+ }
124
+ /* =========================
125
+ LIFECYCLE
126
+ ========================= */
127
+ async start() {
128
+ if (!this.isStarted) {
129
+ await this.initialize();
130
+ }
131
+ }
132
+ async shutdown() {
133
+ if (!this.isStarted)
134
+ return;
135
+ await this.sdk?.shutdown();
136
+ await this.loggerProvider?.shutdown();
137
+ this.sdk = null;
138
+ this.loggerProvider = null;
139
+ this.isStarted = false;
140
+ this.isInitialized = false;
141
+ console.log('[otel] Shutdown complete');
142
+ }
143
+ /* =========================
144
+ HELPERS (TEST + API SAFE)
145
+ ========================= */
146
+ isRunning() {
147
+ return this.isStarted;
148
+ }
149
+ getLoggerProvider() {
150
+ return this.loggerProvider;
151
+ }
152
+ // ✅ ADDED BACK — fixes your test failure
153
+ getConfig() {
154
+ return this.config;
155
+ }
156
+ }
157
+ exports.OpenTelemetryCollector = OpenTelemetryCollector;
158
+ //# sourceMappingURL=collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collector.js","sourceRoot":"","sources":["../src/collector.ts"],"names":[],"mappings":";;;AAAA,sDAAkD;AAElD,sFAA4E;AAC5E,0FAA+E;AAC/E,oFAAyE;AAEzE,kEAAoE;AACpE,4DAGoC;AAEpC,sDAKiC;AAEjC,sDAA+D;AAE/D,0FAAwF;AAExF,wDAAkE;AAClE,4CAA2E;AA4B3E,MAAa,sBAAsB;IASjC,YAAY,MAAuB;QAR3B,QAAG,GAAmB,IAAI,CAAC;QAC3B,mBAAc,GAA0B,IAAI,CAAC;QAE7C,kBAAa,GAAG,KAAK,CAAC;QACtB,cAAS,GAAG,KAAK,CAAC;QAKxB,IAAI,CAAC,MAAM,CAAC,WAAW;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACpE,IAAI,CAAC,MAAM,CAAC,cAAc;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAE1E,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,uBAAuB,CAAC;QAEpE,IAAI,CAAC,MAAM,GAAG;YACZ,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,cAAc,EAAE,MAAM,CAAC,cAAc;YAErC,YAAY;YACZ,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,YAAY;YACrD,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,YAAY;YACvD,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,YAAY;YAEjD,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,IAAI;YAC3C,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,IAAI;YAC3C,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,IAAI;YAC3C,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,IAAI,KAAK;YAExD,oBAAoB,EAAE,MAAM,CAAC,oBAAoB,IAAI,KAAM;YAC3D,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,GAAG;YAExC,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,IAAI,EAAE;YACnD,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,IAAI,EAAE;SAChD,CAAC;QAEF,IACE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa;YACtC,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAC/B,CAAC;YACD,UAAI,CAAC,SAAS,CAAC,IAAI,uBAAiB,EAAE,EAAE,kBAAY,CAAC,KAAK,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED;;gCAE4B;IAEpB,KAAK,CAAC,UAAU;QACtB,IAAI,IAAI,CAAC,aAAa;YAAE,OAAO;QAE/B,oDAAoD;QACpD,MAAM,QAAQ,GAAG,IAAA,kCAAsB,EAAC;YACtC,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,WAAW;YACvC,iBAAiB,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc;YAC7C,wBAAwB,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAa;YAC/D,sBAAsB,EAAE,QAAQ;YAChC,yBAAyB,EAAE,OAAO,CAAC,OAAO;YAC1C,GAAG,IAAI,CAAC,MAAM,CAAC,kBAAkB;SAClC,CAAC,CAAC;QAEH,wCAAwC;QACxC,IAAI,CAAC,GAAG,GAAG,IAAI,kBAAO,CAAC;YACrB,QAAQ;YACR,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa;gBACtC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,mBAAmB;oBAC/B,CAAC,CAAC,IAAI,oCAAmB,EAAE;oBAC3B,CAAC,CAAC,IAAI,4CAAiB,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;gBAC9D,CAAC,CAAC,SAAS;YAEb,YAAY,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa;gBACrC,CAAC,CAAC,IAAI,2CAA6B,CAAC;oBAChC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,mBAAmB;wBACvC,CAAC,CAAC,IAAI,mCAAqB,EAAE;wBAC7B,CAAC,CAAC,IAAI,+CAAkB,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;oBAChE,oBAAoB,EAAE,IAAI,CAAC,MAAM,CAAC,oBAAoB;iBACvD,CAAC;gBACJ,CAAC,CAAC,SAAS;YAEb,gBAAgB,EAAE,IAAI,CAAC,mBAAmB,EAAE;SAC7C,CAAC,CAAC;QAEH,mDAAmD;QACnD,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;YAC9B,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,mBAAmB;gBACjD,CAAC,CAAC,IAAI,mCAAwB,EAAE;gBAChC,CAAC,CAAC,IAAI,yCAAe,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;YAE3D,IAAI,CAAC,cAAc,GAAG,IAAI,yBAAc,CAAC;gBACvC,QAAQ;gBACR,kBAAkB,EAAE,IAAA,mCAAwB,EAAC;oBAC3C;wBACE,OAAO,EAAE,GAAG;wBACZ,MAAM,EAAE;4BACN,eAAe,EAAE,yBAAc,CAAC,IAAI;4BACpC,UAAU,EAAE,KAAK;yBAClB;qBACF;iBACF,CAAC;gBACF,UAAU,EAAE;oBACV,IAAI,kCAAuB,CAAC,WAAW,EAAE;wBACvC,kBAAkB,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY;qBAC7C,CAAC;iBACH;aACF,CAAC,CAAC;YAEH,2CAA2C;YAC3C,eAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QAEvB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAEtB,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED;;gCAE4B;IAEpB,mBAAmB;QACzB,OAAO;YACL,IAAA,wDAA2B,EAAC;gBAC1B,qCAAqC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE;gBACxD,wCAAwC,EAAE;oBACxC,OAAO,EAAE,IAAI;oBACb,YAAY,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;iBACtC;aACF,CAAC;SACH,CAAC;IACJ,CAAC;IAED;;gCAE4B;IAErB,KAAK,CAAC,KAAK;QAChB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,QAAQ;QACnB,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAE5B,MAAM,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC;QAC3B,MAAM,IAAI,CAAC,cAAc,EAAE,QAAQ,EAAE,CAAC;QAEtC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;QAChB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAE3B,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAC1C,CAAC;IAED;;gCAE4B;IAErB,SAAS;QACd,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAEM,iBAAiB;QACtB,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED,yCAAyC;IAClC,SAAS;QACd,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF;AA9KD,wDA8KC"}
@@ -0,0 +1,16 @@
1
+ import { Logger } from './logger';
2
+ export interface TraceOptions {
3
+ /** Custom span name */
4
+ name?: string;
5
+ /** Span attributes */
6
+ attributes?: Record<string, any>;
7
+ /** Logger instance for logging */
8
+ logger?: Logger;
9
+ /** Log method arguments (default: false) */
10
+ logArguments?: boolean;
11
+ /** Log return value (default: false) */
12
+ logReturnValue?: boolean;
13
+ }
14
+ export declare function Trace(options?: TraceOptions): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
15
+ export declare function TraceAsync(options?: TraceOptions): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
16
+ //# sourceMappingURL=decorators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,WAAW,YAAY;IAC3B,uBAAuB;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,sBAAsB;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAEjC,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,wCAAwC;IACxC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,KAAK,CAAC,OAAO,GAAE,YAAiB,IAE5C,QAAQ,GAAG,EACX,aAAa,MAAM,EACnB,YAAY,kBAAkB,wBAoEjC;AAED,wBAAgB,UAAU,CAAC,OAAO,GAAE,YAAiB,IAEjD,QAAQ,GAAG,EACX,aAAa,MAAM,EACnB,YAAY,kBAAkB,wBAyCjC"}
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Trace = Trace;
4
+ exports.TraceAsync = TraceAsync;
5
+ const api_1 = require("@opentelemetry/api");
6
+ function Trace(options = {}) {
7
+ return function (target, propertyKey, descriptor) {
8
+ const originalMethod = descriptor.value;
9
+ const className = target.constructor.name;
10
+ const spanName = options.name || `${className}.${propertyKey}`;
11
+ const logger = options.logger;
12
+ descriptor.value = async function (...args) {
13
+ const tracer = api_1.trace.getTracer(className);
14
+ return tracer.startActiveSpan(spanName, async (span) => {
15
+ try {
16
+ // Add custom attributes
17
+ if (options.attributes) {
18
+ span.setAttributes(options.attributes);
19
+ }
20
+ // Add class and method names as attributes
21
+ span.setAttribute('class.name', className);
22
+ span.setAttribute('method.name', propertyKey);
23
+ // Log method arguments if enabled
24
+ if (options.logArguments && logger) {
25
+ logger.debug(`Method ${spanName} called with arguments`, {
26
+ arguments: args,
27
+ traceId: span.spanContext().traceId,
28
+ });
29
+ }
30
+ // Execute the original method
31
+ const result = await originalMethod.apply(this, args);
32
+ // Log return value if enabled
33
+ if (options.logReturnValue && logger) {
34
+ logger.debug(`Method ${spanName} returned`, {
35
+ result,
36
+ traceId: span.spanContext().traceId,
37
+ });
38
+ }
39
+ span.setStatus({ code: api_1.SpanStatusCode.OK });
40
+ span.end();
41
+ return result;
42
+ }
43
+ catch (error) {
44
+ // Record exception in span
45
+ span.recordException(error);
46
+ span.setStatus({
47
+ code: api_1.SpanStatusCode.ERROR,
48
+ message: error.message,
49
+ });
50
+ // Log error if logger is available
51
+ if (logger) {
52
+ logger.error(`Method ${spanName} failed`, {
53
+ error: error.message,
54
+ stack: error.stack,
55
+ traceId: span.spanContext().traceId,
56
+ });
57
+ }
58
+ span.end();
59
+ throw error;
60
+ }
61
+ });
62
+ };
63
+ return descriptor;
64
+ };
65
+ }
66
+ function TraceAsync(options = {}) {
67
+ return function (target, propertyKey, descriptor) {
68
+ const originalMethod = descriptor.value;
69
+ const className = target.constructor.name;
70
+ const spanName = options.name || `${className}.${propertyKey}`;
71
+ descriptor.value = function (...args) {
72
+ const tracer = api_1.trace.getTracer(className);
73
+ const promise = originalMethod.apply(this, args);
74
+ if (!(promise instanceof Promise)) {
75
+ return promise;
76
+ }
77
+ const span = tracer.startSpan(spanName, {
78
+ attributes: {
79
+ 'class.name': className,
80
+ 'method.name': propertyKey,
81
+ ...options.attributes,
82
+ },
83
+ });
84
+ return promise
85
+ .then((result) => {
86
+ span.setStatus({ code: api_1.SpanStatusCode.OK });
87
+ span.end();
88
+ return result;
89
+ })
90
+ .catch((error) => {
91
+ span.recordException(error);
92
+ span.setStatus({
93
+ code: api_1.SpanStatusCode.ERROR,
94
+ message: error.message,
95
+ });
96
+ span.end();
97
+ throw error;
98
+ });
99
+ };
100
+ return descriptor;
101
+ };
102
+ }
103
+ //# sourceMappingURL=decorators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { Request, Response, NextFunction, Application, Router } from 'express';
2
+ import { Logger } from './logger';
3
+ import { Metrics } from './metrics';
4
+ export interface ExpressMiddlewareConfig {
5
+ /** Service name for logging */
6
+ serviceName: string;
7
+ /** Logger instance */
8
+ logger?: Logger;
9
+ /** Metrics instance */
10
+ metrics?: Metrics;
11
+ /** Paths to exclude from tracing */
12
+ excludePaths?: string[];
13
+ /** Enable request/response body logging (default: false) */
14
+ logBody?: boolean;
15
+ /** Maximum body size to log in bytes (default: 1024) */
16
+ maxBodyLogSize?: number;
17
+ /** Custom span name formatter */
18
+ spanNameFormatter?: (req: Request) => string;
19
+ }
20
+ export declare function createOpenTelemetryMiddleware(config: ExpressMiddlewareConfig): (req: Request, res: Response, next: NextFunction) => void;
21
+ export declare function createErrorMiddleware(logger?: Logger): (error: Error, req: Request, res: Response, next: NextFunction) => void;
22
+ export declare function configureExpressApp(app: Application | Router, config: ExpressMiddlewareConfig): void;
23
+ //# sourceMappingURL=express.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../src/express.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAE/E,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,WAAW,uBAAuB;IACtC,+BAA+B;IAC/B,WAAW,EAAE,MAAM,CAAC;IAEpB,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,uBAAuB;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,oCAAoC;IACpC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,iCAAiC;IACjC,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;CAC9C;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,uBAAuB,IAWnE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,UAsIxD;AAED,wBAAgB,qBAAqB,CAAC,MAAM,CAAC,EAAE,MAAM,IAC3C,OAAO,KAAK,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,UA6BtE;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,WAAW,GAAG,MAAM,EACzB,MAAM,EAAE,uBAAuB,GAC9B,IAAI,CAMN"}
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createOpenTelemetryMiddleware = createOpenTelemetryMiddleware;
4
+ exports.createErrorMiddleware = createErrorMiddleware;
5
+ exports.configureExpressApp = configureExpressApp;
6
+ const api_1 = require("@opentelemetry/api");
7
+ function createOpenTelemetryMiddleware(config) {
8
+ const { serviceName, logger, metrics, excludePaths = ['/health', '/metrics', '/favicon.ico'], logBody = false, maxBodyLogSize = 1024, spanNameFormatter = (req) => `${req.method} ${req.route?.path || req.path}` } = config;
9
+ return (req, res, next) => {
10
+ // Skip excluded paths
11
+ if (excludePaths.some(path => req.path.startsWith(path))) {
12
+ return next();
13
+ }
14
+ const startTime = Date.now();
15
+ const tracer = api_1.trace.getTracer(serviceName);
16
+ const spanName = spanNameFormatter(req);
17
+ // Create span for this request
18
+ const span = tracer.startSpan(spanName, {
19
+ attributes: {
20
+ 'http.method': req.method,
21
+ 'http.url': req.url,
22
+ 'http.route': req.route?.path || req.path,
23
+ 'http.host': req.headers.host,
24
+ 'http.user_agent': req.headers['user-agent'],
25
+ 'net.peer.ip': req.ip || req.socket.remoteAddress,
26
+ },
27
+ });
28
+ // Store trace context in request
29
+ req.traceId = span.spanContext().traceId;
30
+ req.spanId = span.spanContext().spanId;
31
+ req.startTime = startTime;
32
+ // Log request start
33
+ logger?.info('Incoming HTTP request', {
34
+ method: req.method,
35
+ url: req.url,
36
+ path: req.path,
37
+ query: req.query,
38
+ traceId: req.traceId,
39
+ ...(logBody && req.body && {
40
+ body: truncateBody(req.body, maxBodyLogSize)
41
+ }),
42
+ });
43
+ // Increment active requests counter
44
+ metrics?.incrementActiveRequests();
45
+ // Capture response
46
+ const originalSend = res.send;
47
+ let responseBody;
48
+ res.send = function (body) {
49
+ responseBody = body;
50
+ return originalSend.call(this, body);
51
+ };
52
+ res.on('finish', () => {
53
+ const duration = Date.now() - startTime;
54
+ const route = req.route?.path || req.path;
55
+ // Decrement active requests counter
56
+ metrics?.decrementActiveRequests();
57
+ // Update span with response information
58
+ span.setAttributes({
59
+ 'http.status_code': res.statusCode,
60
+ 'http.response_content_length': res.get('Content-Length') || '0',
61
+ 'http.flavor': req.httpVersion,
62
+ 'http.response.duration_ms': duration,
63
+ });
64
+ // Record metrics
65
+ metrics?.recordHttpRequest({
66
+ method: req.method,
67
+ route,
68
+ statusCode: res.statusCode,
69
+ duration,
70
+ });
71
+ // Record response size if available
72
+ const contentLength = res.get('Content-Length');
73
+ if (contentLength) {
74
+ metrics?.recordHttpResponseSize(parseInt(contentLength), req.method, route, res.statusCode);
75
+ }
76
+ // Log response
77
+ const logLevel = res.statusCode >= 400 ? 'warn' : 'info';
78
+ logger?.[logLevel]('HTTP request completed', {
79
+ method: req.method,
80
+ url: req.url,
81
+ statusCode: res.statusCode,
82
+ duration,
83
+ traceId: req.traceId,
84
+ ...(logBody && responseBody && {
85
+ response: truncateBody(responseBody, maxBodyLogSize)
86
+ }),
87
+ });
88
+ // Set span status based on HTTP status code
89
+ if (res.statusCode >= 400) {
90
+ span.setStatus({
91
+ code: api_1.SpanStatusCode.ERROR,
92
+ message: `HTTP ${res.statusCode}`,
93
+ });
94
+ }
95
+ else {
96
+ span.setStatus({ code: api_1.SpanStatusCode.OK });
97
+ }
98
+ span.end();
99
+ });
100
+ // Handle errors
101
+ res.on('error', (error) => {
102
+ logger?.error('HTTP response error', {
103
+ error: error.message,
104
+ stack: error.stack,
105
+ method: req.method,
106
+ url: req.url,
107
+ traceId: req.traceId,
108
+ });
109
+ span.recordException(error);
110
+ span.setStatus({
111
+ code: api_1.SpanStatusCode.ERROR,
112
+ message: error.message,
113
+ });
114
+ span.end();
115
+ });
116
+ // Continue processing
117
+ api_1.context.with(api_1.trace.setSpan(api_1.context.active(), span), () => {
118
+ next();
119
+ });
120
+ };
121
+ }
122
+ function createErrorMiddleware(logger) {
123
+ return (error, req, res, next) => {
124
+ const span = api_1.trace.getActiveSpan();
125
+ logger?.error('Unhandled error in Express middleware', {
126
+ error: error.message,
127
+ stack: error.stack,
128
+ method: req.method,
129
+ url: req.url,
130
+ traceId: req.traceId,
131
+ spanId: req.spanId,
132
+ });
133
+ if (span) {
134
+ span.recordException(error);
135
+ span.setStatus({
136
+ code: api_1.SpanStatusCode.ERROR,
137
+ message: error.message,
138
+ });
139
+ }
140
+ // Send error response
141
+ res.status(500).json({
142
+ error: 'Internal Server Error',
143
+ message: process.env.NODE_ENV === 'production'
144
+ ? 'An unexpected error occurred'
145
+ : error.message,
146
+ traceId: req.traceId,
147
+ });
148
+ };
149
+ }
150
+ function configureExpressApp(app, config) {
151
+ // Add OpenTelemetry middleware
152
+ app.use(createOpenTelemetryMiddleware(config));
153
+ // Add error handling middleware (should be last)
154
+ app.use(createErrorMiddleware(config.logger));
155
+ }
156
+ function truncateBody(body, maxSize) {
157
+ if (typeof body === 'string') {
158
+ return body.length > maxSize ? body.substring(0, maxSize) + '...' : body;
159
+ }
160
+ if (typeof body === 'object') {
161
+ const str = JSON.stringify(body);
162
+ return str.length > maxSize ? str.substring(0, maxSize) + '...' : body;
163
+ }
164
+ return body;
165
+ }
166
+ //# sourceMappingURL=express.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"express.js","sourceRoot":"","sources":["../src/express.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { Application, Router } from 'express';
2
+ import { OpenTelemetryCollector } from './collector';
3
+ import { Logger } from './logger';
4
+ import { HealthStatus } from './types';
5
+ export interface HealthCheckOptions {
6
+ /** Collector instance for checking OpenTelemetry health */
7
+ collector?: OpenTelemetryCollector;
8
+ /** Logger instance */
9
+ logger?: Logger;
10
+ /** Custom health checks */
11
+ checks?: Record<string, () => Promise<boolean>>;
12
+ /** Service name */
13
+ serviceName?: string;
14
+ /** Service version */
15
+ serviceVersion?: string;
16
+ }
17
+ export declare class HealthController {
18
+ private collector?;
19
+ private logger?;
20
+ private checks;
21
+ private serviceName;
22
+ private serviceVersion;
23
+ constructor(options?: HealthCheckOptions);
24
+ getHealthStatus(): Promise<HealthStatus>;
25
+ createHealthRouter(): Router;
26
+ registerHealthRoutes(app: Application | Router): void;
27
+ }
28
+ //# sourceMappingURL=health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,MAAM,WAAW,kBAAkB;IACjC,2DAA2D;IAC3D,SAAS,CAAC,EAAE,sBAAsB,CAAC;IAEnC,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,2BAA2B;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAEhD,mBAAmB;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,sBAAsB;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,SAAS,CAAC,CAAyB;IAC3C,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,MAAM,CAAyC;IACvD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,cAAc,CAAS;gBAEnB,OAAO,GAAE,kBAAuB;IAQ/B,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC;IAoC9C,kBAAkB,IAAI,MAAM;IA+E5B,oBAAoB,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI;CAI7D"}