@zola_do/observability 0.3.1
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 +94 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/observability-options.d.ts +31 -0
- package/dist/observability-options.js +3 -0
- package/dist/observability-options.js.map +1 -0
- package/dist/observability.constants.d.ts +3 -0
- package/dist/observability.constants.js +7 -0
- package/dist/observability.constants.js.map +1 -0
- package/dist/observability.module.d.ts +6 -0
- package/dist/observability.module.js +53 -0
- package/dist/observability.module.js.map +1 -0
- package/dist/otel-log.helper.d.ts +16 -0
- package/dist/otel-log.helper.js +48 -0
- package/dist/otel-log.helper.js.map +1 -0
- package/dist/otel-sdk.helper.d.ts +5 -0
- package/dist/otel-sdk.helper.js +177 -0
- package/dist/otel-sdk.helper.js.map +1 -0
- package/dist/request-correlation.interceptor.d.ts +9 -0
- package/dist/request-correlation.interceptor.js +76 -0
- package/dist/request-correlation.interceptor.js.map +1 -0
- package/dist/trace-context.helper.d.ts +3 -0
- package/dist/trace-context.helper.js +35 -0
- package/dist/trace-context.helper.js.map +1 -0
- package/dist/zola-otel.logger.d.ts +14 -0
- package/dist/zola-otel.logger.js +59 -0
- package/dist/zola-otel.logger.js.map +1 -0
- package/dist/zola-request-logging.middleware.d.ts +8 -0
- package/dist/zola-request-logging.middleware.js +42 -0
- package/dist/zola-request-logging.middleware.js.map +1 -0
- package/package.json +138 -0
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# @zola_do/observability
|
|
2
|
+
|
|
3
|
+
NestJS observability helpers for request correlation, OpenTelemetry trace IDs, and optional telemetry SDK bootstrap.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm i @zola_do/observability
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Install OpenTelemetry packages in the consuming application when telemetry export is needed.
|
|
12
|
+
|
|
13
|
+
For **HTTP/protobuf** OTLP (port `4318`):
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm i @opentelemetry/api @opentelemetry/api-logs @opentelemetry/sdk-node @opentelemetry/sdk-logs @opentelemetry/exporter-trace-otlp-http @opentelemetry/exporter-metrics-otlp-http @opentelemetry/exporter-logs-otlp-http @opentelemetry/instrumentation-http @opentelemetry/instrumentation-nestjs-core @opentelemetry/instrumentation-pg @opentelemetry/resources @opentelemetry/semantic-conventions @opentelemetry/sdk-metrics
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
For **gRPC** OTLP (port `4317`):
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm i @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/exporter-trace-otlp-grpc @opentelemetry/exporter-metrics-otlp-grpc @opentelemetry/instrumentation-http @opentelemetry/instrumentation-nestjs-core @opentelemetry/resources @opentelemetry/semantic-conventions @opentelemetry/sdk-metrics
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Request correlation
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { Module } from '@nestjs/common';
|
|
29
|
+
import { ZolaObservabilityModule } from '@zola_do/observability';
|
|
30
|
+
|
|
31
|
+
@Module({
|
|
32
|
+
imports: [
|
|
33
|
+
ZolaObservabilityModule.forRoot({
|
|
34
|
+
serviceName: 'orders-api',
|
|
35
|
+
environment: process.env.NODE_ENV,
|
|
36
|
+
}),
|
|
37
|
+
],
|
|
38
|
+
})
|
|
39
|
+
export class AppModule {}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The module registers a global interceptor that:
|
|
43
|
+
|
|
44
|
+
- forwards or creates `x-request-id`
|
|
45
|
+
- forwards or creates `x-correlation-id`
|
|
46
|
+
- attaches `request.requestId` and `request.correlationId`
|
|
47
|
+
- echoes the headers on the response
|
|
48
|
+
- adds `trace-id` and `span-id` response headers when an active OpenTelemetry span exists
|
|
49
|
+
|
|
50
|
+
## OpenTelemetry bootstrap
|
|
51
|
+
|
|
52
|
+
Call SDK startup before creating the Nest app (for example in `instrumentation.ts` imported before `NestFactory.create`).
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import {
|
|
56
|
+
resolveOtlpProtocol,
|
|
57
|
+
startZolaOpenTelemetry,
|
|
58
|
+
} from '@zola_do/observability';
|
|
59
|
+
|
|
60
|
+
startZolaOpenTelemetry({
|
|
61
|
+
serviceName: 'orders-api',
|
|
62
|
+
otlpEndpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
|
|
63
|
+
otlpProtocol: resolveOtlpProtocol(process.env.OTEL_EXPORTER_OTLP_PROTOCOL),
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Environment variables:
|
|
68
|
+
|
|
69
|
+
- `OTEL_EXPORTER_OTLP_ENDPOINT` — base OTLP URL (for example `http://collector:4318`; HTTP/protobuf signal paths such as `/v1/traces` are appended automatically)
|
|
70
|
+
- `OTEL_EXPORTER_OTLP_PROTOCOL` — `http/protobuf` or `grpc` (defaults to `http/protobuf` when the endpoint uses port `4318`)
|
|
71
|
+
- `OTEL_LOGS_EXPORTER` — set to `otlp` to export Nest/request logs to `/v1/logs`
|
|
72
|
+
|
|
73
|
+
## Trace-aware Nest logger
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { NestFactory } from '@nestjs/core';
|
|
77
|
+
import { ZolaOtelLogger } from '@zola_do/observability';
|
|
78
|
+
|
|
79
|
+
const app = await NestFactory.create(AppModule, {
|
|
80
|
+
logger: new ZolaOtelLogger(),
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Enable per-request OTLP logs (includes `trace_id` / `span_id`) via `ZolaObservabilityModule.forRoot({ logRequests: true })`.
|
|
85
|
+
|
|
86
|
+
Use `getTraceLogFields()` to enrich custom structured logs:
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { getTraceLogFields } from '@zola_do/observability';
|
|
90
|
+
|
|
91
|
+
logger.log({ ...getTraceLogFields(), message: 'Order created' });
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
All OpenTelemetry packages are optional peers. Applications that do not install an SDK can still use request correlation safely.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './observability.constants';
|
|
2
|
+
export * from './observability-options';
|
|
3
|
+
export * from './observability.module';
|
|
4
|
+
export * from './otel-log.helper';
|
|
5
|
+
export * from './otel-sdk.helper';
|
|
6
|
+
export * from './request-correlation.interceptor';
|
|
7
|
+
export * from './trace-context.helper';
|
|
8
|
+
export * from './zola-otel.logger';
|
|
9
|
+
export * from './zola-request-logging.middleware';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./observability.constants"), exports);
|
|
18
|
+
__exportStar(require("./observability-options"), exports);
|
|
19
|
+
__exportStar(require("./observability.module"), exports);
|
|
20
|
+
__exportStar(require("./otel-log.helper"), exports);
|
|
21
|
+
__exportStar(require("./otel-sdk.helper"), exports);
|
|
22
|
+
__exportStar(require("./request-correlation.interceptor"), exports);
|
|
23
|
+
__exportStar(require("./trace-context.helper"), exports);
|
|
24
|
+
__exportStar(require("./zola-otel.logger"), exports);
|
|
25
|
+
__exportStar(require("./zola-request-logging.middleware"), exports);
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4DAA0C;AAC1C,0DAAwC;AACxC,yDAAuC;AACvC,oDAAkC;AAClC,oDAAkC;AAClC,oEAAkD;AAClD,yDAAuC;AACvC,qDAAmC;AACnC,oEAAkD"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface ZolaObservabilityOptions {
|
|
2
|
+
serviceName?: string;
|
|
3
|
+
serviceVersion?: string;
|
|
4
|
+
environment?: string;
|
|
5
|
+
enabled?: boolean;
|
|
6
|
+
requestIdHeader?: string;
|
|
7
|
+
correlationIdHeader?: string;
|
|
8
|
+
exposeTraceHeaders?: boolean;
|
|
9
|
+
logRequests?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export type ZolaOtlpProtocol = 'grpc' | 'http/protobuf';
|
|
12
|
+
export interface ZolaOpenTelemetrySdkOptions extends ZolaObservabilityOptions {
|
|
13
|
+
otlpEndpoint?: string;
|
|
14
|
+
otlpProtocol?: ZolaOtlpProtocol | 'HttpProtobuf';
|
|
15
|
+
tracesEndpoint?: string;
|
|
16
|
+
metricsEndpoint?: string;
|
|
17
|
+
logsEndpoint?: string;
|
|
18
|
+
enableMetrics?: boolean;
|
|
19
|
+
enableLogs?: boolean;
|
|
20
|
+
enableHttpInstrumentation?: boolean;
|
|
21
|
+
enableNestInstrumentation?: boolean;
|
|
22
|
+
enablePgInstrumentation?: boolean;
|
|
23
|
+
enableAutoInstrumentations?: boolean;
|
|
24
|
+
instrumentations?: unknown[];
|
|
25
|
+
resourceAttributes?: Record<string, string | number | boolean>;
|
|
26
|
+
}
|
|
27
|
+
export interface ZolaTraceIds {
|
|
28
|
+
traceId?: string;
|
|
29
|
+
spanId?: string;
|
|
30
|
+
traceFlags?: number;
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observability-options.js","sourceRoot":"","sources":["../src/observability-options.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_CORRELATION_ID_HEADER = exports.DEFAULT_REQUEST_ID_HEADER = exports.ZOLA_OBSERVABILITY_OPTIONS = void 0;
|
|
4
|
+
exports.ZOLA_OBSERVABILITY_OPTIONS = Symbol('ZOLA_OBSERVABILITY_OPTIONS');
|
|
5
|
+
exports.DEFAULT_REQUEST_ID_HEADER = 'x-request-id';
|
|
6
|
+
exports.DEFAULT_CORRELATION_ID_HEADER = 'x-correlation-id';
|
|
7
|
+
//# sourceMappingURL=observability.constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observability.constants.js","sourceRoot":"","sources":["../src/observability.constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,0BAA0B,GAAG,MAAM,CAAC,4BAA4B,CAAC,CAAC;AAClE,QAAA,yBAAyB,GAAG,cAAc,CAAC;AAC3C,QAAA,6BAA6B,GAAG,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DynamicModule, MiddlewareConsumer, NestModule } from '@nestjs/common';
|
|
2
|
+
import { ZolaObservabilityOptions } from './observability-options';
|
|
3
|
+
export declare class ZolaObservabilityModule implements NestModule {
|
|
4
|
+
static forRoot(options?: ZolaObservabilityOptions): DynamicModule;
|
|
5
|
+
configure(consumer: MiddlewareConsumer): void;
|
|
6
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var ZolaObservabilityModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.ZolaObservabilityModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const core_1 = require("@nestjs/core");
|
|
13
|
+
const observability_constants_1 = require("./observability.constants");
|
|
14
|
+
const request_correlation_interceptor_1 = require("./request-correlation.interceptor");
|
|
15
|
+
const zola_request_logging_middleware_1 = require("./zola-request-logging.middleware");
|
|
16
|
+
let ZolaObservabilityModule = ZolaObservabilityModule_1 = class ZolaObservabilityModule {
|
|
17
|
+
static forRoot(options = {}) {
|
|
18
|
+
const enabled = options.enabled !== false;
|
|
19
|
+
return {
|
|
20
|
+
module: ZolaObservabilityModule_1,
|
|
21
|
+
providers: [
|
|
22
|
+
{
|
|
23
|
+
provide: observability_constants_1.ZOLA_OBSERVABILITY_OPTIONS,
|
|
24
|
+
useValue: options,
|
|
25
|
+
},
|
|
26
|
+
request_correlation_interceptor_1.ZolaRequestCorrelationInterceptor,
|
|
27
|
+
zola_request_logging_middleware_1.ZolaRequestLoggingMiddleware,
|
|
28
|
+
...(enabled
|
|
29
|
+
? [
|
|
30
|
+
{
|
|
31
|
+
provide: core_1.APP_INTERCEPTOR,
|
|
32
|
+
useExisting: request_correlation_interceptor_1.ZolaRequestCorrelationInterceptor,
|
|
33
|
+
},
|
|
34
|
+
]
|
|
35
|
+
: []),
|
|
36
|
+
],
|
|
37
|
+
exports: [
|
|
38
|
+
observability_constants_1.ZOLA_OBSERVABILITY_OPTIONS,
|
|
39
|
+
request_correlation_interceptor_1.ZolaRequestCorrelationInterceptor,
|
|
40
|
+
zola_request_logging_middleware_1.ZolaRequestLoggingMiddleware,
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
configure(consumer) {
|
|
45
|
+
consumer.apply(zola_request_logging_middleware_1.ZolaRequestLoggingMiddleware).forRoutes('*');
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
exports.ZolaObservabilityModule = ZolaObservabilityModule;
|
|
49
|
+
exports.ZolaObservabilityModule = ZolaObservabilityModule = ZolaObservabilityModule_1 = __decorate([
|
|
50
|
+
(0, common_1.Global)(),
|
|
51
|
+
(0, common_1.Module)({})
|
|
52
|
+
], ZolaObservabilityModule);
|
|
53
|
+
//# sourceMappingURL=observability.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observability.module.js","sourceRoot":"","sources":["../src/observability.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAA+F;AAC/F,uCAA+C;AAE/C,uEAAuE;AAEvE,uFAAsF;AACtF,uFAAiF;AAI1E,IAAM,uBAAuB,+BAA7B,MAAM,uBAAuB;IAC3B,AAAP,MAAM,CAAC,OAAO,CAAC,OAAO,GAA6B,EAAE;QACnD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,KAAK,KAAK,CAAC;QAE1C,OAAO;YACL,MAAM,2BAAyB;YAC/B,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,oDAA0B;oBACnC,QAAQ,EAAE,OAAO;iBAClB;gBACD,mEAAiC;gBACjC,8DAA4B;gBAC5B,GAAG,CAAC,OAAO;oBACT,CAAC,CAAC;wBACE;4BACE,OAAO,EAAE,sBAAe;4BACxB,WAAW,EAAE,mEAAiC;yBAC/C;qBACF;oBACH,CAAC,CAAC,EAAE,CAAC;aACR;YACD,OAAO,EAAE;gBACP,oDAA0B;gBAC1B,mEAAiC;gBACjC,8DAA4B;aAC7B;SACF,CAAC;IACJ,CAAC;IAED,SAAS,CAAC,QAA4B;QACpC,QAAQ,CAAC,KAAK,CAAC,8DAA4B,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC9D,CAAC;CACF,CAAA;;kCAjCY,uBAAuB;IAFnC,IAAA,eAAM,GAAE;IACR,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,uBAAuB,CAiCnC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ZolaTraceIds } from './observability-options';
|
|
2
|
+
export interface ZolaOtelLogInput {
|
|
3
|
+
severityNumber: number;
|
|
4
|
+
severityText: string;
|
|
5
|
+
body: string;
|
|
6
|
+
context?: string;
|
|
7
|
+
attributes?: Record<string, string | number | boolean>;
|
|
8
|
+
traceIds?: ZolaTraceIds;
|
|
9
|
+
}
|
|
10
|
+
export declare function emitOtelLog(input: ZolaOtelLogInput): void;
|
|
11
|
+
export declare function emitExceptionLog(payload: Record<string, unknown>): void;
|
|
12
|
+
export declare function emitHttpRequestLog(request: {
|
|
13
|
+
method?: string;
|
|
14
|
+
originalUrl?: string;
|
|
15
|
+
url?: string;
|
|
16
|
+
}, statusCode?: number, traceIds?: ZolaTraceIds): void;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.emitOtelLog = emitOtelLog;
|
|
4
|
+
exports.emitExceptionLog = emitExceptionLog;
|
|
5
|
+
exports.emitHttpRequestLog = emitHttpRequestLog;
|
|
6
|
+
const trace_context_helper_1 = require("./trace-context.helper");
|
|
7
|
+
function emitOtelLog(input) {
|
|
8
|
+
var _a, _b;
|
|
9
|
+
try {
|
|
10
|
+
const { logs, SeverityNumber } = require('@opentelemetry/api-logs');
|
|
11
|
+
const traceIds = (_a = input.traceIds) !== null && _a !== void 0 ? _a : (0, trace_context_helper_1.getActiveTraceIds)();
|
|
12
|
+
const logger = logs.getLogger(input.context || 'nestjs');
|
|
13
|
+
logger.emit(Object.assign({ severityNumber: (_b = input.severityNumber) !== null && _b !== void 0 ? _b : SeverityNumber.INFO, severityText: input.severityText, body: input.body, attributes: Object.assign(Object.assign(Object.assign(Object.assign({}, (input.context ? { 'log.context': input.context } : {})), (traceIds.traceId ? { trace_id: traceIds.traceId } : {})), (traceIds.spanId ? { span_id: traceIds.spanId } : {})), input.attributes) }, (traceIds.traceId
|
|
14
|
+
? {
|
|
15
|
+
traceId: traceIds.traceId,
|
|
16
|
+
spanId: traceIds.spanId,
|
|
17
|
+
traceFlags: traceIds.traceFlags,
|
|
18
|
+
}
|
|
19
|
+
: {})));
|
|
20
|
+
}
|
|
21
|
+
catch (_c) {
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function emitExceptionLog(payload) {
|
|
25
|
+
const statusCode = Number(payload.statusCode) || 500;
|
|
26
|
+
const severity = statusCode >= 500
|
|
27
|
+
? { severityNumber: 17, severityText: 'ERROR' }
|
|
28
|
+
: { severityNumber: 13, severityText: 'WARN' };
|
|
29
|
+
emitOtelLog(Object.assign(Object.assign({}, severity), { body: JSON.stringify(payload), context: 'GlobalExceptionFilter', attributes: Object.assign(Object.assign(Object.assign({ 'http.status_code': statusCode }, (payload.path ? { 'http.target': String(payload.path) } : {})), (payload.exceptionMessage
|
|
30
|
+
? { exception_message: String(payload.exceptionMessage) }
|
|
31
|
+
: {})), (payload.name ? { exception_name: String(payload.name) } : {})) }));
|
|
32
|
+
}
|
|
33
|
+
function emitHttpRequestLog(request, statusCode, traceIds) {
|
|
34
|
+
const method = request.method || 'GET';
|
|
35
|
+
const target = request.originalUrl || request.url || '/';
|
|
36
|
+
const code = statusCode !== null && statusCode !== void 0 ? statusCode : 0;
|
|
37
|
+
const severity = code >= 500
|
|
38
|
+
? { severityNumber: 17, severityText: 'ERROR' }
|
|
39
|
+
: code >= 400
|
|
40
|
+
? { severityNumber: 13, severityText: 'WARN' }
|
|
41
|
+
: { severityNumber: 9, severityText: 'INFO' };
|
|
42
|
+
emitOtelLog(Object.assign(Object.assign({}, severity), { body: `${method} ${target} ${code}`, context: 'http', traceIds, attributes: {
|
|
43
|
+
'http.method': method,
|
|
44
|
+
'http.target': target,
|
|
45
|
+
'http.status_code': code,
|
|
46
|
+
} }));
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=otel-log.helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otel-log.helper.js","sourceRoot":"","sources":["../src/otel-log.helper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ZolaOpenTelemetrySdkOptions, ZolaOtlpProtocol } from './observability-options';
|
|
2
|
+
export declare function resolveOtlpProtocol(value?: string, endpoint?: string): ZolaOtlpProtocol;
|
|
3
|
+
export declare function createZolaOpenTelemetrySdk(options?: ZolaOpenTelemetrySdkOptions): unknown;
|
|
4
|
+
export declare function startZolaOpenTelemetry(options?: ZolaOpenTelemetrySdkOptions): unknown;
|
|
5
|
+
export declare function resolveOtlpHttpSignalUrl(url: string | undefined, signal: 'traces' | 'metrics' | 'logs'): string | undefined;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveOtlpProtocol = resolveOtlpProtocol;
|
|
4
|
+
exports.createZolaOpenTelemetrySdk = createZolaOpenTelemetrySdk;
|
|
5
|
+
exports.startZolaOpenTelemetry = startZolaOpenTelemetry;
|
|
6
|
+
exports.resolveOtlpHttpSignalUrl = resolveOtlpHttpSignalUrl;
|
|
7
|
+
function resolveOtlpProtocol(value, endpoint) {
|
|
8
|
+
const normalized = (value || process.env.OTEL_EXPORTER_OTLP_PROTOCOL || '')
|
|
9
|
+
.trim()
|
|
10
|
+
.toLowerCase();
|
|
11
|
+
if (normalized === 'http/protobuf' ||
|
|
12
|
+
normalized === 'http_protobuf' ||
|
|
13
|
+
normalized === 'httpprotobuf') {
|
|
14
|
+
return 'http/protobuf';
|
|
15
|
+
}
|
|
16
|
+
if (normalized === 'grpc') {
|
|
17
|
+
return 'grpc';
|
|
18
|
+
}
|
|
19
|
+
const resolvedEndpoint = endpoint ||
|
|
20
|
+
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||
|
|
21
|
+
process.env.OTEL_EXPORTER_OTLP_ENDPOINT ||
|
|
22
|
+
'';
|
|
23
|
+
if (/:4318(?:\/|$)/.test(resolvedEndpoint)) {
|
|
24
|
+
return 'http/protobuf';
|
|
25
|
+
}
|
|
26
|
+
return 'grpc';
|
|
27
|
+
}
|
|
28
|
+
function createZolaOpenTelemetrySdk(options = {}) {
|
|
29
|
+
if (options.enabled === false) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
const { NodeSDK } = require('@opentelemetry/sdk-node');
|
|
33
|
+
const resources = require('@opentelemetry/resources');
|
|
34
|
+
const semanticConventions = require('@opentelemetry/semantic-conventions');
|
|
35
|
+
const otlpEndpoint = options.otlpEndpoint || process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
36
|
+
const otlpProtocol = resolveOtlpProtocol(options.otlpProtocol === 'HttpProtobuf'
|
|
37
|
+
? 'http/protobuf'
|
|
38
|
+
: options.otlpProtocol, otlpEndpoint);
|
|
39
|
+
const resourceAttributes = Object.assign({ [semanticConventions.ATTR_SERVICE_NAME || 'service.name']: options.serviceName ||
|
|
40
|
+
process.env.OTEL_SERVICE_NAME ||
|
|
41
|
+
process.env.APPLICATION_NAME ||
|
|
42
|
+
process.env.APP_NAME ||
|
|
43
|
+
'nestjs-app', [semanticConventions.ATTR_SERVICE_VERSION || 'service.version']: options.serviceVersion ||
|
|
44
|
+
process.env.OTEL_SERVICE_VERSION ||
|
|
45
|
+
process.env.npm_package_version ||
|
|
46
|
+
'unknown', [semanticConventions.ATTR_DEPLOYMENT_ENVIRONMENT_NAME ||
|
|
47
|
+
'deployment.environment.name']: options.environment || process.env.NODE_ENV || 'development' }, options.resourceAttributes);
|
|
48
|
+
const tracesUrl = options.tracesEndpoint ||
|
|
49
|
+
options.otlpEndpoint ||
|
|
50
|
+
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ||
|
|
51
|
+
process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
52
|
+
const sdkOptions = {
|
|
53
|
+
resource: createResource(resources, resourceAttributes),
|
|
54
|
+
traceExporter: createTraceExporter(otlpProtocol, tracesUrl),
|
|
55
|
+
instrumentations: buildInstrumentations(options),
|
|
56
|
+
};
|
|
57
|
+
if (options.enableMetrics !== false) {
|
|
58
|
+
const { PeriodicExportingMetricReader, } = require('@opentelemetry/sdk-metrics');
|
|
59
|
+
const metricsUrl = options.metricsEndpoint ||
|
|
60
|
+
options.otlpEndpoint ||
|
|
61
|
+
process.env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT ||
|
|
62
|
+
process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
63
|
+
sdkOptions.metricReader = new PeriodicExportingMetricReader({
|
|
64
|
+
exporter: createMetricExporter(otlpProtocol, metricsUrl),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
if (shouldEnableLogs(options)) {
|
|
68
|
+
const { BatchLogRecordProcessor } = require('@opentelemetry/sdk-logs');
|
|
69
|
+
const logsUrl = options.logsEndpoint ||
|
|
70
|
+
options.otlpEndpoint ||
|
|
71
|
+
process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT ||
|
|
72
|
+
process.env.OTEL_EXPORTER_OTLP_ENDPOINT;
|
|
73
|
+
sdkOptions.logRecordProcessors = [
|
|
74
|
+
new BatchLogRecordProcessor({
|
|
75
|
+
exporter: createLogExporter(otlpProtocol, logsUrl),
|
|
76
|
+
}),
|
|
77
|
+
];
|
|
78
|
+
}
|
|
79
|
+
return new NodeSDK(sdkOptions);
|
|
80
|
+
}
|
|
81
|
+
function shouldEnableLogs(options) {
|
|
82
|
+
if (options.enableLogs === false) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
const exporter = (process.env.OTEL_LOGS_EXPORTER || '').trim().toLowerCase();
|
|
86
|
+
if (exporter === 'none' || exporter === 'false') {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
if (options.enableLogs === true || exporter === 'otlp') {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
return !!(options.logsEndpoint ||
|
|
93
|
+
options.otlpEndpoint ||
|
|
94
|
+
process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT ||
|
|
95
|
+
process.env.OTEL_EXPORTER_OTLP_ENDPOINT);
|
|
96
|
+
}
|
|
97
|
+
function startZolaOpenTelemetry(options = {}) {
|
|
98
|
+
const sdk = createZolaOpenTelemetrySdk(options);
|
|
99
|
+
if (sdk === null || sdk === void 0 ? void 0 : sdk.start) {
|
|
100
|
+
sdk.start();
|
|
101
|
+
}
|
|
102
|
+
return sdk;
|
|
103
|
+
}
|
|
104
|
+
function createTraceExporter(protocol, url) {
|
|
105
|
+
if (protocol === 'http/protobuf') {
|
|
106
|
+
const { OTLPTraceExporter, } = require('@opentelemetry/exporter-trace-otlp-http');
|
|
107
|
+
return new OTLPTraceExporter({
|
|
108
|
+
url: resolveOtlpHttpSignalUrl(url, 'traces'),
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
const { OTLPTraceExporter, } = require('@opentelemetry/exporter-trace-otlp-grpc');
|
|
112
|
+
return new OTLPTraceExporter({ url });
|
|
113
|
+
}
|
|
114
|
+
function createMetricExporter(protocol, url) {
|
|
115
|
+
if (protocol === 'http/protobuf') {
|
|
116
|
+
const { OTLPMetricExporter, } = require('@opentelemetry/exporter-metrics-otlp-http');
|
|
117
|
+
return new OTLPMetricExporter({
|
|
118
|
+
url: resolveOtlpHttpSignalUrl(url, 'metrics'),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
const { OTLPMetricExporter, } = require('@opentelemetry/exporter-metrics-otlp-grpc');
|
|
122
|
+
return new OTLPMetricExporter({ url });
|
|
123
|
+
}
|
|
124
|
+
function createLogExporter(protocol, url) {
|
|
125
|
+
if (protocol === 'http/protobuf') {
|
|
126
|
+
const { OTLPLogExporter } = require('@opentelemetry/exporter-logs-otlp-http');
|
|
127
|
+
return new OTLPLogExporter({
|
|
128
|
+
url: resolveOtlpHttpSignalUrl(url, 'logs'),
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
const { OTLPLogExporter } = require('@opentelemetry/exporter-logs-otlp-grpc');
|
|
132
|
+
return new OTLPLogExporter({ url });
|
|
133
|
+
}
|
|
134
|
+
function resolveOtlpHttpSignalUrl(url, signal) {
|
|
135
|
+
if (!url) {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
const normalized = url.replace(/\/+$/, '');
|
|
139
|
+
if (normalized.endsWith(`/v1/${signal}`)) {
|
|
140
|
+
return normalized;
|
|
141
|
+
}
|
|
142
|
+
return `${normalized}/v1/${signal}`;
|
|
143
|
+
}
|
|
144
|
+
function createResource(resources, attributes) {
|
|
145
|
+
if (typeof resources.resourceFromAttributes === 'function') {
|
|
146
|
+
return resources.resourceFromAttributes(attributes);
|
|
147
|
+
}
|
|
148
|
+
return new resources.Resource(attributes);
|
|
149
|
+
}
|
|
150
|
+
function buildInstrumentations(options) {
|
|
151
|
+
const instrumentations = [...(options.instrumentations || [])];
|
|
152
|
+
if (options.enableAutoInstrumentations) {
|
|
153
|
+
const { getNodeAutoInstrumentations, } = require('@opentelemetry/auto-instrumentations-node');
|
|
154
|
+
instrumentations.push(getNodeAutoInstrumentations());
|
|
155
|
+
return instrumentations;
|
|
156
|
+
}
|
|
157
|
+
if (options.enableHttpInstrumentation !== false) {
|
|
158
|
+
const { HttpInstrumentation, } = require('@opentelemetry/instrumentation-http');
|
|
159
|
+
instrumentations.push(new HttpInstrumentation());
|
|
160
|
+
}
|
|
161
|
+
if (options.enableNestInstrumentation !== false) {
|
|
162
|
+
const { NestInstrumentation, } = require('@opentelemetry/instrumentation-nestjs-core');
|
|
163
|
+
instrumentations.push(new NestInstrumentation());
|
|
164
|
+
}
|
|
165
|
+
if (options.enablePgInstrumentation !== false) {
|
|
166
|
+
try {
|
|
167
|
+
const { PgInstrumentation } = require('@opentelemetry/instrumentation-pg');
|
|
168
|
+
instrumentations.push(new PgInstrumentation({
|
|
169
|
+
enhancedDatabaseReporting: true,
|
|
170
|
+
}));
|
|
171
|
+
}
|
|
172
|
+
catch (_a) {
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return instrumentations;
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=otel-sdk.helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otel-sdk.helper.js","sourceRoot":"","sources":["../src/otel-sdk.helper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common';
|
|
2
|
+
import { Observable } from 'rxjs';
|
|
3
|
+
import { ZolaObservabilityOptions } from './observability-options';
|
|
4
|
+
export declare class ZolaRequestCorrelationInterceptor implements NestInterceptor {
|
|
5
|
+
private readonly options;
|
|
6
|
+
constructor(options?: ZolaObservabilityOptions);
|
|
7
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
|
|
8
|
+
private setTraceHeaders;
|
|
9
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.ZolaRequestCorrelationInterceptor = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const crypto_1 = require("crypto");
|
|
18
|
+
const operators_1 = require("rxjs/operators");
|
|
19
|
+
const observability_constants_1 = require("./observability.constants");
|
|
20
|
+
const trace_context_helper_1 = require("./trace-context.helper");
|
|
21
|
+
let ZolaRequestCorrelationInterceptor = class ZolaRequestCorrelationInterceptor {
|
|
22
|
+
constructor(options = {}) {
|
|
23
|
+
this.options = options;
|
|
24
|
+
}
|
|
25
|
+
intercept(context, next) {
|
|
26
|
+
const http = context.switchToHttp();
|
|
27
|
+
const request = http.getRequest();
|
|
28
|
+
const response = http.getResponse();
|
|
29
|
+
if (!request || !response) {
|
|
30
|
+
return next.handle();
|
|
31
|
+
}
|
|
32
|
+
const requestIdHeader = normalizeHeaderName(this.options.requestIdHeader, observability_constants_1.DEFAULT_REQUEST_ID_HEADER);
|
|
33
|
+
const correlationIdHeader = normalizeHeaderName(this.options.correlationIdHeader, observability_constants_1.DEFAULT_CORRELATION_ID_HEADER);
|
|
34
|
+
const incomingRequestId = readHeader(request.headers, requestIdHeader);
|
|
35
|
+
const incomingCorrelationId = readHeader(request.headers, correlationIdHeader);
|
|
36
|
+
const requestId = incomingRequestId || (0, crypto_1.randomUUID)();
|
|
37
|
+
const correlationId = incomingCorrelationId || requestId;
|
|
38
|
+
request.requestId = requestId;
|
|
39
|
+
request.correlationId = correlationId;
|
|
40
|
+
response.setHeader(requestIdHeader, requestId);
|
|
41
|
+
response.setHeader(correlationIdHeader, correlationId);
|
|
42
|
+
return next.handle().pipe((0, operators_1.finalize)(() => {
|
|
43
|
+
this.setTraceHeaders(response);
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
46
|
+
setTraceHeaders(response) {
|
|
47
|
+
if (this.options.exposeTraceHeaders === false || !response.setHeader) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const traceIds = (0, trace_context_helper_1.getActiveTraceIds)();
|
|
51
|
+
if (traceIds.traceId) {
|
|
52
|
+
response.setHeader('trace-id', traceIds.traceId);
|
|
53
|
+
}
|
|
54
|
+
if (traceIds.spanId) {
|
|
55
|
+
response.setHeader('span-id', traceIds.spanId);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
exports.ZolaRequestCorrelationInterceptor = ZolaRequestCorrelationInterceptor;
|
|
60
|
+
exports.ZolaRequestCorrelationInterceptor = ZolaRequestCorrelationInterceptor = __decorate([
|
|
61
|
+
(0, common_1.Injectable)(),
|
|
62
|
+
__param(0, (0, common_1.Optional)()),
|
|
63
|
+
__param(0, (0, common_1.Inject)(observability_constants_1.ZOLA_OBSERVABILITY_OPTIONS)),
|
|
64
|
+
__metadata("design:paramtypes", [Object])
|
|
65
|
+
], ZolaRequestCorrelationInterceptor);
|
|
66
|
+
function normalizeHeaderName(value, fallback) {
|
|
67
|
+
return (value || fallback).toLowerCase();
|
|
68
|
+
}
|
|
69
|
+
function readHeader(headers, name) {
|
|
70
|
+
const value = headers[name];
|
|
71
|
+
if (Array.isArray(value)) {
|
|
72
|
+
return value[0];
|
|
73
|
+
}
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=request-correlation.interceptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-correlation.interceptor.js","sourceRoot":"","sources":["../src/request-correlation.interceptor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getActiveTraceIds = getActiveTraceIds;
|
|
4
|
+
exports.getTraceLogFields = getTraceLogFields;
|
|
5
|
+
function getActiveTraceIds() {
|
|
6
|
+
var _a;
|
|
7
|
+
try {
|
|
8
|
+
const api = require('@opentelemetry/api');
|
|
9
|
+
const span = api.trace.getActiveSpan();
|
|
10
|
+
const context = (_a = span === null || span === void 0 ? void 0 : span.spanContext) === null || _a === void 0 ? void 0 : _a.call(span);
|
|
11
|
+
if (!context) {
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
traceId: context.traceId,
|
|
16
|
+
spanId: context.spanId,
|
|
17
|
+
traceFlags: context.traceFlags,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
catch (_b) {
|
|
21
|
+
return {};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function getTraceLogFields() {
|
|
25
|
+
const traceIds = getActiveTraceIds();
|
|
26
|
+
const fields = {};
|
|
27
|
+
if (traceIds.traceId) {
|
|
28
|
+
fields.trace_id = traceIds.traceId;
|
|
29
|
+
}
|
|
30
|
+
if (traceIds.spanId) {
|
|
31
|
+
fields.span_id = traceIds.spanId;
|
|
32
|
+
}
|
|
33
|
+
return fields;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=trace-context.helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-context.helper.js","sourceRoot":"","sources":["../src/trace-context.helper.ts"],"names":[],"mappings":";;;;AAEA;;IACE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,WAAW,+CAAjB,IAAI,CAAiB,CAAC;QAEtC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,UAAU,EAAE,OAAO,CAAC,UAAU;SAC/B,CAAC;IACJ,CAAC;eAAO,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;IACE,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;IACrC,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC;IACrC,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpB,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC;IACnC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { LoggerService, LogLevel } from '@nestjs/common';
|
|
2
|
+
export declare class ZolaOtelLogger implements LoggerService {
|
|
3
|
+
private readonly context?;
|
|
4
|
+
constructor(context?: string);
|
|
5
|
+
log(message: unknown, context?: string): void;
|
|
6
|
+
error(message: unknown, stack?: string, context?: string): void;
|
|
7
|
+
warn(message: unknown, context?: string): void;
|
|
8
|
+
debug(message: unknown, context?: string): void;
|
|
9
|
+
verbose(message: unknown, context?: string): void;
|
|
10
|
+
fatal(message: unknown, context?: string): void;
|
|
11
|
+
setLogLevels?(_levels: LogLevel[]): void;
|
|
12
|
+
private write;
|
|
13
|
+
private formatBody;
|
|
14
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ZolaOtelLogger = void 0;
|
|
4
|
+
const otel_log_helper_1 = require("./otel-log.helper");
|
|
5
|
+
const SEVERITY = {
|
|
6
|
+
INFO: { severityNumber: 9, severityText: 'INFO' },
|
|
7
|
+
ERROR: { severityNumber: 17, severityText: 'ERROR' },
|
|
8
|
+
WARN: { severityNumber: 13, severityText: 'WARN' },
|
|
9
|
+
DEBUG: { severityNumber: 5, severityText: 'DEBUG' },
|
|
10
|
+
TRACE: { severityNumber: 1, severityText: 'TRACE' },
|
|
11
|
+
FATAL: { severityNumber: 21, severityText: 'FATAL' },
|
|
12
|
+
};
|
|
13
|
+
class ZolaOtelLogger {
|
|
14
|
+
constructor(context) {
|
|
15
|
+
this.context = context;
|
|
16
|
+
}
|
|
17
|
+
log(message, context) {
|
|
18
|
+
this.write('INFO', SEVERITY.INFO, message, context);
|
|
19
|
+
}
|
|
20
|
+
error(message, stack, context) {
|
|
21
|
+
this.write('ERROR', SEVERITY.ERROR, message, context, stack);
|
|
22
|
+
}
|
|
23
|
+
warn(message, context) {
|
|
24
|
+
this.write('WARN', SEVERITY.WARN, message, context);
|
|
25
|
+
}
|
|
26
|
+
debug(message, context) {
|
|
27
|
+
this.write('DEBUG', SEVERITY.DEBUG, message, context);
|
|
28
|
+
}
|
|
29
|
+
verbose(message, context) {
|
|
30
|
+
this.write('VERBOSE', SEVERITY.TRACE, message, context);
|
|
31
|
+
}
|
|
32
|
+
fatal(message, context) {
|
|
33
|
+
this.write('FATAL', SEVERITY.FATAL, message, context);
|
|
34
|
+
}
|
|
35
|
+
setLogLevels(_levels) {
|
|
36
|
+
}
|
|
37
|
+
write(consoleLevel, severity, message, context, stack) {
|
|
38
|
+
const resolvedContext = context || this.context || 'App';
|
|
39
|
+
const body = this.formatBody(message, stack);
|
|
40
|
+
console.log(`[Nest] ${process.pid} - ${resolvedContext} ${body}`);
|
|
41
|
+
(0, otel_log_helper_1.emitOtelLog)({
|
|
42
|
+
severityNumber: severity.severityNumber,
|
|
43
|
+
severityText: severity.severityText,
|
|
44
|
+
body,
|
|
45
|
+
context: resolvedContext,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
formatBody(message, stack) {
|
|
49
|
+
if (typeof message === 'string') {
|
|
50
|
+
return stack ? `${message}\n${stack}` : message;
|
|
51
|
+
}
|
|
52
|
+
if (message && typeof message === 'object') {
|
|
53
|
+
return JSON.stringify(message);
|
|
54
|
+
}
|
|
55
|
+
return String(message);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.ZolaOtelLogger = ZolaOtelLogger;
|
|
59
|
+
//# sourceMappingURL=zola-otel.logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zola-otel.logger.js","sourceRoot":"","sources":["../src/zola-otel.logger.ts"],"names":[],"mappings":";;;AAEA,uDAAgD;AAEhD,MAAM,QAAQ,GAAG;IACf,IAAI,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE;IACjD,KAAK,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE;IACpD,IAAI,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE;IAClD,KAAK,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,YAAY,EAAE,OAAO,EAAE;IACnD,KAAK,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,YAAY,EAAE,OAAO,EAAE;IACnD,KAAK,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE;CACrD,CAAC;AAEF;IACE,YAA6B,OAAgB;uBAAhB,OAAO;IAAY,CAAC;IAEjD,GAAG,CAAC,OAAgB,EAAE,OAAgB;QACpC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,OAAgB,EAAE,KAAc,EAAE,OAAgB;QACtD,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAC/D,CAAC;IAED,IAAI,CAAC,OAAgB,EAAE,OAAgB;QACrC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,OAAgB,EAAE,OAAgB;QACtC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACxD,CAAC;IAED,OAAO,CAAC,OAAgB,EAAE,OAAgB;QACxC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;IAED,KAAK,CAAC,OAAgB,EAAE,OAAgB;QACtC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACxD,CAAC;IAED,YAAY,CAAE,OAAmB;IAEjC,CAAC;IAEO,KAAK,CACX,YAAoB,EACpB,QAA0D,EAC1D,OAAgB,EAChB,OAAgB,EAChB,KAAc;QAEd,MAAM,eAAe,GAAG,OAAO,IAAI,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC;QACzD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAE7C,OAAO,CAAC,GAAG,CAAC,UAAU,OAAO,CAAC,GAAG,OAAO,eAAe,IAAI,IAAI,EAAE,CAAC,CAAC;QAEnE,IAAA,6BAAW,EAAC;YACV,cAAc,EAAE,QAAQ,CAAC,cAAc;YACvC,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,IAAI;YACJ,OAAO,EAAE,eAAe;SACzB,CAAC,CAAC;IACL,CAAC;IAEO,UAAU,CAAC,OAAgB,EAAE,KAAc;QACjD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;QAClD,CAAC;QAED,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC3C,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC;QAED,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { NestMiddleware } from '@nestjs/common';
|
|
2
|
+
import { NextFunction, Request, Response } from 'express';
|
|
3
|
+
import { ZolaObservabilityOptions } from './observability-options';
|
|
4
|
+
export declare class ZolaRequestLoggingMiddleware implements NestMiddleware {
|
|
5
|
+
private readonly options;
|
|
6
|
+
constructor(options: ZolaObservabilityOptions);
|
|
7
|
+
use(request: Request, response: Response, next: NextFunction): void;
|
|
8
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.ZolaRequestLoggingMiddleware = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const observability_constants_1 = require("./observability.constants");
|
|
18
|
+
const otel_log_helper_1 = require("./otel-log.helper");
|
|
19
|
+
const trace_context_helper_1 = require("./trace-context.helper");
|
|
20
|
+
let ZolaRequestLoggingMiddleware = class ZolaRequestLoggingMiddleware {
|
|
21
|
+
constructor(options) {
|
|
22
|
+
this.options = options;
|
|
23
|
+
}
|
|
24
|
+
use(request, response, next) {
|
|
25
|
+
if (this.options.logRequests === false) {
|
|
26
|
+
next();
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const traceIds = (0, trace_context_helper_1.getActiveTraceIds)();
|
|
30
|
+
response.on('finish', () => {
|
|
31
|
+
(0, otel_log_helper_1.emitHttpRequestLog)(request, response.statusCode, traceIds);
|
|
32
|
+
});
|
|
33
|
+
next();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
exports.ZolaRequestLoggingMiddleware = ZolaRequestLoggingMiddleware;
|
|
37
|
+
exports.ZolaRequestLoggingMiddleware = ZolaRequestLoggingMiddleware = __decorate([
|
|
38
|
+
(0, common_1.Injectable)(),
|
|
39
|
+
__param(0, (0, common_1.Inject)(observability_constants_1.ZOLA_OBSERVABILITY_OPTIONS)),
|
|
40
|
+
__metadata("design:paramtypes", [Object])
|
|
41
|
+
], ZolaRequestLoggingMiddleware);
|
|
42
|
+
//# sourceMappingURL=zola-request-logging.middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zola-request-logging.middleware.js","sourceRoot":"","sources":["../src/zola-request-logging.middleware.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAoE;AAGpE,uEAAuE;AAEvE,uDAAuD;AACvD,iEAA2D;AAGpD,IAAM,4BAA4B,GAAlC,MAAM,4BAA4B;IACvC,YAEmB,OAAiC;uBAAjC,OAAO;IACvB,CAAC;IAEJ,GAAG,CAAC,OAAgB,EAAE,QAAkB,EAAE,IAAkB;QAC1D,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;YACvC,IAAI,EAAE,CAAC;YACP,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,IAAA,wCAAiB,GAAE,CAAC;QAErC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACzB,IAAA,oCAAkB,EAAC,OAAO,EAAE,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH,IAAI,EAAE,CAAC;IACT,CAAC;CACF,CAAA;;uCApBY,4BAA4B;IADxC,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,eAAM,EAAC,oDAA0B,CAAC,CAAA;;GAF1B,4BAA4B,CAoBxC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zola_do/observability",
|
|
3
|
+
"version": "0.3.1",
|
|
4
|
+
"description": "NestJS observability helpers for OpenTelemetry, request correlation, and trace-aware logging",
|
|
5
|
+
"author": "zolaDO",
|
|
6
|
+
"license": "ISC",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=20.0.0"
|
|
10
|
+
},
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"require": "./dist/index.js",
|
|
20
|
+
"default": "./dist/index.js"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist",
|
|
25
|
+
"README.md"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"clean": "rimraf dist",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
30
|
+
"build": "rimraf dist && tsc",
|
|
31
|
+
"prepublishOnly": "rimraf dist && tsc"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"@nestjs/common": "^10.0.0 || ^11.0.0 || ^12.0.0",
|
|
35
|
+
"@nestjs/core": "^10.0.0 || ^11.0.0 || ^12.0.0",
|
|
36
|
+
"@opentelemetry/api": "^1.0.0",
|
|
37
|
+
"@opentelemetry/api-logs": "^0.205.0",
|
|
38
|
+
"@opentelemetry/auto-instrumentations-node": "^0.60.0",
|
|
39
|
+
"@opentelemetry/exporter-logs-otlp-grpc": "^0.205.0",
|
|
40
|
+
"@opentelemetry/exporter-logs-otlp-http": "^0.205.0",
|
|
41
|
+
"@opentelemetry/exporter-metrics-otlp-grpc": "^0.205.0",
|
|
42
|
+
"@opentelemetry/exporter-metrics-otlp-http": "^0.205.0",
|
|
43
|
+
"@opentelemetry/exporter-trace-otlp-grpc": "^0.205.0",
|
|
44
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.205.0",
|
|
45
|
+
"@opentelemetry/instrumentation-http": "^0.205.0",
|
|
46
|
+
"@opentelemetry/instrumentation-nestjs-core": "^0.52.0",
|
|
47
|
+
"@opentelemetry/instrumentation-pg": "^0.54.0",
|
|
48
|
+
"@opentelemetry/resources": "^2.0.0",
|
|
49
|
+
"@opentelemetry/sdk-node": "^0.205.0",
|
|
50
|
+
"@opentelemetry/sdk-logs": "^0.205.0",
|
|
51
|
+
"@opentelemetry/semantic-conventions": "^1.37.0",
|
|
52
|
+
"reflect-metadata": "^0.1.0 || ^0.2.0",
|
|
53
|
+
"rxjs": "^7.0.0 || ^8.0.0",
|
|
54
|
+
"@opentelemetry/sdk-metrics": "^2.0.0"
|
|
55
|
+
},
|
|
56
|
+
"peerDependenciesMeta": {
|
|
57
|
+
"@opentelemetry/api": {
|
|
58
|
+
"optional": true
|
|
59
|
+
},
|
|
60
|
+
"@opentelemetry/api-logs": {
|
|
61
|
+
"optional": true
|
|
62
|
+
},
|
|
63
|
+
"@opentelemetry/auto-instrumentations-node": {
|
|
64
|
+
"optional": true
|
|
65
|
+
},
|
|
66
|
+
"@opentelemetry/exporter-logs-otlp-grpc": {
|
|
67
|
+
"optional": true
|
|
68
|
+
},
|
|
69
|
+
"@opentelemetry/exporter-logs-otlp-http": {
|
|
70
|
+
"optional": true
|
|
71
|
+
},
|
|
72
|
+
"@opentelemetry/exporter-metrics-otlp-grpc": {
|
|
73
|
+
"optional": true
|
|
74
|
+
},
|
|
75
|
+
"@opentelemetry/exporter-metrics-otlp-http": {
|
|
76
|
+
"optional": true
|
|
77
|
+
},
|
|
78
|
+
"@opentelemetry/exporter-trace-otlp-grpc": {
|
|
79
|
+
"optional": true
|
|
80
|
+
},
|
|
81
|
+
"@opentelemetry/exporter-trace-otlp-http": {
|
|
82
|
+
"optional": true
|
|
83
|
+
},
|
|
84
|
+
"@opentelemetry/instrumentation-http": {
|
|
85
|
+
"optional": true
|
|
86
|
+
},
|
|
87
|
+
"@opentelemetry/instrumentation-nestjs-core": {
|
|
88
|
+
"optional": true
|
|
89
|
+
},
|
|
90
|
+
"@opentelemetry/instrumentation-pg": {
|
|
91
|
+
"optional": true
|
|
92
|
+
},
|
|
93
|
+
"@opentelemetry/resources": {
|
|
94
|
+
"optional": true
|
|
95
|
+
},
|
|
96
|
+
"@opentelemetry/sdk-node": {
|
|
97
|
+
"optional": true
|
|
98
|
+
},
|
|
99
|
+
"@opentelemetry/sdk-logs": {
|
|
100
|
+
"optional": true
|
|
101
|
+
},
|
|
102
|
+
"@opentelemetry/semantic-conventions": {
|
|
103
|
+
"optional": true
|
|
104
|
+
},
|
|
105
|
+
"@opentelemetry/sdk-metrics": {
|
|
106
|
+
"optional": true
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
"devDependencies": {
|
|
110
|
+
"rimraf": "^6.1.3",
|
|
111
|
+
"@typescript/native": "npm:typescript@^7.0.2",
|
|
112
|
+
"typescript": "npm:@typescript/typescript6@^6.0.2"
|
|
113
|
+
},
|
|
114
|
+
"repository": {
|
|
115
|
+
"directory": "packages/observability",
|
|
116
|
+
"type": "git",
|
|
117
|
+
"url": "https://github.com/zola0031/zola-nestjs-shared.git"
|
|
118
|
+
},
|
|
119
|
+
"homepage": "https://github.com/zola0031/zola-nestjs-shared#readme",
|
|
120
|
+
"bugs": {
|
|
121
|
+
"url": "https://github.com/zola0031/zola-nestjs-shared/issues"
|
|
122
|
+
},
|
|
123
|
+
"funding": {
|
|
124
|
+
"type": "github",
|
|
125
|
+
"url": "https://github.com/sponsors/zola0031"
|
|
126
|
+
},
|
|
127
|
+
"keywords": [
|
|
128
|
+
"nestjs",
|
|
129
|
+
"typescript",
|
|
130
|
+
"observability",
|
|
131
|
+
"opentelemetry",
|
|
132
|
+
"telemetry",
|
|
133
|
+
"tracing",
|
|
134
|
+
"metrics",
|
|
135
|
+
"zola_do",
|
|
136
|
+
"nestjs-shared"
|
|
137
|
+
]
|
|
138
|
+
}
|