autotel 7.4.0 → 7.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +29 -12
  2. package/dist/{attributes-Dt4YUYbP.js → attributes-DQQl-D6Q.js} +3 -1
  3. package/dist/{attributes-Cxys8tgr.cjs → attributes-DnfoMlA9.cjs} +3 -1
  4. package/dist/attributes.cjs +1 -1
  5. package/dist/attributes.d.cts +1 -1
  6. package/dist/attributes.d.ts +1 -1
  7. package/dist/attributes.js +1 -1
  8. package/dist/auto.cjs +1 -1
  9. package/dist/auto.js +1 -1
  10. package/dist/{canonical-log-line-processor-DolzdawH.cjs → canonical-log-line-processor-B-tzezhk.cjs} +24 -10
  11. package/dist/{canonical-log-line-processor-l0Aqe6yp.d.cts → canonical-log-line-processor-C0Z_N4oL.d.cts} +17 -3
  12. package/dist/{canonical-log-line-processor-hFUmS__K.js → canonical-log-line-processor-CBv-OCp4.js} +24 -10
  13. package/dist/{canonical-log-line-processor-cPB4Axk-.d.ts → canonical-log-line-processor-Yq4cXcD5.d.ts} +17 -3
  14. package/dist/correlation-id.cjs +1 -1
  15. package/dist/correlation-id.js +1 -1
  16. package/dist/db.cjs +7 -7
  17. package/dist/db.js +7 -7
  18. package/dist/decorators.cjs +1 -1
  19. package/dist/decorators.js +1 -1
  20. package/dist/event.cjs +1 -1
  21. package/dist/event.js +1 -1
  22. package/dist/{functional-C4js2vTM.js → functional-BXgTFVTA.js} +1 -1
  23. package/dist/{functional-DHlD7V0x.cjs → functional-zasLBPyX.cjs} +1 -1
  24. package/dist/functional.cjs +1 -1
  25. package/dist/functional.js +1 -1
  26. package/dist/http.cjs +12 -9
  27. package/dist/http.js +12 -9
  28. package/dist/{index-CwrNAsgk.d.ts → index-CsoeCsGL.d.ts} +2 -2
  29. package/dist/{index-DQHf4cNl.d.cts → index-Y7If_wH4.d.cts} +2 -2
  30. package/dist/index.cjs +5 -5
  31. package/dist/index.d.cts +3 -3
  32. package/dist/index.d.ts +3 -3
  33. package/dist/index.js +5 -5
  34. package/dist/{init-8GSy2bza.d.cts → init-BU7qa-Ii.d.cts} +67 -6
  35. package/dist/{init-CsKK9vZO.js → init-Bst_BhiS.js} +35 -13
  36. package/dist/{init-UnKrXhpq.d.ts → init-DDCgmfa4.d.ts} +67 -6
  37. package/dist/{init-DmM7dprX.cjs → init-OSYC19sK.cjs} +35 -13
  38. package/dist/instrumentation.cjs +3 -1
  39. package/dist/instrumentation.js +3 -1
  40. package/dist/messaging.cjs +2 -4
  41. package/dist/messaging.js +2 -4
  42. package/dist/processors.cjs +1 -1
  43. package/dist/processors.d.cts +1 -1
  44. package/dist/processors.d.ts +1 -1
  45. package/dist/processors.js +1 -1
  46. package/dist/{registry-DVSmWg6Y.js → registry-Cy4JjIB-.js} +2 -2
  47. package/dist/{registry-DYgvb62e.cjs → registry-DIoklBz5.cjs} +2 -2
  48. package/dist/sampling.cjs +1 -1
  49. package/dist/sampling.js +1 -1
  50. package/dist/semantic-conventions.cjs +1 -1
  51. package/dist/semantic-conventions.js +1 -1
  52. package/dist/semantic-helpers.cjs +4 -5
  53. package/dist/semantic-helpers.js +4 -5
  54. package/dist/tail-sampling-processor.cjs +1 -1
  55. package/dist/tail-sampling-processor.js +1 -1
  56. package/dist/webhook.cjs +1 -1
  57. package/dist/webhook.js +1 -1
  58. package/dist/workflow-distributed.cjs +1 -1
  59. package/dist/workflow-distributed.js +1 -1
  60. package/dist/workflow.cjs +1 -1
  61. package/dist/workflow.js +1 -1
  62. package/dist/yaml-config.cjs +1 -1
  63. package/dist/yaml-config.d.cts +1 -1
  64. package/dist/yaml-config.d.ts +1 -1
  65. package/dist/yaml-config.js +1 -1
  66. package/package.json +34 -34
package/README.md CHANGED
@@ -1027,10 +1027,10 @@ export const processUser = withTracing({})((ctx) => async (user) => {
1027
1027
  // Warn on deprecated attributes
1028
1028
  safeSetAttributes(
1029
1029
  ctx,
1030
- { 'http.method': 'GET' }, // Deprecated!
1030
+ { 'http.request.method': 'GET' }, // Deprecated!
1031
1031
  { guardrails: { warnDeprecated: true } },
1032
1032
  );
1033
- // Console: [autotel/attributes] Attribute "http.method" is deprecated. Use "http.request.method" instead.
1033
+ // Console: [autotel/attributes] Attribute "http.request.method" is deprecated. Use "http.request.method" instead.
1034
1034
  });
