Files
calendar/packages/lib/tracing/index.ts
T
1ff5d57ded feat: distributed tracing - 2 (#24861)
* feat: distributed tracing 2

* feat: distributed tracing 2

* refactor: feedback

* refactor: feedback

* fix: type error

* fix: trpc error

---------

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2025-11-13 11:51:54 +00:00

109 lines
2.7 KiB
TypeScript

import type { Logger } from "tslog";
export interface TraceContext {
traceId: string;
spanId: string;
parentSpanId?: string;
operation: string;
// So that we don't violate open closed principle, we allow meta to be added to the trace context
meta?: Record<string, string | number | boolean | null | undefined>;
}
export interface IdGenerator {
generate: () => string;
}
export class DistributedTracing {
constructor(private idGenerator: IdGenerator, private loggerInstance: Logger<unknown>) {}
createTrace(operation: string, context?: Partial<TraceContext>): TraceContext {
const { traceId, spanId, meta, ...otherContext } = context || {};
return {
...otherContext,
traceId: traceId || `trace_${this.idGenerator.generate()}`,
spanId: `span_${this.idGenerator.generate()}`,
parentSpanId: spanId,
operation,
meta,
};
}
createSpan(
parentContext: TraceContext,
operation: string,
additionalMeta?: Record<string, string | number | boolean | null | undefined>
): TraceContext {
const mergedMeta = {
...parentContext.meta,
...additionalMeta,
};
return {
...parentContext,
spanId: `span_${this.idGenerator.generate()}`,
parentSpanId: parentContext.spanId,
operation,
meta: mergedMeta,
};
}
getTracingLogger(
context: TraceContext,
additionalMeta?: Record<string, string | number | boolean | null | undefined>
) {
const mergedMeta = {
...context.meta,
...additionalMeta,
};
const prefixes = [
"distributed-trace",
`trace:${context.traceId}`,
`span:${context.spanId}`,
`op:${context.operation}`,
];
if (mergedMeta) {
Object.entries(mergedMeta).forEach(([key, value]) => {
if (value !== undefined && value !== null) {
prefixes.push(`${key}:${value}`);
}
});
}
return this.loggerInstance.getSubLogger({ prefix: prefixes });
}
extractTraceFromPayload(payload: string): TraceContext | null {
try {
const parsed = JSON.parse(payload);
if (parsed._traceContext && parsed._traceContext.traceId) {
return parsed._traceContext;
}
} catch {}
return null;
}
injectTraceIntoPayload(payload: any, traceContext?: TraceContext): any {
if (!traceContext) return payload;
return {
...payload,
_traceContext: traceContext,
};
}
updateTrace(
traceContext: TraceContext,
additionalMeta?: Record<string, string | number | boolean | null | undefined>
): TraceContext {
return {
...traceContext,
meta: {
...traceContext.meta,
...additionalMeta,
},
};
}
}