Files
moeka-project/server/apps/auth/instrumentation.ts
T
RainbowBirdandautofix-ci[bot] 22b5249c64 refactor(server): split independent auth service (#2202)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-12 23:33:58 +08:00

104 lines
4.2 KiB
TypeScript

import process, { env } from 'node:process'
/**
* Auth-server OpenTelemetry preload.
*
* Loaded before application modules so PostgreSQL, Redis, HTTP, and fetch
* instrumentation can patch their runtimes before the auth composition root
* imports those clients.
*/
import { randomUUID } from 'node:crypto'
import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api'
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-proto'
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-proto'
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto'
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http'
import { IORedisInstrumentation } from '@opentelemetry/instrumentation-ioredis'
import { PgInstrumentation } from '@opentelemetry/instrumentation-pg'
import { RuntimeNodeInstrumentation } from '@opentelemetry/instrumentation-runtime-node'
import { UndiciInstrumentation } from '@opentelemetry/instrumentation-undici'
import { resourceFromAttributes } from '@opentelemetry/resources'
import { BatchLogRecordProcessor } from '@opentelemetry/sdk-logs'
import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'
import { NodeSDK } from '@opentelemetry/sdk-node'
import { BatchSpanProcessor, ParentBasedSampler, TraceIdRatioBasedSampler } from '@opentelemetry/sdk-trace-node'
import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions'
if (!env.OTEL_SEMCONV_STABILITY_OPT_IN)
env.OTEL_SEMCONV_STABILITY_OPT_IN = 'http'
const otlpEndpoint = env.OTEL_EXPORTER_OTLP_ENDPOINT
if (!otlpEndpoint) {
console.info('[otel-preload] Auth OpenTelemetry disabled (set OTEL_EXPORTER_OTLP_ENDPOINT to enable)')
}
else {
if (env.OTEL_DEBUG === 'true')
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG)
const headers: Record<string, string> = {}
for (const pair of (env.OTEL_EXPORTER_OTLP_HEADERS ?? '').split(',')) {
const separator = pair.indexOf('=')
if (separator > 0)
headers[pair.slice(0, separator).trim()] = pair.slice(separator + 1).trim()
}
const samplingRatioRaw = Number(env.OTEL_TRACES_SAMPLING_RATIO ?? '1')
const samplingRatio = Number.isFinite(samplingRatioRaw) && samplingRatioRaw >= 0 && samplingRatioRaw <= 1
? samplingRatioRaw
: 1
const instanceId = env.RAILWAY_REPLICA_ID || env.SERVER_INSTANCE_ID || randomUUID()
const resource = resourceFromAttributes({
[ATTR_SERVICE_NAME]: env.OTEL_SERVICE_NAME || 'auth-server',
[ATTR_SERVICE_VERSION]: env.npm_package_version || '0.0.0',
'service.namespace': env.OTEL_SERVICE_NAMESPACE || 'airi',
'service.instance.id': instanceId,
'deployment.environment': env.NODE_ENV || 'development',
})
const sdk = new NodeSDK({
resource,
sampler: new ParentBasedSampler({ root: new TraceIdRatioBasedSampler(samplingRatio) }),
spanProcessors: [new BatchSpanProcessor(new OTLPTraceExporter({
url: `${otlpEndpoint}/v1/traces`,
headers,
}))],
metricReaders: [new PeriodicExportingMetricReader({
exporter: new OTLPMetricExporter({ url: `${otlpEndpoint}/v1/metrics`, headers }),
exportIntervalMillis: 15_000,
exportTimeoutMillis: 10_000,
})],
logRecordProcessors: [new BatchLogRecordProcessor(new OTLPLogExporter({
url: `${otlpEndpoint}/v1/logs`,
headers,
}))],
instrumentations: [
new HttpInstrumentation({ disableIncomingRequestInstrumentation: true }),
new PgInstrumentation({ enhancedDatabaseReporting: true }),
new IORedisInstrumentation(),
new RuntimeNodeInstrumentation(),
new UndiciInstrumentation(),
],
})
sdk.start()
console.info(`[otel-preload] Auth OpenTelemetry initialized — OTLP: ${otlpEndpoint}, sampling ratio: ${samplingRatio}`)
let shuttingDown = false
const shutdown = async () => {
if (shuttingDown)
return
shuttingDown = true
try {
await sdk.shutdown()
console.info('[otel-preload] Auth OpenTelemetry shut down successfully')
}
catch (error) {
console.error('[otel-preload] Failed to shut down Auth OpenTelemetry:', error)
}
}
process.once('SIGTERM', () => void shutdown().finally(() => process.exit(0)))
process.once('SIGINT', () => void shutdown().finally(() => process.exit(0)))
}