1035
1035
  ```
1036
1036
 
@@ -1161,7 +1161,7 @@ export const publishOrder = traceProducer({
1161
1161
  **Automatic Span Attributes (OTel Semantic Conventions):**
1162
1162
 
1163
1163
  - `messaging.system` - The messaging system (kafka, sqs, rabbitmq, etc.)
1164
- - `messaging.operation` - Always "publish" for producers
1164
+ - `messaging.operation.type` - Always "publish" for producers
1165
1165
  - `messaging.destination.name` - Topic/queue name
1166
1166
  - `messaging.message.id` - Extracted message ID (if configured)
1167
1167
  - `messaging.kafka.destination.partition` - Partition number (Kafka-specific)
@@ -1222,7 +1222,7 @@ export const processWithDLQ = traceConsumer({
1222
1222
 
1223
1223
  - `messaging.consumer.group` - Consumer group name
1224
1224
  - `messaging.batch.message_count` - Batch size (if batch mode)
1225
- - `messaging.operation` - "receive" or "process"
1225
+ - `messaging.operation.type` - "receive" or "process"
1226
1226
 
1227
1227
  ### Consumer Lag Metrics
1228
1228
 
@@ -1836,6 +1836,23 @@ WHERE duration_ms > 200
1836
1836
 
1837
1837
  ### Configuration Options
1838
1838
 
1839
+ To keep canonical lines in a platform logger and send the same records to
1840
+ Grafana Loki over OTLP, enable both destinations. Selecting `otel: true`
1841
+ auto-configures log export from `endpoint`; an explicit `logs: false` or
1842
+ `AUTOTEL_LOGS=off` still wins.
1843
+
1844
+ ```typescript
1845
+ init({
1846
+ service: 'my-app',
1847
+ endpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
1848
+ canonicalLogLines: {
1849
+ enabled: true,
1850
+ logger: [pino(), auditLogger],
1851
+ otel: true,
1852
+ },
1853
+ });
1854
+ ```
1855
+
1839
1856
  ```typescript
