@shuttle-labs/node-observability 1.0.3 → 1.0.5

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/dist/register.js CHANGED
@@ -4,11 +4,16 @@ const sdk_node_1 = require("@opentelemetry/sdk-node");
4
4
  const auto_instrumentations_node_1 = require("@opentelemetry/auto-instrumentations-node");
5
5
  const exporter_metrics_otlp_http_1 = require("@opentelemetry/exporter-metrics-otlp-http");
6
6
  const sdk_metrics_1 = require("@opentelemetry/sdk-metrics");
7
+ const exporter_logs_otlp_http_1 = require("@opentelemetry/exporter-logs-otlp-http");
8
+ const sdk_logs_1 = require("@opentelemetry/sdk-logs");
9
+ const api_logs_1 = require("@opentelemetry/api-logs");
7
10
  // Guard against double-initialization (e.g. hot reload, test environments)
8
11
  const g = global;
9
12
  if (!g.__otelSdkInitialized) {
10
13
  g.__otelSdkInitialized = true;
11
14
  const exportIntervalMillis = Number(process.env.OTEL_METRIC_EXPORT_INTERVAL ?? 15000);
15
+ const logExporter = new exporter_logs_otlp_http_1.OTLPLogExporter();
16
+ const logProcessor = new sdk_logs_1.BatchLogRecordProcessor(logExporter);
12
17
  const sdk = new sdk_node_1.NodeSDK({
13
18
  // Resource (service.name, deployment.environment) is read automatically
14
19
  // from OTEL_SERVICE_NAME and OTEL_RESOURCE_ATTRIBUTES env vars
@@ -18,6 +23,8 @@ if (!g.__otelSdkInitialized) {
18
23
  exporter: new exporter_metrics_otlp_http_1.OTLPMetricExporter(),
19
24
  exportIntervalMillis: Number.isFinite(exportIntervalMillis) ? exportIntervalMillis : 15000,
20
25
  }),
26
+ // Logs — exported via OTLP alongside traces and metrics
27
+ logRecordProcessors: [logProcessor],
21
28
  // Auto-instrumentation: HTTP, NestJS, Express, TypeORM, Kafka, Redis, pg, etc.
22
29
  instrumentations: [
23
30
  (0, auto_instrumentations_node_1.getNodeAutoInstrumentations)({
@@ -27,6 +34,16 @@ if (!g.__otelSdkInitialized) {
27
34
  ],
28
35
  });
29
36
  sdk.start();
37
+ // Flush logs to SigNoz on startup crashes before dying
38
+ process.on('uncaughtException', async (err) => {
39
+ api_logs_1.logs.getLogger('startup').emit({
40
+ severityNumber: api_logs_1.SeverityNumber.FATAL,
41
+ severityText: 'FATAL',
42
+ body: `STARTUP CRASH: ${err.stack ?? err.message}`,
43
+ });
44
+ await logProcessor.forceFlush();
45
+ process.exit(1);
46
+ });
30
47
  process.on('SIGTERM', () => {
31
48
  sdk.shutdown().catch(() => { });
32
49
  });
@@ -1 +1 @@
1
- {"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":";;AAAA,sDAAkD;AAClD,0FAAwF;AACxF,0FAA+E;AAC/E,4DAA2E;AAE3E,2EAA2E;AAC3E,MAAM,CAAC,GAAG,MAA4D,CAAC;AACvE,IAAI,CAAC,CAAC,CAAC,oBAAoB,EAAE,CAAC;IAC5B,CAAC,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAE9B,MAAM,oBAAoB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,KAAK,CAAC,CAAC;IAEtF,MAAM,GAAG,GAAG,IAAI,kBAAO,CAAC;QACtB,wEAAwE;QACxE,+DAA+D;QAE/D,+EAA+E;QAC/E,UAAU;QACV,YAAY,EAAE,IAAI,2CAA6B,CAAC;YAC9C,QAAQ,EAAE,IAAI,+CAAkB,EAAE;YAClC,oBAAoB,EAAE,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,KAAK;SAC3F,CAAC;QAEF,+EAA+E;QAC/E,gBAAgB,EAAE;YAChB,IAAA,wDAA2B,EAAC;gBAC1B,gDAAgD;gBAChD,mCAAmC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;aACxD,CAAC;SACH;KACF,CAAC,CAAC;IAEH,GAAG,CAAC,KAAK,EAAE,CAAC;IAEZ,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACzB,GAAG,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":";;AAAA,sDAAkD;AAClD,0FAAwF;AACxF,0FAA+E;AAC/E,4DAA2E;AAC3E,oFAAyE;AACzE,sDAAkE;AAClE,sDAA+D;AAE/D,2EAA2E;AAC3E,MAAM,CAAC,GAAG,MAA4D,CAAC;AACvE,IAAI,CAAC,CAAC,CAAC,oBAAoB,EAAE,CAAC;IAC5B,CAAC,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAE9B,MAAM,oBAAoB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,KAAK,CAAC,CAAC;IAEtF,MAAM,WAAW,GAAG,IAAI,yCAAe,EAAE,CAAC;IAC1C,MAAM,YAAY,GAAG,IAAI,kCAAuB,CAAC,WAAW,CAAC,CAAC;IAE9D,MAAM,GAAG,GAAG,IAAI,kBAAO,CAAC;QACtB,wEAAwE;QACxE,+DAA+D;QAE/D,+EAA+E;QAC/E,UAAU;QACV,YAAY,EAAE,IAAI,2CAA6B,CAAC;YAC9C,QAAQ,EAAE,IAAI,+CAAkB,EAAE;YAClC,oBAAoB,EAAE,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,KAAK;SAC3F,CAAC;QAEF,wDAAwD;QACxD,mBAAmB,EAAE,CAAC,YAAY,CAAC;QAEnC,+EAA+E;QAC/E,gBAAgB,EAAE;YAChB,IAAA,wDAA2B,EAAC;gBAC1B,gDAAgD;gBAChD,mCAAmC,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;aACxD,CAAC;SACH;KACF,CAAC,CAAC;IAEH,GAAG,CAAC,KAAK,EAAE,CAAC;IAEZ,uDAAuD;IACvD,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC5C,eAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC;YAC7B,cAAc,EAAE,yBAAc,CAAC,KAAK;YACpC,YAAY,EAAE,OAAO;YACrB,IAAI,EAAE,kBAAkB,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,EAAE;SACnD,CAAC,CAAC;QACH,MAAM,YAAY,CAAC,UAAU,EAAE,CAAC;QAChC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACzB,GAAG,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shuttle-labs/node-observability",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Shared OTel observability for Node.js services — traces, logs, metrics",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -22,16 +22,20 @@
22
22
  "dependencies": {
23
23
  "@opentelemetry/api": "^1.9.0",
24
24
  "@opentelemetry/auto-instrumentations-node": "^0.71.0",
25
+ "@opentelemetry/exporter-logs-otlp-http": "^0.213.0",
25
26
  "@opentelemetry/exporter-metrics-otlp-http": "^0.205.0",
26
27
  "@opentelemetry/exporter-trace-otlp-http": "^0.213.0",
27
28
  "@opentelemetry/resources": "^2.1.0",
29
+ "@opentelemetry/api-logs": "^0.213.0",
30
+ "@opentelemetry/sdk-logs": "^0.213.0",
28
31
  "@opentelemetry/sdk-metrics": "^2.1.0",
29
32
  "@opentelemetry/sdk-node": "^0.213.0",
30
33
  "@opentelemetry/semantic-conventions": "^1.37.0",
31
34
  "nestjs-pino": "^4.0.0",
32
35
  "pino": "^10.0.0",
33
36
  "pino-http": "^10.0.0",
34
- "pino-opentelemetry-transport": "^3.0.0"
37
+ "pino-opentelemetry-transport": "^3.0.0",
38
+ "pino-pretty": "^13.0.0"
35
39
  },
36
40
  "devDependencies": {
37
41
  "@nestjs/common": "^11.0.0",
package/src/register.ts CHANGED
@@ -2,6 +2,9 @@ import { NodeSDK } from '@opentelemetry/sdk-node';
2
2
  import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
3
3
  import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http';
4
4
  import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
5
+ import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
6
+ import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs';
7
+ import { logs, SeverityNumber } from '@opentelemetry/api-logs';
5
8
 
6
9
  // Guard against double-initialization (e.g. hot reload, test environments)
7
10
  const g = global as typeof global & { __otelSdkInitialized?: boolean };
@@ -10,6 +13,9 @@ if (!g.__otelSdkInitialized) {
10
13
 
11
14
  const exportIntervalMillis = Number(process.env.OTEL_METRIC_EXPORT_INTERVAL ?? 15000);
12
15
 
16
+ const logExporter = new OTLPLogExporter();
17
+ const logProcessor = new BatchLogRecordProcessor(logExporter);
18
+
13
19
  const sdk = new NodeSDK({
14
20
  // Resource (service.name, deployment.environment) is read automatically
15
21
  // from OTEL_SERVICE_NAME and OTEL_RESOURCE_ATTRIBUTES env vars
@@ -21,6 +27,9 @@ if (!g.__otelSdkInitialized) {
21
27
  exportIntervalMillis: Number.isFinite(exportIntervalMillis) ? exportIntervalMillis : 15000,
22
28
  }),
23
29
 
30
+ // Logs — exported via OTLP alongside traces and metrics
31
+ logRecordProcessors: [logProcessor],
32
+
24
33
  // Auto-instrumentation: HTTP, NestJS, Express, TypeORM, Kafka, Redis, pg, etc.
25
34
  instrumentations: [
26
35
  getNodeAutoInstrumentations({
@@ -32,6 +41,17 @@ if (!g.__otelSdkInitialized) {
32
41
 
33
42
  sdk.start();
34
43
 
44
+ // Flush logs to SigNoz on startup crashes before dying
45
+ process.on('uncaughtException', async (err) => {
46
+ logs.getLogger('startup').emit({
47
+ severityNumber: SeverityNumber.FATAL,
48
+ severityText: 'FATAL',
49
+ body: `STARTUP CRASH: ${err.stack ?? err.message}`,
50
+ });
51
+ await logProcessor.forceFlush();
52
+ process.exit(1);
53
+ });
54
+
35
55
  process.on('SIGTERM', () => {
36
56
  sdk.shutdown().catch(() => {});
37
57
  });