@generazioneai/telemetry
v0.2.0
Published
Osservabilità comune dei servizi Node (ADR-013): OpenTelemetry con esportazione OTLP, JsonLogger con trace_id, span dei comandi NATS con traceparent negli header, attributi a lista bianca e redazione dei dati personali.
Readme
@generazioneai/telemetry
Osservabilità comune dei servizi Node (ADR-013, spec «Fondamenta enterprise» §5): tracce e metriche OpenTelemetry verso il collector, log JSON con trace_id, span dei comandi NATS, nessun dato personale.
npm i @generazioneai/telemetryUso
// main.ts — PRIMA riga
import '@generazioneai/telemetry/register';
import { createLogger } from '@generazioneai/telemetry/logger';
const app = await NestFactory.create(AppModule, { logger: createLogger('hr') });
// app.module.ts
TelemetryModule.forRoot({ service: 'hr' })| Variabile | Valori | Di serie |
|---|---|---|
| OTEL_EXPORTER_OTLP_ENDPOINT | base OTLP/HTTP | http://otel-collector.observability:4318 (in sviluppo locale: vuota); vuota = spento (il processo non carica l'SDK, nessuna connessione) |
| TELEMETRY_MODE | on | 0.2 (decisione del 2026-11-10): accesa se c'è l'endpoint. off conta solo in sviluppo locale e nei test (SKILLERA_ENV dev/local o NODE_ENV development/test, fuori da un cluster); altrove si ignora con un avviso |
| OTEL_SERVICE_NAME | nome | name del package.json (senza scope) |
| SKILLERA_ENV | | → deployment.environment |
| LOG_FORMAT | text | json | text |
| APP_LOGGER_LEVEL | log,error,warn,debug,verbose | none | log,error,warn (fatal segue error) |
| TELEMETRY_SAMPLE_RATIO | 0..1 | 1 (il campionamento in coda è del collector) |
| OTEL_METRIC_EXPORT_INTERVAL | ms | 60000 |
Impostare OTEL_SERVICE_NAME nei manifest: register parte prima di Nest e non conosce l'opzione service del modulo.
Cosa fa
/register: Node SDK con OTLP/HTTP per tracce e metriche; strumentazioni HTTP (senzahealth/metrics),pg,ioredis, Prisma (le ultime tre opzionali). Nessun gestore di SIGTERM: lo spegnimento ordinato lo faTelemetryModule(obeforeExit).- NATS: l'interceptor globale (solo contesto
rpc) aprenats.server <cmd>(kind consumer) come figlio deltraceparentnegli header, mettecmdejuridicalIdnel contesto dei log, contanats_server_requests_total{cmd,outcome}enats_server_request_duration_seconds{cmd}.juridicalIdviene dall'headerGen-Tenanto daauth.juridicalId/auth.tenantId/dto.juridicalId, solo se è un UUID. - Invio:
traceparentHeadersHookscrivetraceparentnegli header.TelemetryModule.forRootlo registra consetNatsHeadersHookdi@generazioneai/authz≥ 0.7 se c'è (altrimenti nulla); si può passare il modulo conauthz: …o spegnere conauthz: false. Per gli eventi di JetStream ci pensa@generazioneai/eventsconinjectTraceContext/extractTraceContext. - Log (
JsonLogger):level,ts,service,msg,trace_id,span_id,cmd,juridicalId(+context,err, campi del messaggio-oggetto, mai in conflitto con quelli del contratto). - Dati personali (decisione 35): gli span escono da
SanitizingSpanExporter, che tiene solo gli attributi della lista bianca (ALLOWED_ATTRIBUTES: metodo, rotta come modello, comando, esito, durata, dimensioni, id di azienda UUID,db.statementsenza letterali, redis solo il comando), stato senza messaggio, IP solo come hash (client.ip_hash).redact()/maskString()(usate dal logger) azzerano i valori di chiavi comeauthorization,cookie,body,dto,email,*name,fiscalCode,iban,password,*tokene mascherano nel testo email, codici fiscali (anche omocodici), IBAN, JWT,Bearer ….
Compatibilità delle versioni OpenTelemetry
Le strumentazioni sono fissate alla famiglia 0.219 con @opentelemetry/api 1.9 (la 0.300 richiede api ≥ 1.10, che gli SDK 2.x non accettano ancora). Il servizio non deve avere un proprio @opentelemetry/api diverso.
Prove
npm test. La prova dell'SDK acceso gira in un processo Node figlio (le strumentazioni usano import() dinamici, che Jest non esegue) e costruisce il pacchetto in .test-dist/.
