Skip to main content
Glama

Git MCP Server

instrumentation.ts4.31 kB
/** * @fileoverview OpenTelemetry SDK initialization and lifecycle management. * This file MUST be imported before any other module in the application's * entry point (`src/index.ts`) to ensure all modules are correctly instrumented. * It handles both the initialization (startup) and graceful shutdown of the SDK. * @module src/utils/telemetry/instrumentation */ import { config } from '@/config/index.js'; import { DiagConsoleLogger, DiagLogLevel, diag } from '@opentelemetry/api'; import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'; import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; import { PinoInstrumentation } from '@opentelemetry/instrumentation-pino'; import { resourceFromAttributes } from '@opentelemetry/resources'; import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'; import { NodeSDK } from '@opentelemetry/sdk-node'; import { BatchSpanProcessor, type SpanProcessor, TraceIdRatioBasedSampler, } from '@opentelemetry/sdk-trace-node'; import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, } from '@opentelemetry/semantic-conventions/incubating'; export let sdk: NodeSDK | null = null; // A flag to ensure we only try to initialize once. let isOtelInitialized = false; if (config.openTelemetry.enabled && !isOtelInitialized) { isOtelInitialized = true; try { const otelLogLevelString = config.openTelemetry.logLevel.toUpperCase() as keyof typeof DiagLogLevel; const otelLogLevel = DiagLogLevel[otelLogLevelString] ?? DiagLogLevel.INFO; diag.setLogger(new DiagConsoleLogger(), otelLogLevel); const tracesEndpoint = config.openTelemetry.tracesEndpoint; const metricsEndpoint = config.openTelemetry.metricsEndpoint; if (!tracesEndpoint && !metricsEndpoint) { diag.warn( 'OTEL_ENABLED is true, but no OTLP endpoint for traces or metrics is configured. OpenTelemetry will not export any telemetry.', ); } const resource = resourceFromAttributes({ [ATTR_SERVICE_NAME]: config.openTelemetry.serviceName, [ATTR_SERVICE_VERSION]: config.openTelemetry.serviceVersion, 'deployment.environment.name': config.environment, }); const spanProcessors: SpanProcessor[] = []; if (tracesEndpoint) { diag.info(`Using OTLP exporter for traces, endpoint: ${tracesEndpoint}`); const traceExporter = new OTLPTraceExporter({ url: tracesEndpoint }); spanProcessors.push(new BatchSpanProcessor(traceExporter)); } else { diag.info( 'No OTLP traces endpoint configured. Traces will not be exported.', ); } const metricReader = metricsEndpoint ? new PeriodicExportingMetricReader({ exporter: new OTLPMetricExporter({ url: metricsEndpoint }), exportIntervalMillis: 15000, }) : undefined; sdk = new NodeSDK({ resource, spanProcessors, ...(metricReader && { metricReader }), sampler: new TraceIdRatioBasedSampler(config.openTelemetry.samplingRatio), instrumentations: [ getNodeAutoInstrumentations({ '@opentelemetry/instrumentation-http': { enabled: true, ignoreIncomingRequestHook: (req) => req.url === '/healthz', }, '@opentelemetry/instrumentation-fs': { enabled: false }, }), new PinoInstrumentation({ logHook: (_span, record) => { record['trace_id'] = _span.spanContext().traceId; record['span_id'] = _span.spanContext().spanId; }, }), ], }); sdk.start(); diag.info( `OpenTelemetry initialized for ${config.openTelemetry.serviceName} v${config.openTelemetry.serviceVersion}`, ); } catch (error) { diag.error('Error initializing OpenTelemetry', error); sdk = null; } } /** * Gracefully shuts down the OpenTelemetry SDK. * This function is called during the application's shutdown sequence. */ export async function shutdownOpenTelemetry() { if (sdk) { try { await sdk.shutdown(); diag.info('OpenTelemetry terminated successfully.'); } catch (error) { diag.error('Error terminating OpenTelemetry', error); } } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cyanheads/git-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server