@skediprof/telemetry 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/dist/_state.d.ts +6 -0
- package/dist/_state.d.ts.map +1 -0
- package/dist/_state.js +21 -0
- package/dist/_state.js.map +1 -0
- package/dist/context.d.ts +7 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +23 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +11 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +95 -0
- package/dist/init.js.map +1 -0
- package/dist/instrumentations.d.ts +6 -0
- package/dist/instrumentations.d.ts.map +1 -0
- package/dist/instrumentations.js +27 -0
- package/dist/instrumentations.js.map +1 -0
- package/dist/metrics.d.ts +19 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +35 -0
- package/dist/metrics.js.map +1 -0
- package/dist/shutdown.d.ts +8 -0
- package/dist/shutdown.d.ts.map +1 -0
- package/dist/shutdown.js +35 -0
- package/dist/shutdown.js.map +1 -0
- package/dist/types.d.ts +53 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +41 -0
package/dist/_state.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { NodeSDK } from '@opentelemetry/sdk-node';
|
|
2
|
+
export declare function setSDK(instance: NodeSDK | null): void;
|
|
3
|
+
export declare function getSDK(): NodeSDK | null;
|
|
4
|
+
export declare function setInitialized(value: boolean): void;
|
|
5
|
+
export declare function isInitialized(): boolean;
|
|
6
|
+
//# sourceMappingURL=_state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_state.d.ts","sourceRoot":"","sources":["../src/_state.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAKvD,wBAAgB,MAAM,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,GAAG,IAAI,CAErD;AAED,wBAAgB,MAAM,IAAI,OAAO,GAAG,IAAI,CAEvC;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAEnD;AAED,wBAAgB,aAAa,IAAI,OAAO,CAEvC"}
|
package/dist/_state.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setSDK = setSDK;
|
|
4
|
+
exports.getSDK = getSDK;
|
|
5
|
+
exports.setInitialized = setInitialized;
|
|
6
|
+
exports.isInitialized = isInitialized;
|
|
7
|
+
let sdk = null;
|
|
8
|
+
let initialized = false;
|
|
9
|
+
function setSDK(instance) {
|
|
10
|
+
sdk = instance;
|
|
11
|
+
}
|
|
12
|
+
function getSDK() {
|
|
13
|
+
return sdk;
|
|
14
|
+
}
|
|
15
|
+
function setInitialized(value) {
|
|
16
|
+
initialized = value;
|
|
17
|
+
}
|
|
18
|
+
function isInitialized() {
|
|
19
|
+
return initialized;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=_state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_state.js","sourceRoot":"","sources":["../src/_state.ts"],"names":[],"mappings":";;AAOA,wBAEC;AAED,wBAEC;AAED,wCAEC;AAED,sCAEC;AAjBD,IAAI,GAAG,GAAmB,IAAI,CAAC;AAC/B,IAAI,WAAW,GAAG,KAAK,CAAC;AAExB,SAAgB,MAAM,CAAC,QAAwB;IAC7C,GAAG,GAAG,QAAQ,CAAC;AACjB,CAAC;AAED,SAAgB,MAAM;IACpB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAgB,cAAc,CAAC,KAAc;IAC3C,WAAW,GAAG,KAAK,CAAC;AACtB,CAAC;AAED,SAAgB,aAAa;IAC3B,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { TraceContext } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Retorna o contexto de trace ativo (se houver).
|
|
4
|
+
* Usado para injetar traceId/spanId nos logs (Winston/Pino).
|
|
5
|
+
*/
|
|
6
|
+
export declare function getTraceContext(): TraceContext | null;
|
|
7
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C;;;GAGG;AACH,wBAAgB,eAAe,IAAI,YAAY,GAAG,IAAI,CAcrD"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getTraceContext = getTraceContext;
|
|
4
|
+
const api_1 = require("@opentelemetry/api");
|
|
5
|
+
/**
|
|
6
|
+
* Retorna o contexto de trace ativo (se houver).
|
|
7
|
+
* Usado para injetar traceId/spanId nos logs (Winston/Pino).
|
|
8
|
+
*/
|
|
9
|
+
function getTraceContext() {
|
|
10
|
+
const span = api_1.trace.getActiveSpan();
|
|
11
|
+
if (!span)
|
|
12
|
+
return null;
|
|
13
|
+
const ctx = span.spanContext();
|
|
14
|
+
if (!ctx.traceId || ctx.traceId === '00000000000000000000000000000000') {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
traceId: ctx.traceId,
|
|
19
|
+
spanId: ctx.spanId,
|
|
20
|
+
traceFlags: ctx.traceFlags,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":";;AAOA,0CAcC;AArBD,4CAA2C;AAG3C;;;GAGG;AACH,SAAgB,eAAe;IAC7B,MAAM,IAAI,GAAG,WAAK,CAAC,aAAa,EAAE,CAAC;IACnC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAC/B,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,KAAK,kCAAkC,EAAE,CAAC;QACvE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,UAAU,EAAE,GAAG,CAAC,UAAU;KAC3B,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { initTelemetry, withTelemetry } from './init';
|
|
2
|
+
export { createCounter, createHistogram, createGauge } from './metrics';
|
|
3
|
+
export { getTraceContext } from './context';
|
|
4
|
+
export { shutdownTelemetry } from './shutdown';
|
|
5
|
+
export type { TelemetryConfig, TraceContext } from './types';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.shutdownTelemetry = exports.getTraceContext = exports.createGauge = exports.createHistogram = exports.createCounter = exports.withTelemetry = exports.initTelemetry = void 0;
|
|
4
|
+
var init_1 = require("./init");
|
|
5
|
+
Object.defineProperty(exports, "initTelemetry", { enumerable: true, get: function () { return init_1.initTelemetry; } });
|
|
6
|
+
Object.defineProperty(exports, "withTelemetry", { enumerable: true, get: function () { return init_1.withTelemetry; } });
|
|
7
|
+
var metrics_1 = require("./metrics");
|
|
8
|
+
Object.defineProperty(exports, "createCounter", { enumerable: true, get: function () { return metrics_1.createCounter; } });
|
|
9
|
+
Object.defineProperty(exports, "createHistogram", { enumerable: true, get: function () { return metrics_1.createHistogram; } });
|
|
10
|
+
Object.defineProperty(exports, "createGauge", { enumerable: true, get: function () { return metrics_1.createGauge; } });
|
|
11
|
+
var context_1 = require("./context");
|
|
12
|
+
Object.defineProperty(exports, "getTraceContext", { enumerable: true, get: function () { return context_1.getTraceContext; } });
|
|
13
|
+
var shutdown_1 = require("./shutdown");
|
|
14
|
+
Object.defineProperty(exports, "shutdownTelemetry", { enumerable: true, get: function () { return shutdown_1.shutdownTelemetry; } });
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,+BAAsD;AAA7C,qGAAA,aAAa,OAAA;AAAE,qGAAA,aAAa,OAAA;AACrC,qCAAwE;AAA/D,wGAAA,aAAa,OAAA;AAAE,0GAAA,eAAe,OAAA;AAAE,sGAAA,WAAW,OAAA;AACpD,qCAA4C;AAAnC,0GAAA,eAAe,OAAA;AACxB,uCAA+C;AAAtC,6GAAA,iBAAiB,OAAA"}
|
package/dist/init.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { TelemetryConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Inicializa toda a stack de telemetria (traces + metrics).
|
|
4
|
+
* DEVE ser chamado ANTES de qualquer import de framework (Express, Firebase).
|
|
5
|
+
*/
|
|
6
|
+
export declare function initTelemetry(config: TelemetryConfig): void;
|
|
7
|
+
/**
|
|
8
|
+
* Wrapper para Cloud Functions que faz init no cold start e flush apos cada invocacao.
|
|
9
|
+
*/
|
|
10
|
+
export declare function withTelemetry<TArgs extends unknown[], TReturn>(config: TelemetryConfig, handler: (...args: TArgs) => Promise<TReturn>): (...args: TArgs) => Promise<TReturn>;
|
|
11
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAM/C;;;GAGG;AAIH,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAqE3D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,KAAK,SAAS,OAAO,EAAE,EACvB,OAAO,EAEP,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,GAC5C,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,OAAO,CAAC,CAetC"}
|
package/dist/init.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.initTelemetry = initTelemetry;
|
|
4
|
+
exports.withTelemetry = withTelemetry;
|
|
5
|
+
const sdk_node_1 = require("@opentelemetry/sdk-node");
|
|
6
|
+
const exporter_trace_otlp_http_1 = require("@opentelemetry/exporter-trace-otlp-http");
|
|
7
|
+
const exporter_metrics_otlp_http_1 = require("@opentelemetry/exporter-metrics-otlp-http");
|
|
8
|
+
const sdk_metrics_1 = require("@opentelemetry/sdk-metrics");
|
|
9
|
+
const resources_1 = require("@opentelemetry/resources");
|
|
10
|
+
const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
|
|
11
|
+
const instrumentations_1 = require("./instrumentations");
|
|
12
|
+
const _state_1 = require("./_state");
|
|
13
|
+
const shutdown_1 = require("./shutdown");
|
|
14
|
+
// AIDEV: OTLP/HTTP (not gRPC) — Cloud Functions kill persistent gRPC connections
|
|
15
|
+
// on cold start. Do not switch to gRPC exporter. See ADR-002.
|
|
16
|
+
const DEFAULT_ENDPOINT = 'https://otlp.nr-data.net:4318';
|
|
17
|
+
/**
|
|
18
|
+
* Inicializa toda a stack de telemetria (traces + metrics).
|
|
19
|
+
* DEVE ser chamado ANTES de qualquer import de framework (Express, Firebase).
|
|
20
|
+
*/
|
|
21
|
+
// AIDEV: initTelemetry MUST be called before any Express/Firebase import.
|
|
22
|
+
// OTel auto-instrumentation works via monkey-patching — if modules are
|
|
23
|
+
// imported first, the patches don't apply.
|
|
24
|
+
function initTelemetry(config) {
|
|
25
|
+
if ((0, _state_1.isInitialized)()) {
|
|
26
|
+
console.warn('[@skediprof/telemetry] Already initialized, skipping.');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (process.env.TELEMETRY_ENABLED === 'false') {
|
|
30
|
+
console.log('[@skediprof/telemetry] Disabled via TELEMETRY_ENABLED=false');
|
|
31
|
+
(0, _state_1.setInitialized)(true);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const environment = config.environment || process.env.NODE_ENV || 'production';
|
|
35
|
+
const endpoint = process.env.OTEL_EXPORTER_OTLP_ENDPOINT ||
|
|
36
|
+
config.otlpEndpoint ||
|
|
37
|
+
DEFAULT_ENDPOINT;
|
|
38
|
+
const apiKey = config.apiKey || process.env.NEW_RELIC_LICENSE_KEY;
|
|
39
|
+
const runtime = config.runtime || 'server';
|
|
40
|
+
const metricInterval = config.metricExportInterval || (runtime === 'function' ? 10000 : 60000);
|
|
41
|
+
if (!apiKey) {
|
|
42
|
+
console.warn('[@skediprof/telemetry] No API key found. Set NEW_RELIC_LICENSE_KEY or pass apiKey in config. Telemetry disabled.');
|
|
43
|
+
(0, _state_1.setInitialized)(true);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
// AIDEV: New Relic OTLP requires header 'api-key' (not 'Authorization: Bearer').
|
|
47
|
+
const headers = { 'api-key': apiKey };
|
|
48
|
+
const resource = (0, resources_1.resourceFromAttributes)({
|
|
49
|
+
[semantic_conventions_1.ATTR_SERVICE_NAME]: config.serviceName,
|
|
50
|
+
[semantic_conventions_1.ATTR_SERVICE_VERSION]: config.serviceVersion || '0.0.0',
|
|
51
|
+
[semantic_conventions_1.ATTR_DEPLOYMENT_ENVIRONMENT_NAME]: environment,
|
|
52
|
+
});
|
|
53
|
+
const traceExporter = new exporter_trace_otlp_http_1.OTLPTraceExporter({
|
|
54
|
+
url: `${endpoint}/v1/traces`,
|
|
55
|
+
headers,
|
|
56
|
+
});
|
|
57
|
+
const metricExporter = new exporter_metrics_otlp_http_1.OTLPMetricExporter({
|
|
58
|
+
url: `${endpoint}/v1/metrics`,
|
|
59
|
+
headers,
|
|
60
|
+
});
|
|
61
|
+
const metricReader = new sdk_metrics_1.PeriodicExportingMetricReader({
|
|
62
|
+
exporter: metricExporter,
|
|
63
|
+
exportIntervalMillis: metricInterval,
|
|
64
|
+
});
|
|
65
|
+
const sdk = new sdk_node_1.NodeSDK({
|
|
66
|
+
resource,
|
|
67
|
+
traceExporter,
|
|
68
|
+
metricReader,
|
|
69
|
+
instrumentations: (0, instrumentations_1.buildInstrumentations)(config),
|
|
70
|
+
});
|
|
71
|
+
sdk.start();
|
|
72
|
+
(0, _state_1.setSDK)(sdk);
|
|
73
|
+
(0, _state_1.setInitialized)(true);
|
|
74
|
+
console.log(`[@skediprof/telemetry] Initialized for "${config.serviceName}" (${runtime}/${environment})`);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Wrapper para Cloud Functions que faz init no cold start e flush apos cada invocacao.
|
|
78
|
+
*/
|
|
79
|
+
function withTelemetry(config, handler) {
|
|
80
|
+
const functionConfig = {
|
|
81
|
+
...config,
|
|
82
|
+
runtime: 'function',
|
|
83
|
+
metricExportInterval: config.metricExportInterval || 10000,
|
|
84
|
+
};
|
|
85
|
+
return async (...args) => {
|
|
86
|
+
initTelemetry(functionConfig);
|
|
87
|
+
try {
|
|
88
|
+
return await handler(...args);
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
await (0, shutdown_1.shutdownTelemetry)();
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=init.js.map
|
package/dist/init.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
|
|
2
|
+
import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express';
|
|
3
|
+
import { GrpcInstrumentation } from '@opentelemetry/instrumentation-grpc';
|
|
4
|
+
import type { TelemetryConfig } from './types';
|
|
5
|
+
export declare function buildInstrumentations(config: TelemetryConfig): (HttpInstrumentation | ExpressInstrumentation | GrpcInstrumentation)[];
|
|
6
|
+
//# sourceMappingURL=instrumentations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrumentations.d.ts","sourceRoot":"","sources":["../src/instrumentations.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,eAAe,0EAsB5D"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildInstrumentations = buildInstrumentations;
|
|
4
|
+
// AIDEV: Health check endpoints (/health, /ping) are filtered from HTTP
|
|
5
|
+
// instrumentation to reduce trace noise — same pattern as whatsapp-bot's newrelic.js.
|
|
6
|
+
const instrumentation_http_1 = require("@opentelemetry/instrumentation-http");
|
|
7
|
+
const instrumentation_express_1 = require("@opentelemetry/instrumentation-express");
|
|
8
|
+
const instrumentation_grpc_1 = require("@opentelemetry/instrumentation-grpc");
|
|
9
|
+
function buildInstrumentations(config) {
|
|
10
|
+
const instrumentations = [];
|
|
11
|
+
if (config.autoInstrumentHttp !== false) {
|
|
12
|
+
instrumentations.push(new instrumentation_http_1.HttpInstrumentation({
|
|
13
|
+
ignoreIncomingRequestHook: (req) => {
|
|
14
|
+
const url = req.url || '';
|
|
15
|
+
return url === '/health' || url === '/ping';
|
|
16
|
+
},
|
|
17
|
+
}));
|
|
18
|
+
instrumentations.push(new instrumentation_express_1.ExpressInstrumentation());
|
|
19
|
+
}
|
|
20
|
+
if (config.autoInstrumentFirestore !== false) {
|
|
21
|
+
// AIDEV: Firestore uses gRPC internally — instrumenting gRPC captures
|
|
22
|
+
// Firestore operations as spans (rpc.service = google.firestore.v1.Firestore).
|
|
23
|
+
instrumentations.push(new instrumentation_grpc_1.GrpcInstrumentation());
|
|
24
|
+
}
|
|
25
|
+
return instrumentations;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=instrumentations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrumentations.js","sourceRoot":"","sources":["../src/instrumentations.ts"],"names":[],"mappings":";;AAOA,sDAsBC;AA7BD,wEAAwE;AACxE,sFAAsF;AACtF,8EAA0E;AAC1E,oFAAgF;AAChF,8EAA0E;AAG1E,SAAgB,qBAAqB,CAAC,MAAuB;IAC3D,MAAM,gBAAgB,GAAG,EAAE,CAAC;IAE5B,IAAI,MAAM,CAAC,kBAAkB,KAAK,KAAK,EAAE,CAAC;QACxC,gBAAgB,CAAC,IAAI,CACnB,IAAI,0CAAmB,CAAC;YACtB,yBAAyB,EAAE,CAAC,GAAG,EAAE,EAAE;gBACjC,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC;gBAC1B,OAAO,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,OAAO,CAAC;YAC9C,CAAC;SACF,CAAC,CACH,CAAC;QACF,gBAAgB,CAAC,IAAI,CAAC,IAAI,gDAAsB,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,MAAM,CAAC,uBAAuB,KAAK,KAAK,EAAE,CAAC;QAC7C,sEAAsE;QACtE,+EAA+E;QAC/E,gBAAgB,CAAC,IAAI,CAAC,IAAI,0CAAmB,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,gBAAgB,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Counter, Histogram, ObservableGauge } from '@opentelemetry/api';
|
|
2
|
+
/**
|
|
3
|
+
* Cria um contador (incrementa monotonicamente).
|
|
4
|
+
* Ex: total de aulas criadas, mensagens enviadas.
|
|
5
|
+
*
|
|
6
|
+
* Convencao de nome: skedi.<dominio>.<metrica>
|
|
7
|
+
*/
|
|
8
|
+
export declare function createCounter(name: string, description: string): Counter;
|
|
9
|
+
/**
|
|
10
|
+
* Cria um histograma (distribuicao de valores).
|
|
11
|
+
* Ex: latencia de API, tamanho de payload.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createHistogram(name: string, description: string, unit?: string): Histogram;
|
|
14
|
+
/**
|
|
15
|
+
* Cria um gauge observavel (valor instantaneo via callback).
|
|
16
|
+
* Uso: gauge.addCallback((result) => result.observe(valor, atributos));
|
|
17
|
+
*/
|
|
18
|
+
export declare function createGauge(name: string, description: string): ObservableGauge;
|
|
19
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAS9E;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAExE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE,MAAM,GACZ,SAAS,CAEX;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAClB,eAAe,CAEjB"}
|
package/dist/metrics.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCounter = createCounter;
|
|
4
|
+
exports.createHistogram = createHistogram;
|
|
5
|
+
exports.createGauge = createGauge;
|
|
6
|
+
const api_1 = require("@opentelemetry/api");
|
|
7
|
+
const METER_NAME = '@skediprof/telemetry';
|
|
8
|
+
const METER_VERSION = '1.0.0';
|
|
9
|
+
function getMeter() {
|
|
10
|
+
return api_1.metrics.getMeter(METER_NAME, METER_VERSION);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Cria um contador (incrementa monotonicamente).
|
|
14
|
+
* Ex: total de aulas criadas, mensagens enviadas.
|
|
15
|
+
*
|
|
16
|
+
* Convencao de nome: skedi.<dominio>.<metrica>
|
|
17
|
+
*/
|
|
18
|
+
function createCounter(name, description) {
|
|
19
|
+
return getMeter().createCounter(name, { description });
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Cria um histograma (distribuicao de valores).
|
|
23
|
+
* Ex: latencia de API, tamanho de payload.
|
|
24
|
+
*/
|
|
25
|
+
function createHistogram(name, description, unit) {
|
|
26
|
+
return getMeter().createHistogram(name, { description, unit });
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Cria um gauge observavel (valor instantaneo via callback).
|
|
30
|
+
* Uso: gauge.addCallback((result) => result.observe(valor, atributos));
|
|
31
|
+
*/
|
|
32
|
+
function createGauge(name, description) {
|
|
33
|
+
return getMeter().createObservableGauge(name, { description });
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":";;AAgBA,sCAEC;AAMD,0CAMC;AAMD,kCAKC;AAzCD,4CAA6C;AAG7C,MAAM,UAAU,GAAG,sBAAsB,CAAC;AAC1C,MAAM,aAAa,GAAG,OAAO,CAAC;AAE9B,SAAS,QAAQ;IACf,OAAO,aAAO,CAAC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AACrD,CAAC;AAED;;;;;GAKG;AACH,SAAgB,aAAa,CAAC,IAAY,EAAE,WAAmB;IAC7D,OAAO,QAAQ,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;AACzD,CAAC;AAED;;;GAGG;AACH,SAAgB,eAAe,CAC7B,IAAY,EACZ,WAAmB,EACnB,IAAa;IAEb,OAAO,QAAQ,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;AACjE,CAAC;AAED;;;GAGG;AACH,SAAgB,WAAW,CACzB,IAAY,EACZ,WAAmB;IAEnB,OAAO,QAAQ,EAAE,CAAC,qBAAqB,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Faz flush de todos os spans/metricas pendentes e encerra exporters.
|
|
3
|
+
* CRITICO para Cloud Functions — sem isso, dados podem ser perdidos.
|
|
4
|
+
*
|
|
5
|
+
* Timeout padrao: 5000ms (evita travar o shutdown do processo).
|
|
6
|
+
*/
|
|
7
|
+
export declare function shutdownTelemetry(): Promise<void>;
|
|
8
|
+
//# sourceMappingURL=shutdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shutdown.d.ts","sourceRoot":"","sources":["../src/shutdown.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAKH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAsBvD"}
|
package/dist/shutdown.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.shutdownTelemetry = shutdownTelemetry;
|
|
4
|
+
const _state_1 = require("./_state");
|
|
5
|
+
const SHUTDOWN_TIMEOUT_MS = 5000;
|
|
6
|
+
/**
|
|
7
|
+
* Faz flush de todos os spans/metricas pendentes e encerra exporters.
|
|
8
|
+
* CRITICO para Cloud Functions — sem isso, dados podem ser perdidos.
|
|
9
|
+
*
|
|
10
|
+
* Timeout padrao: 5000ms (evita travar o shutdown do processo).
|
|
11
|
+
*/
|
|
12
|
+
// AIDEV: shutdownTelemetry MUST reset initialized state so that withTelemetry
|
|
13
|
+
// can re-init on Cloud Function warm starts. Without this, the second invocation
|
|
14
|
+
// on a warm instance would skip init (isInitialized=true) but the SDK is already
|
|
15
|
+
// shut down, resulting in zero telemetry.
|
|
16
|
+
async function shutdownTelemetry() {
|
|
17
|
+
const sdk = (0, _state_1.getSDK)();
|
|
18
|
+
if (!sdk || !(0, _state_1.isInitialized)()) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
await Promise.race([
|
|
23
|
+
sdk.shutdown(),
|
|
24
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('Shutdown timed out')), SHUTDOWN_TIMEOUT_MS)),
|
|
25
|
+
]);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
console.error('[@skediprof/telemetry] Shutdown error:', err);
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
(0, _state_1.setSDK)(null);
|
|
32
|
+
(0, _state_1.setInitialized)(false);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=shutdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shutdown.js","sourceRoot":"","sources":["../src/shutdown.ts"],"names":[],"mappings":";;AAcA,8CAsBC;AApCD,qCAAyE;AAEzE,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAEjC;;;;;GAKG;AACH,8EAA8E;AAC9E,iFAAiF;AACjF,iFAAiF;AACjF,0CAA0C;AACnC,KAAK,UAAU,iBAAiB;IACrC,MAAM,GAAG,GAAG,IAAA,eAAM,GAAE,CAAC;IACrB,IAAI,CAAC,GAAG,IAAI,CAAC,IAAA,sBAAa,GAAE,EAAE,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,IAAI,CAAC;YACjB,GAAG,CAAC,QAAQ,EAAE;YACd,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAC9B,UAAU,CACR,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC,EAC7C,mBAAmB,CACpB,CACF;SACF,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,wCAAwC,EAAE,GAAG,CAAC,CAAC;IAC/D,CAAC;YAAS,CAAC;QACT,IAAA,eAAM,EAAC,IAAI,CAAC,CAAC;QACb,IAAA,uBAAc,EAAC,KAAK,CAAC,CAAC;IACxB,CAAC;AACH,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export interface TelemetryConfig {
|
|
2
|
+
/**
|
|
3
|
+
* Nome do servico (aparece no New Relic como entity name).
|
|
4
|
+
* Ex: 'zico', 'skedi-students-imdb', 'ms-skedi-notifications'
|
|
5
|
+
*/
|
|
6
|
+
serviceName: string;
|
|
7
|
+
/**
|
|
8
|
+
* Versao do servico (opcional). Default: '0.0.0'
|
|
9
|
+
*/
|
|
10
|
+
serviceVersion?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Ambiente: 'production' | 'development' | 'staging'
|
|
13
|
+
* Default: process.env.NODE_ENV || 'production'
|
|
14
|
+
*/
|
|
15
|
+
environment?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Endpoint OTLP. Default: 'https://otlp.nr-data.net:4318'
|
|
18
|
+
* Sobrescrito por OTEL_EXPORTER_OTLP_ENDPOINT se definido.
|
|
19
|
+
*/
|
|
20
|
+
otlpEndpoint?: string;
|
|
21
|
+
/**
|
|
22
|
+
* API key do New Relic. Default: process.env.NEW_RELIC_LICENSE_KEY
|
|
23
|
+
*/
|
|
24
|
+
apiKey?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Habilitar auto-instrumentation de HTTP/Express.
|
|
27
|
+
* Default: true
|
|
28
|
+
*/
|
|
29
|
+
autoInstrumentHttp?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Habilitar auto-instrumentation de Firestore/gRPC.
|
|
32
|
+
* Default: true
|
|
33
|
+
*/
|
|
34
|
+
autoInstrumentFirestore?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Tipo de runtime (afeta estrategia de flush/shutdown).
|
|
37
|
+
* - 'server': Cloud Run, servidor persistente (flush periodico)
|
|
38
|
+
* - 'function': Cloud Functions (flush agressivo a cada invocacao)
|
|
39
|
+
* Default: 'server'
|
|
40
|
+
*/
|
|
41
|
+
runtime?: 'server' | 'function';
|
|
42
|
+
/**
|
|
43
|
+
* Intervalo de export de metricas em ms.
|
|
44
|
+
* Default: 60000 (1 min) para server, 10000 (10s) para function
|
|
45
|
+
*/
|
|
46
|
+
metricExportInterval?: number;
|
|
47
|
+
}
|
|
48
|
+
export interface TraceContext {
|
|
49
|
+
traceId: string;
|
|
50
|
+
spanId: string;
|
|
51
|
+
traceFlags: number;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;OAGG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAEhC;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@skediprof/telemetry",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Shared OpenTelemetry library for Skedi microservices",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc -p tsconfig.build.json",
|
|
12
|
+
"clean": "rm -rf dist",
|
|
13
|
+
"typecheck": "tsc --noEmit",
|
|
14
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
15
|
+
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=18.0.0"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@opentelemetry/api": "^1.9.0",
|
|
21
|
+
"@opentelemetry/exporter-metrics-otlp-http": "^0.218.0",
|
|
22
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.218.0",
|
|
23
|
+
"@opentelemetry/instrumentation-express": "^0.66.0",
|
|
24
|
+
"@opentelemetry/instrumentation-grpc": "^0.218.0",
|
|
25
|
+
"@opentelemetry/instrumentation-http": "^0.218.0",
|
|
26
|
+
"@opentelemetry/resources": "^2.7.1",
|
|
27
|
+
"@opentelemetry/sdk-metrics": "^2.7.1",
|
|
28
|
+
"@opentelemetry/sdk-node": "^0.218.0",
|
|
29
|
+
"@opentelemetry/sdk-trace-node": "^2.7.1",
|
|
30
|
+
"@opentelemetry/semantic-conventions": "^1.29.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^20.11.16",
|
|
34
|
+
"typescript": "^5.4.0"
|
|
35
|
+
},
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "https://github.com/Skedi-Prof/otel-skedi-lib.git"
|
|
40
|
+
}
|
|
41
|
+
}
|