1840
1857
  init({
1841
1858
  service: 'my-app',
@@ -3005,8 +3022,8 @@ export function instrumentAxios(
3005
3022
  });
3006
3023
 
3007
3024
  // Follow OpenTelemetry semantic conventions
3008
- span.setAttribute('http.method', method);
3009
- span.setAttribute('http.url', url);
3025
+ span.setAttribute('http.request.method', method);
3026
+ span.setAttribute('url.full', url);
3010
3027
 
3011
3028
  if (captureHeaders && requestConfig.headers) {
3012
3029
  span.setAttribute(
@@ -3033,7 +3050,7 @@ export function instrumentAxios(
3033
3050
  (response: AxiosResponse) => {
3034
3051
  const span = (response.config as any).__span;
3035
3052
  if (span) {
3036
- span.setAttribute('http.status_code', response.status);
3053
+ span.setAttribute('http.response.status_code', response.status);
3037
3054
 
3038
3055
  if (captureResponseBody && response.data) {
3039
3056
  span.setAttribute(
@@ -3051,7 +3068,7 @@ export function instrumentAxios(
3051
3068
  const span = error.config?.__span;
3052
3069
  if (span) {
3053
3070
  if (error.response) {
3054
- span.setAttribute('http.status_code', error.response.status);
3071
+ span.setAttribute('http.response.status_code', error.response.status);
3055
3072
  }
3056
3073
  // Step 9: Finalize span on error (records exception)
3057
3074
  finalizeSpan(span, error);
@@ -3139,10 +3156,10 @@ Use standard attribute names from [OpenTelemetry Semantic Conventions](https://o
3139
3156
 
3140
3157
  ```typescript
3141
3158
  // ✅ Good - Standard conventions
3142
- span.setAttribute('http.method', 'GET');
3143
- span.setAttribute('http.status_code', 200);
3144
- span.setAttribute('db.system', 'postgresql');
3145
- span.setAttribute('db.operation', 'SELECT');
3159
+ span.setAttribute('http.request.method', 'GET');
3160
+ span.setAttribute('http.response.status_code', 200);
3161
+ span.setAttribute('db.system.name', 'postgresql');
3162
+ span.setAttribute('db.operation.name', 'SELECT');
3146
3163
  span.setAttribute('messaging.system', 'kafka');
3147
3164
 
3148
3165
  // ❌ Bad - Custom names
@@ -1,6 +1,6 @@
1
1
  import { l as asString } from "./values-BenyvWKz.js";
2
2
  import { REDACTOR_PATTERNS } from "./attribute-redacting-processor.js";
3
- import { C as URLAttributes, S as ThreadAttributes, _ as RPCAttributes, a as DeviceAttributes, b as SessionAttributes, c as FaaSAttributes, d as HTTPAttributes, f as K8sAttributes, g as ProcessAttributes, h as OTelAttributes, i as DBAttributes, l as FeatureFlagAttributes, m as NetworkAttributes, n as CodeAttributes, o as ErrorAttributes, p as MessagingAttributes, r as ContainerAttributes, s as ExceptionAttributes, t as CloudAttributes, u as GraphQLAttributes, v as ServerAddressAttributes, w as UserAttributes, x as TLSAttributes, y as ServiceAttributes } from "./registry-DVSmWg6Y.js";
3
+ import { C as URLAttributes, S as ThreadAttributes, _ as RPCAttributes, a as DeviceAttributes, b as SessionAttributes, c as FaaSAttributes, d as HTTPAttributes, f as K8sAttributes, g as ProcessAttributes, h as OTelAttributes, i as DBAttributes, l as FeatureFlagAttributes, m as NetworkAttributes, n as CodeAttributes, o as ErrorAttributes, p as MessagingAttributes, r as ContainerAttributes, s as ExceptionAttributes, t as CloudAttributes, u as GraphQLAttributes, v as ServerAddressAttributes, w as UserAttributes, x as TLSAttributes, y as ServiceAttributes } from "./registry-Cy4JjIB-.js";
4
4
  import { resourceFromAttributes } from "@opentelemetry/resources";
5
5
 
6
6
  //#region src/attributes/builders.ts
@@ -351,6 +351,8 @@ const DEPRECATED_ATTRIBUTES = /* @__PURE__ */ new Map([
351
351
  ["db.operation", "db.operation.name"],
352
352
  ["db.statement", "db.query.text"],
353
353
  ["db.system", "db.system.name"],
354
+ ["rpc.system", "rpc.system.name"],
355
+ ["messaging.operation", "messaging.operation.type"],
354
356
  ["db.collection", "db.collection.name"],
355
357
  ["db.instance.id", null],
356
358
  ["db.jdbc.driver_classname", null],
@@ -1,6 +1,6 @@
1
1
  const require_values = require('./values-DApyq53y.cjs');
2
2
  const require_attribute_redacting_processor = require('./attribute-redacting-processor.cjs');
3
- const require_registry = require('./registry-DYgvb62e.cjs');
3
+ const require_registry = require('./registry-DIoklBz5.cjs');
4
4
  let _opentelemetry_resources = require("@opentelemetry/resources");
5
5
 
6
6
  //#region src/attributes/builders.ts
@@ -351,6 +351,8 @@ const DEPRECATED_ATTRIBUTES = /* @__PURE__ */ new Map([
351
351
  ["db.operation", "db.operation.name"],
352
352
  ["db.statement", "db.query.text"],
353
353
  ["db.system", "db.system.name"],
354
+ ["rpc.system", "rpc.system.name"],
355
+ ["messaging.operation", "messaging.operation.type"],
354
356
  ["db.collection", "db.collection.name"],
355
357
  ["db.instance.id", null],
356
358
  ["db.jdbc.driver_classname", null],
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_attributes = require('./attributes-Cxys8tgr.cjs');
2
+ const require_attributes = require('./attributes-DnfoMlA9.cjs');
3
3
 
4
4
  exports.attrs = require_attributes.attrs;
5
5
  exports.autoRedactPII = require_attributes.autoRedactPII;
@@ -1,2 +1,2 @@
1
- import { A as ExceptionAttrs, B as PeerAttrs, C as CloudAttrs, D as DeploymentAttrs, E as DBAttrs, F as HTTPServerAttrs, G as SessionAttrs, H as RPCAttrs, I as K8sAttrs, J as URLAttrs, K as TLSAttrs, L as MessagingAttrs, M as FeatureFlagAttrs, N as GraphQLAttrs, O as DeviceAttrs, P as HTTPClientAttrs, R as NetworkAttrs, S as ClientAttrs, T as ContainerAttrs, U as ServerAddressAttrs, V as ProcessAttrs, W as ServiceAttrs, Y as UserAttrs, _ as autoRedactPII, a as httpClient, b as validateAttribute, c as mergeServiceResource, d as setError, f as setException, g as AttributePolicy, h as AttributeGuardrails, i as dbClient, j as FaaSAttrs, k as ErrorAttrs, l as request, m as setUser, n as safeSetAttributes, o as httpServer, p as setSession, q as ThreadAttrs, r as transaction, s as identify, t as mergeAttrs, u as setDevice, v as checkDeprecatedAttribute, w as CodeAttrs, x as attrs, y as defaultGuardrails, z as OTelAttrs } from "./index-DQHf4cNl.cjs";
1
+ import { A as ExceptionAttrs, B as PeerAttrs, C as CloudAttrs, D as DeploymentAttrs, E as DBAttrs, F as HTTPServerAttrs, G as SessionAttrs, H as RPCAttrs, I as K8sAttrs, J as URLAttrs, K as TLSAttrs, L as MessagingAttrs, M as FeatureFlagAttrs, N as GraphQLAttrs, O as DeviceAttrs, P as HTTPClientAttrs, R as NetworkAttrs, S as ClientAttrs, T as ContainerAttrs, U as ServerAddressAttrs, V as ProcessAttrs, W as ServiceAttrs, Y as UserAttrs, _ as autoRedactPII, a as httpClient, b as validateAttribute, c as mergeServiceResource, d as setError, f as setException, g as AttributePolicy, h as AttributeGuardrails, i as dbClient, j as FaaSAttrs, k as ErrorAttrs, l as request, m as setUser, n as safeSetAttributes, o as httpServer, p as setSession, q as ThreadAttrs, r as transaction, s as identify, t as mergeAttrs, u as setDevice, v as checkDeprecatedAttribute, w as CodeAttrs, x as attrs, y as defaultGuardrails, z as OTelAttrs } from "./index-Y7If_wH4.cjs";
2
2
  export { type AttributeGuardrails, type AttributePolicy, type ClientAttrs, type CloudAttrs, type CodeAttrs, type ContainerAttrs, type DBAttrs, type DeploymentAttrs, type DeviceAttrs, type ErrorAttrs, type ExceptionAttrs, type FaaSAttrs, type FeatureFlagAttrs, type GraphQLAttrs, type HTTPClientAttrs, type HTTPServerAttrs, type K8sAttrs, type MessagingAttrs, type NetworkAttrs, type OTelAttrs, type PeerAttrs, type ProcessAttrs, type RPCAttrs, type ServerAddressAttrs, type ServiceAttrs, type SessionAttrs, type TLSAttrs, type ThreadAttrs, type URLAttrs, type UserAttrs, attrs, autoRedactPII, checkDeprecatedAttribute, dbClient, defaultGuardrails, httpClient, httpServer, identify, mergeAttrs, mergeServiceResource, request, safeSetAttributes, setDevice, setError, setException, setSession, setUser, transaction, validateAttribute };
@@ -1,2 +1,2 @@
1
- import { A as ExceptionAttrs, B as PeerAttrs, C as CloudAttrs, D as DeploymentAttrs, E as DBAttrs, F as HTTPServerAttrs, G as SessionAttrs, H as RPCAttrs, I as K8sAttrs, J as URLAttrs, K as TLSAttrs, L as MessagingAttrs, M as FeatureFlagAttrs, N as GraphQLAttrs, O as DeviceAttrs, P as HTTPClientAttrs, R as NetworkAttrs, S as ClientAttrs, T as ContainerAttrs, U as ServerAddressAttrs, V as ProcessAttrs, W as ServiceAttrs, Y as UserAttrs, _ as autoRedactPII, a as httpClient, b as validateAttribute, c as mergeServiceResource, d as setError, f as setException, g as AttributePolicy, h as AttributeGuardrails, i as dbClient, j as FaaSAttrs, k as ErrorAttrs, l as request, m as setUser, n as safeSetAttributes, o as httpServer, p as setSession, q as ThreadAttrs, r as transaction, s as identify, t as mergeAttrs, u as setDevice, v as checkDeprecatedAttribute, w as CodeAttrs, x as attrs, y as defaultGuardrails, z as OTelAttrs } from "./index-CwrNAsgk.js";
1
+ import { A as ExceptionAttrs, B as PeerAttrs, C as CloudAttrs, D as DeploymentAttrs, E as DBAttrs, F as HTTPServerAttrs, G as SessionAttrs, H as RPCAttrs, I as K8sAttrs, J as URLAttrs, K as TLSAttrs, L as MessagingAttrs, M as FeatureFlagAttrs, N as GraphQLAttrs, O as DeviceAttrs, P as HTTPClientAttrs, R as NetworkAttrs, S as ClientAttrs, T as ContainerAttrs, U as ServerAddressAttrs, V as ProcessAttrs, W as ServiceAttrs, Y as UserAttrs, _ as autoRedactPII, a as httpClient, b as validateAttribute, c as mergeServiceResource, d as setError, f as setException, g as AttributePolicy, h as AttributeGuardrails, i as dbClient, j as FaaSAttrs, k as ErrorAttrs, l as request, m as setUser, n as safeSetAttributes, o as httpServer, p as setSession, q as ThreadAttrs, r as transaction, s as identify, t as mergeAttrs, u as setDevice, v as checkDeprecatedAttribute, w as CodeAttrs, x as attrs, y as defaultGuardrails, z as OTelAttrs } from "./index-CsoeCsGL.js";
2
2
  export { type AttributeGuardrails, type AttributePolicy, type ClientAttrs, type CloudAttrs, type CodeAttrs, type ContainerAttrs, type DBAttrs, type DeploymentAttrs, type DeviceAttrs, type ErrorAttrs, type ExceptionAttrs, type FaaSAttrs, type FeatureFlagAttrs, type GraphQLAttrs, type HTTPClientAttrs, type HTTPServerAttrs, type K8sAttrs, type MessagingAttrs, type NetworkAttrs, type OTelAttrs, type PeerAttrs, type ProcessAttrs, type RPCAttrs, type ServerAddressAttrs, type ServiceAttrs, type SessionAttrs, type TLSAttrs, type ThreadAttrs, type URLAttrs, type UserAttrs, attrs, autoRedactPII, checkDeprecatedAttribute, dbClient, defaultGuardrails, httpClient, httpServer, identify, mergeAttrs, mergeServiceResource, request, safeSetAttributes, setDevice, setError, setException, setSession, setUser, transaction, validateAttribute };
@@ -1,3 +1,3 @@
1
- import { _ as defaultGuardrails, a as identify, c as setDevice, d as setSession, f as setUser, g as checkDeprecatedAttribute, h as autoRedactPII, i as httpServer, l as setError, m as safeSetAttributes, n as dbClient, o as mergeServiceResource, p as mergeAttrs, r as httpClient, s as request, t as transaction, u as setException, v as validateAttribute, y as attrs } from "./attributes-Dt4YUYbP.js";
1
+ import { _ as defaultGuardrails, a as identify, c as setDevice, d as setSession, f as setUser, g as checkDeprecatedAttribute, h as autoRedactPII, i as httpServer, l as setError, m as safeSetAttributes, n as dbClient, o as mergeServiceResource, p as mergeAttrs, r as httpClient, s as request, t as transaction, u as setException, v as validateAttribute, y as attrs } from "./attributes-DQQl-D6Q.js";
2
2
 
3
3
  export { attrs, autoRedactPII, checkDeprecatedAttribute, dbClient, defaultGuardrails, httpClient, httpServer, identify, mergeAttrs, mergeServiceResource, request, safeSetAttributes, setDevice, setError, setException, setSession, setUser, transaction, validateAttribute };
package/dist/auto.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  const require_rolldown_runtime = require('./rolldown-runtime-C_NdSu1c.cjs');
2
- const require_init = require('./init-DmM7dprX.cjs');
2
+ const require_init = require('./init-OSYC19sK.cjs');
3
3
  let node_module = require("node:module");
4
4
  node_module = require_rolldown_runtime.__toESM(node_module, 1);
5
5
  let import_in_the_middle = require("import-in-the-middle");
package/dist/auto.js CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as loadYamlConfig, a as init } from "./init-CsKK9vZO.js";
1
+ import { _ as loadYamlConfig, a as init } from "./init-Bst_BhiS.js";
2
2
  import * as nodeModule from "node:module";
3
3
  import { createAddHookMessageChannel } from "import-in-the-middle";
4
4
 
@@ -233,7 +233,8 @@ const SEVERITY_NUMBERS = /* @__PURE__ */ new Map([
233
233
  * ```
234
234
  */
235
235
  var CanonicalLogLineProcessor = class {
236
- logger;
236
+ loggers;
237
+ useOtel;
237
238
  rootSpansOnly;
238
239
  minLevel;
239
240
  messageFormat;
@@ -245,7 +246,8 @@ var CanonicalLogLineProcessor = class {
245
246
  pretty;
246
247
  getOTelLogger = null;
247
248
  constructor(options = {}) {
248
- this.logger = options.logger;
249
+ this.loggers = options.logger ? Array.isArray(options.logger) ? options.logger.filter(Boolean) : [options.logger] : [];
250
+ this.useOtel = options.otel ?? this.loggers.length === 0;
249
251
  this.rootSpansOnly = options.rootSpansOnly ?? false;
250
252
  this.minLevel = options.minLevel ?? "info";
251
253
  this.messageFormat = options.messageFormat ?? ((span) => `[${span.name}] Request completed`);
@@ -255,7 +257,7 @@ var CanonicalLogLineProcessor = class {
255
257
  this.drain = options.drain;
256
258
  this.onDrainError = options.onDrainError;
257
259
  this.pretty = options.pretty ?? (require_values.hasProcess() && process.env.NODE_ENV === "development");
258
- if (!this.logger) this.getOTelLogger = () => _opentelemetry_api_logs.logs.getLogger("autotel.canonical-log-line");
260
+ if (this.useOtel) this.getOTelLogger = () => _opentelemetry_api_logs.logs.getLogger("autotel.canonical-log-line");
259
261
  }
260
262
  buildKeepPredicate(keep) {
261
263
  if (!keep || keep.length === 0) return void 0;
@@ -287,10 +289,12 @@ var CanonicalLogLineProcessor = class {
287
289
  };
288
290
  if (this.shouldEmit && !this.shouldEmit(eventContext)) return;
289
291
  if (this.pretty) console.log(formatPrettyLogLine(eventContext));
290
- if (this.logger) this.emitViaLogger(level, message, canonicalLogLine);
291
- else if (this.getOTelLogger) {
292
+ if (this.loggers.length > 0) this.emitViaLogger(level, message, canonicalLogLine);
293
+ if (this.getOTelLogger) try {
292
294
  const otelLogger = this.getOTelLogger();
293
295
  this.emitViaOTel(level, message, canonicalLogLine, otelLogger);
296
+ } catch (error) {
297
+ this.reportInternalWarning("canonical log line OTel emission failed", error);
294
298
  }
295
299
  if (this.drain) Promise.resolve(this.drain(eventContext)).catch((error) => {
296
300
  if (this.onDrainError) {
@@ -328,7 +332,11 @@ var CanonicalLogLineProcessor = class {
328
332
  return redacted;
329
333
  }
330
334
  emitViaLogger(level, message, canonicalLogLine) {
331
- this.logger[level](canonicalLogLine, message);
335
+ for (const logger of this.loggers) try {
336
+ logger[level](canonicalLogLine, message);
337
+ } catch (error) {
338
+ this.reportInternalWarning("canonical log line logger emission failed", error);
339
+ }
332
340
  }
333
341
  emitViaOTel(level, message, canonicalLogLine, otelLogger) {
334
342
  const otelAttributes = {};
@@ -364,11 +372,17 @@ var CanonicalLogLineProcessor = class {
364
372
  }
365
373
  reportInternalWarning(message, cause) {
366
374
  const err = cause === void 0 ? "unknown error" : require_values.toError(cause).message;
367
- if (this.logger) {
368
- this.logger.warn({ error: err }, `[autotel] ${message}`);
369
- return;
375
+ if (this.loggers.length > 0) {
376
+ let reported = false;
377
+ for (const logger of this.loggers) try {
378
+ logger.warn({ error: err }, `[autotel] ${message}`);
379
+ reported = true;
380
+ } catch {}
381
+ if (reported) return;
370
382
  }
371
- console.warn(`[autotel] ${message}: ${err}`);
383
+ try {
384
+ console.warn(`[autotel] ${message}: ${err}`);
385
+ } catch {}
372
386
  }
373
387
  async forceFlush() {}
374
388
  async shutdown() {}
@@ -22,8 +22,21 @@ interface KeepCondition {
22
22
  path?: string;
23
23
  }
24
24
  interface CanonicalLogLineOptions {
25
- /** Logger to use for emitting canonical log lines (defaults to OTel Logs API) */
26
- logger?: Logger;
25
+ /**
26
+ * Logger(s) to emit canonical log lines through. Pass an array to fan out to
27
+ * several. When omitted, lines go to the OTel Logs API instead.
28
+ */
29
+ logger?: Logger | Logger[];
30
+ /**
31
+ * Also emit through the OTel Logs API (and so to an OTLP logs backend such
32
+ * as Loki) alongside any `logger`.
33
+ *
34
+ * Defaults to true only when no `logger` is given, which is the historical
35
+ * either/or behaviour. Set it explicitly to have both: a console/pino logger
36
+ * keeps lines in the platform's own log view while OTLP carries the same
37
+ * lines to your backend.
38
+ */
39
+ otel?: boolean;
27
40
  /** Only emit canonical log lines for root spans (default: false) */
28
41
  rootSpansOnly?: boolean;
29
42
  /** Minimum log level for canonical log lines (default: 'info') */
@@ -116,7 +129,8 @@ interface CanonicalLogLineOptions {
116
129
  * ```
117
130
  */
118
131
  declare class CanonicalLogLineProcessor implements SpanProcessor {
119
- private logger?;
132
+ private loggers;
133
+ private useOtel;
120
134
  private rootSpansOnly;
121
135
  private minLevel;
122
136
  private messageFormat;
@@ -233,7 +233,8 @@ const SEVERITY_NUMBERS = /* @__PURE__ */ new Map([
233
233
  * ```
234
234
  */
235
235
  var CanonicalLogLineProcessor = class {
236
- logger;
236
+ loggers;
237
+ useOtel;
237
238
  rootSpansOnly;
238
239
  minLevel;
239
240
  messageFormat;
@@ -245,7 +246,8 @@ var CanonicalLogLineProcessor = class {
245
246
  pretty;
246
247
  getOTelLogger = null;
247
248
  constructor(options = {}) {
248
- this.logger = options.logger;
249
+ this.loggers = options.logger ? Array.isArray(options.logger) ? options.logger.filter(Boolean) : [options.logger] : [];
250
+ this.useOtel = options.otel ?? this.loggers.length === 0;
249
251
  this.rootSpansOnly = options.rootSpansOnly ?? false;
250
252
  this.minLevel = options.minLevel ?? "info";
251
253
  this.messageFormat = options.messageFormat ?? ((span) => `[${span.name}] Request completed`);
@@ -255,7 +257,7 @@ var CanonicalLogLineProcessor = class {
255
257
  this.drain = options.drain;
256
258
  this.onDrainError = options.onDrainError;
257
259
  this.pretty = options.pretty ?? (hasProcess() && process.env.NODE_ENV === "development");
258
- if (!this.logger) this.getOTelLogger = () => logs.getLogger("autotel.canonical-log-line");
260
+ if (this.useOtel) this.getOTelLogger = () => logs.getLogger("autotel.canonical-log-line");
259
261
  }
260
262
  buildKeepPredicate(keep) {
261
263
  if (!keep || keep.length === 0) return void 0;
@@ -287,10 +289,12 @@ var CanonicalLogLineProcessor = class {
287
289
  };
288
290
  if (this.shouldEmit && !this.shouldEmit(eventContext)) return;
289
291
  if (this.pretty) console.log(formatPrettyLogLine(eventContext));
290
- if (this.logger) this.emitViaLogger(level, message, canonicalLogLine);
291
- else if (this.getOTelLogger) {
292
+ if (this.loggers.length > 0) this.emitViaLogger(level, message, canonicalLogLine);
293
+ if (this.getOTelLogger) try {
292
294
  const otelLogger = this.getOTelLogger();
293
295
  this.emitViaOTel(level, message, canonicalLogLine, otelLogger);
296
+ } catch (error) {
297
+ this.reportInternalWarning("canonical log line OTel emission failed", error);
294
298
  }
295
299
  if (this.drain) Promise.resolve(this.drain(eventContext)).catch((error) => {
296
300
  if (this.onDrainError) {
@@ -328,7 +332,11 @@ var CanonicalLogLineProcessor = class {
328
332
  return redacted;
329
333
  }
330
334
  emitViaLogger(level, message, canonicalLogLine) {
331
- this.logger[level](canonicalLogLine, message);
335
+ for (const logger of this.loggers) try {
336
+ logger[level](canonicalLogLine, message);
337
+ } catch (error) {
338
+ this.reportInternalWarning("canonical log line logger emission failed", error);
339
+ }
332
340
  }
333
341
  emitViaOTel(level, message, canonicalLogLine, otelLogger) {
334
342
  const otelAttributes = {};
@@ -364,11 +372,17 @@ var CanonicalLogLineProcessor = class {
364
372
  }
365
373
  reportInternalWarning(message, cause) {
366
374
  const err = cause === void 0 ? "unknown error" : toError(cause).message;
367
- if (this.logger) {
368
- this.logger.warn({ error: err }, `[autotel] ${message}`);
369
- return;
375
+ if (this.loggers.length > 0) {
376
+ let reported = false;
377
+ for (const logger of this.loggers) try {
378
+ logger.warn({ error: err }, `[autotel] ${message}`);
379
+ reported = true;
380
+ } catch {}
381
+ if (reported) return;
370
382
  }
371
- console.warn(`[autotel] ${message}: ${err}`);
383
+ try {
384
+ console.warn(`[autotel] ${message}: ${err}`);
385
+ } catch {}
372
386
  }
373
387
  async forceFlush() {}
374
388
  async shutdown() {}
@@ -22,8 +22,21 @@ interface KeepCondition {
22
22
  path?: string;
23
23
  }
24
24
  interface CanonicalLogLineOptions {
25
- /** Logger to use for emitting canonical log lines (defaults to OTel Logs API) */
26
- logger?: Logger;
25
+ /**
26
+ * Logger(s) to emit canonical log lines through. Pass an array to fan out to
27
+ * several. When omitted, lines go to the OTel Logs API instead.
28
+ */
29
+ logger?: Logger | Logger[];
30
+ /**
31
+ * Also emit through the OTel Logs API (and so to an OTLP logs backend such
32
+ * as Loki) alongside any `logger`.
33
+ *
34
+ * Defaults to true only when no `logger` is given, which is the historical
35
+ * either/or behaviour. Set it explicitly to have both: a console/pino logger
36
+ * keeps lines in the platform's own log view while OTLP carries the same
37
+ * lines to your backend.
38
+ */
39
+ otel?: boolean;
27
40
  /** Only emit canonical log lines for root spans (default: false) */
28
41
  rootSpansOnly?: boolean;
29
42
  /** Minimum log level for canonical log lines (default: 'info') */
@@ -116,7 +129,8 @@ interface CanonicalLogLineOptions {
116
129
  * ```
117
130
  */
118
131
  declare class CanonicalLogLineProcessor implements SpanProcessor {
119
- private logger?;
132
+ private loggers;
133
+ private useOtel;
120
134
  private rootSpansOnly;
121
135
  private minLevel;
122
136
  private messageFormat;
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_init = require('./init-DmM7dprX.cjs');
2
+ const require_init = require('./init-OSYC19sK.cjs');
3
3
 
4
4
  exports.CORRELATION_ID_BAGGAGE_KEY = require_init.CORRELATION_ID_BAGGAGE_KEY;
5
5
  exports.generateCorrelationId = require_init.generateCorrelationId;
@@ -1,3 +1,3 @@
1
- import { $ as getCorrelationStorage, Q as getCorrelationId, X as CORRELATION_ID_BAGGAGE_KEY, Z as generateCorrelationId, et as getOrCreateCorrelationId, nt as setCorrelationId, rt as setCorrelationIdInBaggage, tt as runWithCorrelationId } from "./init-CsKK9vZO.js";
1
+ import { $ as getCorrelationStorage, Q as getCorrelationId, X as CORRELATION_ID_BAGGAGE_KEY, Z as generateCorrelationId, et as getOrCreateCorrelationId, nt as setCorrelationId, rt as setCorrelationIdInBaggage, tt as runWithCorrelationId } from "./init-Bst_BhiS.js";
2
2
 
3
3
  export { CORRELATION_ID_BAGGAGE_KEY, generateCorrelationId, getCorrelationId, getCorrelationStorage, getOrCreateCorrelationId, runWithCorrelationId, setCorrelationId, setCorrelationIdInBaggage };
package/dist/db.cjs CHANGED
@@ -45,8 +45,8 @@ async function tracebQuery(dbSystem, operation, fn, attributes) {
45
45
  const startTime = performance.now();
46
46
  try {
47
47
  span.setAttributes({
48
- "db.system": dbSystem,
49
- "db.operation": operation,
48
+ "db.system.name": dbSystem,
49
+ "db.operation.name": operation,
50
50
  ...attributes
51
51
  });
52
52
  const result = await fn();
@@ -188,13 +188,13 @@ function instrumentDatabase(client, options) {
188
188
  const startTime = performance.now();
189
189
  try {
190
190
  span.setAttributes({
191
- "db.system": dbSystem,
192
- "db.operation": operation
191
+ "db.system.name": dbSystem,
192
+ "db.operation.name": operation
193
193
  });
194
- if (dbName) span.setAttribute("db.name", dbName);
195
- if (table) span.setAttribute("db.sql.table", table);
194
+ if (dbName) span.setAttribute("db.namespace", dbName);
195
+ if (table) span.setAttribute("db.collection.name", table);
196
196
  const query = extractQueryFromArgs(args);
197
- if (query) span.setAttribute("db.statement", sanitizeQuery ? sanitizeSqlQuery(query) : query);
197
+ if (query) span.setAttribute("db.query.text", sanitizeQuery ? sanitizeSqlQuery(query) : query);
198
198
  const result = await originalMethod.apply(this, args);
199
199
  const duration = performance.now() - startTime;
200
200
  span.setStatus({ code: _opentelemetry_api.SpanStatusCode.OK });
package/dist/db.js CHANGED
@@ -44,8 +44,8 @@ async function tracebQuery(dbSystem, operation, fn, attributes) {
44
44
  const startTime = performance.now();
45
45
  try {
46
46
  span.setAttributes({
47
- "db.system": dbSystem,
48
- "db.operation": operation,
47
+ "db.system.name": dbSystem,
48
+ "db.operation.name": operation,
49
49
  ...attributes
50
50
  });
51
51
  const result = await fn();
@@ -187,13 +187,13 @@ function instrumentDatabase(client, options) {
187
187
  const startTime = performance.now();
188
188
  try {
189
189
  span.setAttributes({
190
- "db.system": dbSystem,
191
- "db.operation": operation
190
+ "db.system.name": dbSystem,
191
+ "db.operation.name": operation
192
192
  });
193
- if (dbName) span.setAttribute("db.name", dbName);
194
- if (table) span.setAttribute("db.sql.table", table);
193
+ if (dbName) span.setAttribute("db.namespace", dbName);
194
+ if (table) span.setAttribute("db.collection.name", table);
195
195
  const query = extractQueryFromArgs(args);
196
- if (query) span.setAttribute("db.statement", sanitizeQuery ? sanitizeSqlQuery(query) : query);
196
+ if (query) span.setAttribute("db.query.text", sanitizeQuery ? sanitizeSqlQuery(query) : query);
197
197
  const result = await originalMethod.apply(this, args);
198
198
  const duration = performance.now() - startTime;
199
199
  span.setStatus({ code: SpanStatusCode.OK });
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_values = require('./values-DApyq53y.cjs');
3
3
  const require_config = require('./config.cjs');
4
- const require_init = require('./init-DmM7dprX.cjs');
4
+ const require_init = require('./init-OSYC19sK.cjs');
5
5
  let _opentelemetry_api = require("@opentelemetry/api");
6
6
 
7
7
  //#region src/decorators.ts
@@ -1,6 +1,6 @@
1
1
  import { y as splitNameOrOptions } from "./values-BenyvWKz.js";
2
2
  import { getConfig } from "./config.js";
3
- import { U as createTraceContext } from "./init-CsKK9vZO.js";
3
+ import { U as createTraceContext } from "./init-Bst_BhiS.js";
4
4
  import { SpanStatusCode } from "@opentelemetry/api";
5
5
 
6
6
  //#region src/decorators.ts
package/dist/event.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_init = require('./init-DmM7dprX.cjs');
2
+ const require_init = require('./init-OSYC19sK.cjs');
3
3
 
4
4
  exports.Event = require_init.Event;
5
5
  exports.getEvents = require_init.getEvents;
package/dist/event.js CHANGED
@@ -1,3 +1,3 @@
1
- import { d as Event, f as getEvents, p as resetEvents } from "./init-CsKK9vZO.js";
1
+ import { d as Event, f as getEvents, p as resetEvents } from "./init-Bst_BhiS.js";
2
2
 
3
3
  export { Event, getEvents, resetEvents };
@@ -1,7 +1,7 @@
1
1
  import { l as asString, m as isDevelopment } from "./values-BenyvWKz.js";
2
2
  import { getForceFlushableProvider } from "./tracer-provider.js";
3
3
  import { getConfig } from "./config.js";
4
- import { C as AUTOTEL_SAMPLING_RATE, D as AlwaysSampler, G as getActiveContextWithBaggage, I as debugCaptureRequested, J as getEventQueue, K as getContextStorage, T as AUTOTEL_SAMPLING_TAIL_KEEP, U as createTraceContext, h as runInOperationContext, i as getSdk, n as getConfiguredSampler, q as hasExplicitSpanStatus, t as getConfig$1, w as AUTOTEL_SAMPLING_TAIL_EVALUATED, z as isForceKept } from "./init-CsKK9vZO.js";
4
+ import { C as AUTOTEL_SAMPLING_RATE, D as AlwaysSampler, G as getActiveContextWithBaggage, I as debugCaptureRequested, J as getEventQueue, K as getContextStorage, T as AUTOTEL_SAMPLING_TAIL_KEEP, U as createTraceContext, h as runInOperationContext, i as getSdk, n as getConfiguredSampler, q as hasExplicitSpanStatus, t as getConfig$1, w as AUTOTEL_SAMPLING_TAIL_EVALUATED, z as isForceKept } from "./init-Bst_BhiS.js";
5
5
  import { evidenceAttribute } from "./evidence.js";
6
6
  import { setSpanName } from "./trace-helpers.js";
7
7
  import { SpanStatusCode, context, propagation, trace } from "@opentelemetry/api";
@@ -2,7 +2,7 @@ const require_rolldown_runtime = require('./rolldown-runtime-C_NdSu1c.cjs');
2
2
  const require_values = require('./values-DApyq53y.cjs');
3
3
  const require_tracer_provider = require('./tracer-provider.cjs');
4
4
  const require_config = require('./config.cjs');
5
- const require_init = require('./init-DmM7dprX.cjs');
5
+ const require_init = require('./init-OSYC19sK.cjs');
6
6
  const require_evidence = require('./evidence.cjs');
7
7
  const require_trace_helpers = require('./trace-helpers.cjs');
8
8
  let _opentelemetry_api = require("@opentelemetry/api");
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_functional = require('./functional-DHlD7V0x.cjs');
2
+ const require_functional = require('./functional-zasLBPyX.cjs');
3
3
 
4
4
  exports.ctx = require_functional.ctx;
5
5
  exports.getActiveTraceContext = require_functional.getActiveTraceContext;
@@ -1,3 +1,3 @@
1
- import { a as trace, c as withTracing, i as span, n as getActiveTraceContext, o as withBaggage, r as instrument, s as withNewContext, t as ctx } from "./functional-C4js2vTM.js";
1
+ import { a as trace, c as withTracing, i as span, n as getActiveTraceContext, o as withBaggage, r as instrument, s as withNewContext, t as ctx } from "./functional-BXgTFVTA.js";
2
2
 
3
3
  export { ctx, getActiveTraceContext, instrument, span, trace, withBaggage, withNewContext, withTracing };
package/dist/http.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_values = require('./values-DApyq53y.cjs');
3
3
  const require_config = require('./config.cjs');
4
- const require_init = require('./init-DmM7dprX.cjs');
4
+ const require_init = require('./init-OSYC19sK.cjs');
5
5
  let _opentelemetry_api = require("@opentelemetry/api");
6
6
 
7
7
  //#region src/http.ts
@@ -89,17 +89,18 @@ function HttpInstrumented(options = {}) {
89
89
  const startTime = performance.now();
90
90
  try {
91
91
  span.setAttributes({
92
- "http.method": method,
93
- "http.url": url || "unknown",
92
+ "http.request.method": method,
93
+ "url.full": url || "unknown",
94
94
  "service.name": serviceName,
95
95
  "operation.name": `${serviceName}.${methodName}`
96
96
  });
97
97
  if (url) {
98
98
  const urlObj = parseUrl(url);
99
99
  span.setAttributes({
100
- "http.scheme": urlObj.protocol,
101
- "http.host": urlObj.host,
102
- "http.target": urlObj.path
100
+ "url.scheme": urlObj.protocol,
101
+ "server.address": urlObj.host,
102
+ "url.path": urlObj.path,
103
+ ...urlObj.query ? { "url.query": urlObj.query } : {}
103
104
  });
104
105
  }
105
106
  if (options.attributesFromArgs) span.setAttributes(options.attributesFromArgs(args));
@@ -107,7 +108,7 @@ function HttpInstrumented(options = {}) {
107
108
  const duration = performance.now() - startTime;
108
109
  const statusCode = extractStatusCode(result);
109
110
  if (statusCode) {
110
- span.setAttribute("http.status_code", statusCode);
111
+ span.setAttribute("http.response.status_code", statusCode);
111
112
  if (statusCode >= 400) span.setStatus({
112
113
  code: _opentelemetry_api.SpanStatusCode.ERROR,
113
114
  message: `HTTP ${statusCode}`
@@ -202,13 +203,15 @@ function parseUrl(url) {
202
203
  return {
203
204
  protocol: urlObj.protocol.replace(":", ""),
204
205
  host: urlObj.host,
205
- path: urlObj.pathname + urlObj.search
206
+ path: urlObj.pathname,
207
+ query: urlObj.search.replace(/^\?/, "")
206
208
  };
207
209
  } catch {
208
210
  return {
209
211
  protocol: "http",
210
212
  host: "unknown",
211
- path: url
213
+ path: url,
214
+ query: ""
212
215
  };
213
216
  }
214
217
  }