{"version":3,"sources":["../../src/XyConsoleSpanExporter.ts"],"sourcesContent":["import type { ReadableSpan } from '@opentelemetry/sdk-trace-base'\nimport { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-base'\nimport type { Logger } from '@xylabs/logger'\nimport chalk from 'chalk'\n\n/**\n * Calculates the duration of a span in milliseconds from its high-resolution time tuple.\n * @param span - The span to measure.\n * @returns The span duration in milliseconds.\n */\nexport function spanDurationInMillis(span: ReadableSpan) {\n  return span.duration[0] * 1000 + span.duration[1] / 1e6\n}\n\n/**\n * A console span exporter that formats spans with color-coded durations using chalk.\n * Spans are filtered by a configurable log level based on their duration.\n */\nexport class XyConsoleSpanExporter extends ConsoleSpanExporter {\n  /** Duration thresholds (in ms) that map to increasing log levels. */\n  static readonly durationToLogLevel = [\n    0,\n    1,\n    10,\n    100,\n    1000,\n  ]\n\n  /** Chalk color functions corresponding to each log level. */\n  static readonly logLevelToChalkColor = [\n    chalk.grey,\n    chalk.white,\n    chalk.green,\n    chalk.yellow,\n    chalk.red,\n  ]\n\n  logger: Logger\n  private _logLevel: number\n\n  constructor(logLevel = 0, logger: Logger = console) {\n    super()\n    this._logLevel = logLevel\n    this.logger = logger\n  }\n\n  /** The minimum log level required for a span to be exported. */\n  get logLevel() {\n    return this._logLevel\n  }\n\n  override export(spans: ReadableSpan[]): void {\n    for (const span of spans) {\n      const spanLevel = this.spanLevel(span)\n      if (spanLevel < this.logLevel) {\n        continue\n      }\n      const duration = spanDurationInMillis(span)\n      this.logger.log(chalk.grey([\n        `Span [${span.name}]`,\n        this.logColor(spanLevel)(`${duration}ms`),\n        `TraceId: ${span.spanContext().traceId}`,\n      ].join(', ')))\n    }\n  }\n\n  /**\n   * Returns the chalk color function for the given log level.\n   * @param level - The log level index.\n   * @returns A chalk color function.\n   */\n  logColor(level: number) {\n    return XyConsoleSpanExporter.logLevelToChalkColor[level] ?? chalk.magenta\n  }\n\n  /**\n   * Determines the log level of a span based on its duration.\n   * @param span - The span to evaluate.\n   * @returns The numeric log level (index into durationToLogLevel).\n   */\n  spanLevel(span: ReadableSpan) {\n    let logLevel = 0\n    const duration = spanDurationInMillis(span)\n    for (let x = XyConsoleSpanExporter.durationToLogLevel.length - 1; x >= 0; x--) {\n      if (duration > XyConsoleSpanExporter.durationToLogLevel[x]) {\n        logLevel = x\n        break\n      }\n    }\n    return logLevel\n  }\n}\n"],"mappings":";AACA,SAAS,2BAA2B;AAEpC,OAAO,WAAW;AAOX,SAAS,qBAAqB,MAAoB;AACvD,SAAO,KAAK,SAAS,CAAC,IAAI,MAAO,KAAK,SAAS,CAAC,IAAI;AACtD;AAMO,IAAM,wBAAN,MAAM,+BAA8B,oBAAoB;AAAA;AAAA,EAE7D,OAAgB,qBAAqB;AAAA,IACnC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA;AAAA,EAGA,OAAgB,uBAAuB;AAAA,IACrC,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAAA,EAEA;AAAA,EACQ;AAAA,EAER,YAAY,WAAW,GAAG,SAAiB,SAAS;AAClD,UAAM;AACN,SAAK,YAAY;AACjB,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA,EAGA,IAAI,WAAW;AACb,WAAO,KAAK;AAAA,EACd;AAAA,EAES,OAAO,OAA6B;AAC3C,eAAW,QAAQ,OAAO;AACxB,YAAM,YAAY,KAAK,UAAU,IAAI;AACrC,UAAI,YAAY,KAAK,UAAU;AAC7B;AAAA,MACF;AACA,YAAM,WAAW,qBAAqB,IAAI;AAC1C,WAAK,OAAO,IAAI,MAAM,KAAK;AAAA,QACzB,SAAS,KAAK,IAAI;AAAA,QAClB,KAAK,SAAS,SAAS,EAAE,GAAG,QAAQ,IAAI;AAAA,QACxC,YAAY,KAAK,YAAY,EAAE,OAAO;AAAA,MACxC,EAAE,KAAK,IAAI,CAAC,CAAC;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,SAAS,OAAe;AACtB,WAAO,uBAAsB,qBAAqB,KAAK,KAAK,MAAM;AAAA,EACpE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAU,MAAoB;AAC5B,QAAI,WAAW;AACf,UAAM,WAAW,qBAAqB,IAAI;AAC1C,aAAS,IAAI,uBAAsB,mBAAmB,SAAS,GAAG,KAAK,GAAG,KAAK;AAC7E,UAAI,WAAW,uBAAsB,mBAAmB,CAAC,GAAG;AAC1D,mBAAW;AACX;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;","names":[]}