* refactor: apply biome formatting to small packages + packages/lib Format packages/sms, packages/prisma, packages/platform/libraries, packages/platform/examples, packages/platform/types, packages/emails, and packages/lib. Excludes packages/platform/examples/base/src/pages/[bookingUid].tsx due to pre-existing lint errors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * revert: remove packages/platform formatting changes Revert biome formatting for packages/platform as requested. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
112 lines
2.7 KiB
TypeScript
112 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,
|
|
},
|
|
};
|
|
}
|
|
}
|