@ryanzeng/nest-observe 0.1.1 → 0.1.2
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 +27 -1
- package/dist/index.d.mts +42 -15
- package/dist/index.d.ts +42 -15
- package/dist/index.js +347 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +353 -39
- package/dist/index.mjs.map +1 -1
- package/dist/register.js +313 -40
- package/dist/register.js.map +1 -1
- package/dist/register.mjs +313 -40
- package/dist/register.mjs.map +1 -1
- package/package.json +19 -9
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ OBSERVE_ENVIRONMENT=production
|
|
|
36
36
|
|
|
37
37
|
通用 endpoint 会自动派生 `/v1/traces`、`/v1/metrics` 和 `/v1/logs`。也可使用标准的 `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`、`OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`、`OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` 分别覆盖。
|
|
38
38
|
|
|
39
|
-
初始化或 exporter 配置失败时,SDK
|
|
39
|
+
初始化或 exporter 配置失败时,SDK 默认保持 fail-open,不会阻止业务应用启动;同时会把脱敏、限频后的诊断信息写入 `stderr`,避免观测链路静默失效。
|
|
40
40
|
|
|
41
41
|
## OpenObserve 完整示例
|
|
42
42
|
|
|
@@ -56,6 +56,8 @@ import { ObserveModule } from '@ryanzeng/nest-observe';
|
|
|
56
56
|
export class AppModule {}
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
+
Module-only 模式还会注册一个全局 Nest interceptor,补采因 HTTP 模块已经加载而无法挂载底层 hook 的已匹配 Controller 请求指标。它与早期 HTTP instrumentation 共享请求状态,不会重复计数。
|
|
60
|
+
|
|
59
61
|
## 装饰器
|
|
60
62
|
|
|
61
63
|
```ts
|
|
@@ -95,6 +97,7 @@ Traces:
|
|
|
95
97
|
Logs:
|
|
96
98
|
|
|
97
99
|
- 默认 Nest `Logger` 的 `verbose/debug/log/warn/error/fatal`
|
|
100
|
+
- 对象和数组消息会在脱敏后序列化成 JSON 字符串,保证 OpenObserve 的标准 `body` 字段始终可见
|
|
98
101
|
- OTLP severity、`nestjs.context`、`trace_id`、`span_id`
|
|
99
102
|
- `service.name`、`service.version`、`deployment.environment.name`
|
|
100
103
|
- `StructuredLogEmitter` 抽象可用于后续 Pino/Winston adapter
|
|
@@ -110,6 +113,8 @@ Metrics:
|
|
|
110
113
|
|
|
111
114
|
HTTP 与 Nest method 指标只使用 route template、method、status、controller/provider/method 等有限维度,避免把 URL id 或请求数据变成高基数标签。
|
|
112
115
|
|
|
116
|
+
OpenObserve 会把 OTel metric 名称中的 `.` 转换为 `_`,例如 `process.uptime` 对应 `process_uptime` stream,`http.server.request.count` 对应 `http_server_request_count`。指标使用独立的 Metrics streams,不在 Logs 的 `default` stream 中;首次数据默认最多需要等待 `metricExportIntervalMillis`(默认 60 秒),也可以调用 `forceFlush()` 立即导出。应用关闭时 SDK 会先采集并 flush runtime observable metrics,再移除 callbacks。
|
|
117
|
+
|
|
113
118
|
## 程序化配置
|
|
114
119
|
|
|
115
120
|
```ts
|
|
@@ -134,6 +139,27 @@ await telemetry.shutdown();
|
|
|
134
139
|
|
|
135
140
|
环境变量方式仍是推荐方式。有合理默认值的配置无需填写。
|
|
136
141
|
|
|
142
|
+
### 故障诊断
|
|
143
|
+
|
|
144
|
+
SDK 会区分本地 pipeline 已启动和远端导出是否健康。`status` 可能为 `inactive`、`starting`、`active`、`degraded` 或 `stopped`;例如 OTLP endpoint 返回 401 时,业务继续运行,但状态会变为 `degraded`:
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
const telemetry = observe({
|
|
148
|
+
serviceName: 'mall-app',
|
|
149
|
+
endpoint: 'https://observe.example.com',
|
|
150
|
+
onError(event) {
|
|
151
|
+
// event.error 已脱敏,不包含 Authorization、token 等凭据。
|
|
152
|
+
console.error(event.signal, event.stage, event.error.message);
|
|
153
|
+
},
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
console.log(telemetry.status, telemetry.lastError);
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
默认诊断日志直接写入原始 `stderr`,不会经过 Nest Logger,因而不会形成“导出失败日志再次导出”的递归。相同错误在恢复前只报告一次。可以设置 `diagnosticLogging: false` 关闭默认输出,并继续通过 `onError` 接收事件。
|
|
160
|
+
|
|
161
|
+
同步初始化失败默认返回 `started: false`、`status: 'inactive'` 的 handle。测试或严格部署场景可以设置 `failFast: true`,让同步初始化错误直接阻止 Nest 启动;异步 OTLP 导出错误仍采用 fail-open,并通过 `degraded`、`lastError` 和 `onError` 暴露。
|
|
162
|
+
|
|
137
163
|
### Sampling
|
|
138
164
|
|
|
139
165
|
支持显式 `sampling`(0–1)以及标准环境变量:
|
package/dist/index.d.mts
CHANGED
|
@@ -6,9 +6,10 @@ import { Logger } from '@opentelemetry/api-logs';
|
|
|
6
6
|
import { InstrumentationConfig, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';
|
|
7
7
|
import { NestInstrumentation } from '@opentelemetry/instrumentation-nestjs-core';
|
|
8
8
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
9
|
-
import { DynamicModule } from '@nestjs/common';
|
|
10
|
-
import {
|
|
9
|
+
import { NestInterceptor, ExecutionContext, CallHandler, DynamicModule } from '@nestjs/common';
|
|
10
|
+
import { Observable } from 'rxjs';
|
|
11
11
|
import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
|
|
12
|
+
import { Resource } from '@opentelemetry/resources';
|
|
12
13
|
|
|
13
14
|
interface ObserveExporters {
|
|
14
15
|
/** Primarily useful for custom backends and tests. OTLP is used by default. */
|
|
@@ -16,6 +17,15 @@ interface ObserveExporters {
|
|
|
16
17
|
log?: LogRecordExporter;
|
|
17
18
|
metricReader?: MetricReader;
|
|
18
19
|
}
|
|
20
|
+
type ObserveSignal = 'sdk' | 'traces' | 'metrics' | 'logs';
|
|
21
|
+
type ObserveErrorStage = 'initialization' | 'export' | 'forceFlush' | 'shutdown';
|
|
22
|
+
type ObserveStatus = 'inactive' | 'starting' | 'active' | 'degraded' | 'stopped';
|
|
23
|
+
interface ObserveErrorEvent {
|
|
24
|
+
signal: ObserveSignal;
|
|
25
|
+
stage: ObserveErrorStage;
|
|
26
|
+
error: Error;
|
|
27
|
+
timestamp: number;
|
|
28
|
+
}
|
|
19
29
|
interface ObserveOptions {
|
|
20
30
|
enabled?: boolean;
|
|
21
31
|
serviceName?: string;
|
|
@@ -34,6 +44,12 @@ interface ObserveOptions {
|
|
|
34
44
|
exportTimeoutMillis?: number;
|
|
35
45
|
metricExportIntervalMillis?: number;
|
|
36
46
|
resourceAttributes?: Record<string, string | number | boolean>;
|
|
47
|
+
/** Writes sanitized, rate-limited SDK/export failures to stderr. Defaults to true. */
|
|
48
|
+
diagnosticLogging?: boolean;
|
|
49
|
+
/** Receives sanitized pipeline failure notifications without affecting the application. */
|
|
50
|
+
onError?: (event: ObserveErrorEvent) => void;
|
|
51
|
+
/** Throws synchronous initialization failures instead of degrading to an inactive handle. */
|
|
52
|
+
failFast?: boolean;
|
|
37
53
|
exporters?: ObserveExporters;
|
|
38
54
|
}
|
|
39
55
|
interface ResolvedObserveConfig {
|
|
@@ -58,10 +74,14 @@ interface ResolvedObserveConfig {
|
|
|
58
74
|
exportTimeoutMillis: number;
|
|
59
75
|
metricExportIntervalMillis: number;
|
|
60
76
|
resourceAttributes: Record<string, string | number | boolean>;
|
|
77
|
+
diagnosticLogging: boolean;
|
|
78
|
+
failFast: boolean;
|
|
61
79
|
exporters?: ObserveExporters;
|
|
62
80
|
}
|
|
63
81
|
interface ObserveHandle {
|
|
64
82
|
readonly started: boolean;
|
|
83
|
+
readonly status: ObserveStatus;
|
|
84
|
+
readonly lastError: ObserveErrorEvent | undefined;
|
|
65
85
|
readonly config: Readonly<ResolvedObserveConfig>;
|
|
66
86
|
forceFlush(): Promise<void>;
|
|
67
87
|
shutdown(): Promise<void>;
|
|
@@ -132,8 +152,8 @@ declare class HttpRequestMetrics {
|
|
|
132
152
|
private readonly errorCount;
|
|
133
153
|
private readonly startedAt;
|
|
134
154
|
constructor(meter: Meter, serviceName: string);
|
|
135
|
-
start(request: IncomingMessage):
|
|
136
|
-
record(request: IncomingMessage, response: ServerResponse):
|
|
155
|
+
start(request: IncomingMessage): boolean;
|
|
156
|
+
record(request: IncomingMessage, response: ServerResponse): boolean;
|
|
137
157
|
}
|
|
138
158
|
|
|
139
159
|
declare class RuntimeMetrics {
|
|
@@ -162,14 +182,29 @@ declare class NestMethodInstrumenter {
|
|
|
162
182
|
private instrumentTarget;
|
|
163
183
|
}
|
|
164
184
|
|
|
185
|
+
interface ObserveRuntime extends ObserveHandle {
|
|
186
|
+
readonly tracerProvider: NodeTracerProvider | undefined;
|
|
187
|
+
readonly meterProvider: MeterProvider | undefined;
|
|
188
|
+
readonly loggerProvider: LoggerProvider | undefined;
|
|
189
|
+
readonly httpRequestMetrics: HttpRequestMetrics | undefined;
|
|
190
|
+
}
|
|
191
|
+
declare function observe(options?: ObserveOptions): ObserveRuntime;
|
|
192
|
+
declare function getObserveRuntime(): ObserveRuntime | undefined;
|
|
193
|
+
|
|
165
194
|
declare const OBSERVE_OPTIONS: unique symbol;
|
|
166
195
|
declare const OBSERVE_HANDLE: unique symbol;
|
|
196
|
+
/** Provides inbound HTTP metrics when module-load instrumentation was registered too late. */
|
|
197
|
+
declare class NestHttpMetricsInterceptor implements NestInterceptor {
|
|
198
|
+
private readonly handle;
|
|
199
|
+
constructor(handle: ObserveRuntime);
|
|
200
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
|
|
201
|
+
}
|
|
167
202
|
declare class ObserveModule {
|
|
168
203
|
static forRoot(options?: ObserveOptions): DynamicModule;
|
|
169
204
|
}
|
|
170
205
|
|
|
171
|
-
declare const SDK_NAME
|
|
172
|
-
declare const SDK_VERSION
|
|
206
|
+
declare const SDK_NAME: string;
|
|
207
|
+
declare const SDK_VERSION: string;
|
|
173
208
|
declare function createObserveResource(config: ResolvedObserveConfig): Resource;
|
|
174
209
|
|
|
175
210
|
declare const REDACTED = "[REDACTED]";
|
|
@@ -186,12 +221,4 @@ declare class SpanRedactionProcessor implements SpanProcessor {
|
|
|
186
221
|
shutdown(): Promise<void>;
|
|
187
222
|
}
|
|
188
223
|
|
|
189
|
-
|
|
190
|
-
readonly tracerProvider: NodeTracerProvider | undefined;
|
|
191
|
-
readonly meterProvider: MeterProvider | undefined;
|
|
192
|
-
readonly loggerProvider: LoggerProvider | undefined;
|
|
193
|
-
}
|
|
194
|
-
declare function observe(options?: ObserveOptions): ObserveRuntime;
|
|
195
|
-
declare function getObserveRuntime(): ObserveRuntime | undefined;
|
|
196
|
-
|
|
197
|
-
export { CompatibleNestInstrumentation, type CompatibleNestInstrumentationConfig, HttpRequestMetrics, IgnoreTrace, type NestComponentKind, NestLoggerInstrumentation, NestMethodInstrumenter, OBSERVE_HANDLE, OBSERVE_OPTIONS, type ObserveExporters, type ObserveHandle, ObserveModule, type ObserveOptions, type ObserveRuntime, OpenTelemetryLogEmitter, REDACTED, type ResolvedObserveConfig, RuntimeMetrics, SDK_NAME, SDK_VERSION, SpanRedactionProcessor, type StructuredLogEmitter, type StructuredLogRecord, Trace, type TraceOptions, createObserveResource, getObserveRuntime, isSensitiveKey, isTraceDecorated, isTraceIgnored, markTraceDecorated, markTraceIgnored, observe, parseKeyValueList, redact, redactText, resolveObserveConfig, sanitizeHeaders };
|
|
224
|
+
export { CompatibleNestInstrumentation, type CompatibleNestInstrumentationConfig, HttpRequestMetrics, IgnoreTrace, type NestComponentKind, NestHttpMetricsInterceptor, NestLoggerInstrumentation, NestMethodInstrumenter, OBSERVE_HANDLE, OBSERVE_OPTIONS, type ObserveErrorEvent, type ObserveErrorStage, type ObserveExporters, type ObserveHandle, ObserveModule, type ObserveOptions, type ObserveRuntime, type ObserveSignal, type ObserveStatus, OpenTelemetryLogEmitter, REDACTED, type ResolvedObserveConfig, RuntimeMetrics, SDK_NAME, SDK_VERSION, SpanRedactionProcessor, type StructuredLogEmitter, type StructuredLogRecord, Trace, type TraceOptions, createObserveResource, getObserveRuntime, isSensitiveKey, isTraceDecorated, isTraceIgnored, markTraceDecorated, markTraceIgnored, observe, parseKeyValueList, redact, redactText, resolveObserveConfig, sanitizeHeaders };
|
package/dist/index.d.ts
CHANGED
|
@@ -6,9 +6,10 @@ import { Logger } from '@opentelemetry/api-logs';
|
|
|
6
6
|
import { InstrumentationConfig, InstrumentationNodeModuleDefinition } from '@opentelemetry/instrumentation';
|
|
7
7
|
import { NestInstrumentation } from '@opentelemetry/instrumentation-nestjs-core';
|
|
8
8
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
9
|
-
import { DynamicModule } from '@nestjs/common';
|
|
10
|
-
import {
|
|
9
|
+
import { NestInterceptor, ExecutionContext, CallHandler, DynamicModule } from '@nestjs/common';
|
|
10
|
+
import { Observable } from 'rxjs';
|
|
11
11
|
import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
|
|
12
|
+
import { Resource } from '@opentelemetry/resources';
|
|
12
13
|
|
|
13
14
|
interface ObserveExporters {
|
|
14
15
|
/** Primarily useful for custom backends and tests. OTLP is used by default. */
|
|
@@ -16,6 +17,15 @@ interface ObserveExporters {
|
|
|
16
17
|
log?: LogRecordExporter;
|
|
17
18
|
metricReader?: MetricReader;
|
|
18
19
|
}
|
|
20
|
+
type ObserveSignal = 'sdk' | 'traces' | 'metrics' | 'logs';
|
|
21
|
+
type ObserveErrorStage = 'initialization' | 'export' | 'forceFlush' | 'shutdown';
|
|
22
|
+
type ObserveStatus = 'inactive' | 'starting' | 'active' | 'degraded' | 'stopped';
|
|
23
|
+
interface ObserveErrorEvent {
|
|
24
|
+
signal: ObserveSignal;
|
|
25
|
+
stage: ObserveErrorStage;
|
|
26
|
+
error: Error;
|
|
27
|
+
timestamp: number;
|
|
28
|
+
}
|
|
19
29
|
interface ObserveOptions {
|
|
20
30
|
enabled?: boolean;
|
|
21
31
|
serviceName?: string;
|
|
@@ -34,6 +44,12 @@ interface ObserveOptions {
|
|
|
34
44
|
exportTimeoutMillis?: number;
|
|
35
45
|
metricExportIntervalMillis?: number;
|
|
36
46
|
resourceAttributes?: Record<string, string | number | boolean>;
|
|
47
|
+
/** Writes sanitized, rate-limited SDK/export failures to stderr. Defaults to true. */
|
|
48
|
+
diagnosticLogging?: boolean;
|
|
49
|
+
/** Receives sanitized pipeline failure notifications without affecting the application. */
|
|
50
|
+
onError?: (event: ObserveErrorEvent) => void;
|
|
51
|
+
/** Throws synchronous initialization failures instead of degrading to an inactive handle. */
|
|
52
|
+
failFast?: boolean;
|
|
37
53
|
exporters?: ObserveExporters;
|
|
38
54
|
}
|
|
39
55
|
interface ResolvedObserveConfig {
|
|
@@ -58,10 +74,14 @@ interface ResolvedObserveConfig {
|
|
|
58
74
|
exportTimeoutMillis: number;
|
|
59
75
|
metricExportIntervalMillis: number;
|
|
60
76
|
resourceAttributes: Record<string, string | number | boolean>;
|
|
77
|
+
diagnosticLogging: boolean;
|
|
78
|
+
failFast: boolean;
|
|
61
79
|
exporters?: ObserveExporters;
|
|
62
80
|
}
|
|
63
81
|
interface ObserveHandle {
|
|
64
82
|
readonly started: boolean;
|
|
83
|
+
readonly status: ObserveStatus;
|
|
84
|
+
readonly lastError: ObserveErrorEvent | undefined;
|
|
65
85
|
readonly config: Readonly<ResolvedObserveConfig>;
|
|
66
86
|
forceFlush(): Promise<void>;
|
|
67
87
|
shutdown(): Promise<void>;
|
|
@@ -132,8 +152,8 @@ declare class HttpRequestMetrics {
|
|
|
132
152
|
private readonly errorCount;
|
|
133
153
|
private readonly startedAt;
|
|
134
154
|
constructor(meter: Meter, serviceName: string);
|
|
135
|
-
start(request: IncomingMessage):
|
|
136
|
-
record(request: IncomingMessage, response: ServerResponse):
|
|
155
|
+
start(request: IncomingMessage): boolean;
|
|
156
|
+
record(request: IncomingMessage, response: ServerResponse): boolean;
|
|
137
157
|
}
|
|
138
158
|
|
|
139
159
|
declare class RuntimeMetrics {
|
|
@@ -162,14 +182,29 @@ declare class NestMethodInstrumenter {
|
|
|
162
182
|
private instrumentTarget;
|
|
163
183
|
}
|
|
164
184
|
|
|
185
|
+
interface ObserveRuntime extends ObserveHandle {
|
|
186
|
+
readonly tracerProvider: NodeTracerProvider | undefined;
|
|
187
|
+
readonly meterProvider: MeterProvider | undefined;
|
|
188
|
+
readonly loggerProvider: LoggerProvider | undefined;
|
|
189
|
+
readonly httpRequestMetrics: HttpRequestMetrics | undefined;
|
|
190
|
+
}
|
|
191
|
+
declare function observe(options?: ObserveOptions): ObserveRuntime;
|
|
192
|
+
declare function getObserveRuntime(): ObserveRuntime | undefined;
|
|
193
|
+
|
|
165
194
|
declare const OBSERVE_OPTIONS: unique symbol;
|
|
166
195
|
declare const OBSERVE_HANDLE: unique symbol;
|
|
196
|
+
/** Provides inbound HTTP metrics when module-load instrumentation was registered too late. */
|
|
197
|
+
declare class NestHttpMetricsInterceptor implements NestInterceptor {
|
|
198
|
+
private readonly handle;
|
|
199
|
+
constructor(handle: ObserveRuntime);
|
|
200
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
|
|
201
|
+
}
|
|
167
202
|
declare class ObserveModule {
|
|
168
203
|
static forRoot(options?: ObserveOptions): DynamicModule;
|
|
169
204
|
}
|
|
170
205
|
|
|
171
|
-
declare const SDK_NAME
|
|
172
|
-
declare const SDK_VERSION
|
|
206
|
+
declare const SDK_NAME: string;
|
|
207
|
+
declare const SDK_VERSION: string;
|
|
173
208
|
declare function createObserveResource(config: ResolvedObserveConfig): Resource;
|
|
174
209
|
|
|
175
210
|
declare const REDACTED = "[REDACTED]";
|
|
@@ -186,12 +221,4 @@ declare class SpanRedactionProcessor implements SpanProcessor {
|
|
|
186
221
|
shutdown(): Promise<void>;
|
|
187
222
|
}
|
|
188
223
|
|
|
189
|
-
|
|
190
|
-
readonly tracerProvider: NodeTracerProvider | undefined;
|
|
191
|
-
readonly meterProvider: MeterProvider | undefined;
|
|
192
|
-
readonly loggerProvider: LoggerProvider | undefined;
|
|
193
|
-
}
|
|
194
|
-
declare function observe(options?: ObserveOptions): ObserveRuntime;
|
|
195
|
-
declare function getObserveRuntime(): ObserveRuntime | undefined;
|
|
196
|
-
|
|
197
|
-
export { CompatibleNestInstrumentation, type CompatibleNestInstrumentationConfig, HttpRequestMetrics, IgnoreTrace, type NestComponentKind, NestLoggerInstrumentation, NestMethodInstrumenter, OBSERVE_HANDLE, OBSERVE_OPTIONS, type ObserveExporters, type ObserveHandle, ObserveModule, type ObserveOptions, type ObserveRuntime, OpenTelemetryLogEmitter, REDACTED, type ResolvedObserveConfig, RuntimeMetrics, SDK_NAME, SDK_VERSION, SpanRedactionProcessor, type StructuredLogEmitter, type StructuredLogRecord, Trace, type TraceOptions, createObserveResource, getObserveRuntime, isSensitiveKey, isTraceDecorated, isTraceIgnored, markTraceDecorated, markTraceIgnored, observe, parseKeyValueList, redact, redactText, resolveObserveConfig, sanitizeHeaders };
|
|
224
|
+
export { CompatibleNestInstrumentation, type CompatibleNestInstrumentationConfig, HttpRequestMetrics, IgnoreTrace, type NestComponentKind, NestHttpMetricsInterceptor, NestLoggerInstrumentation, NestMethodInstrumenter, OBSERVE_HANDLE, OBSERVE_OPTIONS, type ObserveErrorEvent, type ObserveErrorStage, type ObserveExporters, type ObserveHandle, ObserveModule, type ObserveOptions, type ObserveRuntime, type ObserveSignal, type ObserveStatus, OpenTelemetryLogEmitter, REDACTED, type ResolvedObserveConfig, RuntimeMetrics, SDK_NAME, SDK_VERSION, SpanRedactionProcessor, type StructuredLogEmitter, type StructuredLogRecord, Trace, type TraceOptions, createObserveResource, getObserveRuntime, isSensitiveKey, isTraceDecorated, isTraceIgnored, markTraceDecorated, markTraceIgnored, observe, parseKeyValueList, redact, redactText, resolveObserveConfig, sanitizeHeaders };
|