autotel-backends 2.9.1 → 2.11.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.
- package/dist/datadog.d.ts +0 -2
- package/dist/datadog.js +4 -5
- package/dist/datadog.js.map +1 -1
- package/dist/grafana.d.ts +86 -0
- package/dist/grafana.js +76 -0
- package/dist/grafana.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +74 -6
- package/dist/index.js.map +1 -1
- package/package.json +15 -17
- package/src/datadog.ts +5 -11
- package/src/grafana.ts +171 -0
- package/src/index.ts +2 -0
package/dist/datadog.d.ts
CHANGED
package/dist/datadog.js
CHANGED
|
@@ -79,17 +79,16 @@ function createDatadogConfig(config) {
|
|
|
79
79
|
cloudConfig.logRecordProcessors = logRecordProcessors;
|
|
80
80
|
} else {
|
|
81
81
|
try {
|
|
82
|
-
const
|
|
83
|
-
const { BatchLogRecordProcessor } =
|
|
82
|
+
const pkgRequire = createRequire(import.meta.url);
|
|
83
|
+
const { BatchLogRecordProcessor } = pkgRequire(
|
|
84
84
|
"@opentelemetry/sdk-logs"
|
|
85
85
|
);
|
|
86
|
-
const { OTLPLogExporter } =
|
|
86
|
+
const { OTLPLogExporter } = pkgRequire(
|
|
87
87
|
"@opentelemetry/exporter-logs-otlp-http"
|
|
88
88
|
);
|
|
89
89
|
cloudConfig.logRecordProcessors = [
|
|
90
90
|
new BatchLogRecordProcessor(
|
|
91
91
|
new OTLPLogExporter({
|
|
92
|
-
// Logs use /v1/logs path (SDK appends this to endpoint)
|
|
93
92
|
url: `${otlpEndpoint}/v1/logs`,
|
|
94
93
|
headers: {
|
|
95
94
|
"dd-api-key": apiKey
|
|
@@ -99,7 +98,7 @@ function createDatadogConfig(config) {
|
|
|
99
98
|
];
|
|
100
99
|
} catch {
|
|
101
100
|
throw new Error(
|
|
102
|
-
"Log export requires
|
|
101
|
+
"Log export requires @opentelemetry/sdk-logs and @opentelemetry/exporter-logs-otlp-http. Install them or set enableLogs: false."
|
|
103
102
|
);
|
|
104
103
|
}
|
|
105
104
|
}
|
package/dist/datadog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/datadog.ts"],"names":[],"mappings":"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","file":"datadog.js","sourcesContent":["/**\n * Datadog preset for autotel\n *\n * Provides a simplified configuration helper for Datadog integration\n * with best practices built-in.\n *\n * @example Direct cloud ingestion (serverless, edge)\n * ```typescript\n * import { init } from 'autotel';\n * import { createDatadogConfig } from 'autotel-backends/datadog';\n *\n * init(createDatadogConfig({\n * apiKey: process.env.DATADOG_API_KEY!,\n * service: 'my-lambda',\n * enableLogs: true,\n * }));\n * ```\n *\n * @example Local Datadog Agent (long-running services, Kubernetes)\n * ```typescript\n * import { init } from 'autotel';\n * import { createDatadogConfig } from 'autotel-backends/datadog';\n *\n * init(createDatadogConfig({\n * service: 'my-api',\n * useAgent: true, // No API key needed - Agent handles it\n * }));\n * ```\n */\n\nimport { createRequire } from 'node:module';\nimport type { AutotelConfig } from 'autotel';\nimport type { LogRecordProcessor } from '@opentelemetry/sdk-logs';\n\n/**\n * Datadog site regions\n */\nexport type DatadogSite =\n | 'datadoghq.com' // US1 (default)\n | 'datadoghq.eu' // EU\n | 'us3.datadoghq.com' // US3\n | 'us5.datadoghq.com' // US5\n | 'ap1.datadoghq.com' // AP1\n | 'ddog-gov.com'; // US1-FED\n\n/**\n * Configuration options for Datadog preset\n */\nexport interface DatadogPresetConfig {\n /**\n * Datadog API key (required for direct cloud ingestion).\n * Not needed if using local Datadog Agent (useAgent: true).\n *\n * Get your API key from:\n * https://app.datadoghq.com/organization-settings/api-keys\n */\n apiKey?: string;\n\n /**\n * Datadog site/region.\n * Determines which Datadog intake endpoint to use.\n *\n * @default 'datadoghq.com' (US1)\n */\n site?: DatadogSite;\n\n /**\n * Service name (required).\n * Appears in Datadog APM, Service Catalog, and all telemetry.\n */\n service: string;\n\n /**\n * Deployment environment (e.g., 'production', 'staging', 'development').\n * Used for environment filtering in Datadog.\n *\n * @default process.env.DD_ENV || process.env.NODE_ENV || 'development'\n */\n environment?: string;\n\n /**\n * Service version for deployment tracking.\n * Enables Deployment Tracking in Datadog APM.\n *\n * @default process.env.DD_VERSION || auto-detected from package.json\n */\n version?: string;\n\n /**\n * Enable log export to Datadog via OTLP.\n *\n * When enabled, this:\n * 1. Sets up OTel Logs SDK with OTLP exporter (for direct OTel logs API usage)\n * 2. Auto-configures OTEL_EXPORTER_OTLP_LOGS_* env vars for pino-opentelemetry-transport\n *\n * For Pino users: Just add pino-opentelemetry-transport to your logger config:\n * ```typescript\n * const logger = pino({\n * transport: {\n * targets: [\n * { target: 'pino-pretty' },\n * { target: 'pino-opentelemetry-transport' }, // Auto-configured!\n * ],\n * },\n * });\n * ```\n *\n * Requires peer dependencies: @opentelemetry/sdk-logs, @opentelemetry/exporter-logs-otlp-http\n *\n * @default false\n */\n enableLogs?: boolean;\n\n /**\n * Use local Datadog Agent instead of direct cloud ingestion.\n *\n * Benefits:\n * - Lower egress costs (Agent aggregates locally)\n * - Advanced features: trace-log correlation, multi-line logs, data scrubbing\n * - 500+ integrations for enrichment\n * - Infrastructure metrics collection\n *\n * Requires: Datadog Agent 7.35+ with OTLP enabled\n *\n * @default false\n */\n useAgent?: boolean;\n\n /**\n * Datadog Agent hostname (when useAgent: true).\n *\n * @default 'localhost'\n */\n agentHost?: string;\n\n /**\n * Datadog Agent OTLP port (when useAgent: true).\n *\n * @default 4318 (OTLP HTTP)\n */\n agentPort?: number;\n\n /**\n * Custom log record processors (advanced).\n * Overrides the default log processor if enableLogs is true.\n */\n logRecordProcessors?: LogRecordProcessor[];\n}\n\n/**\n * Create an autotel configuration optimized for Datadog.\n *\n * This preset handles:\n * - Proper OTLP endpoint configuration (Agent vs direct ingestion)\n * - Direct: https://otlp.{site} → SDK appends /v1/traces, /v1/metrics, /v1/logs\n * - Agent: http://localhost:4318 (default)\n * - Datadog API key authentication headers (direct ingestion only)\n * - Unified service tagging (service, env, version)\n * - Resource attribute best practices\n * - Optional log export configuration\n *\n * @param config - Datadog-specific configuration options\n * @returns AutotelConfig ready to pass to init()\n *\n * @example Simple cloud ingestion\n * ```typescript\n * init(createDatadogConfig({\n * apiKey: process.env.DATADOG_API_KEY!,\n * service: 'my-app',\n * }));\n * ```\n *\n * @example With logs and custom environment\n * ```typescript\n * init(createDatadogConfig({\n * apiKey: process.env.DATADOG_API_KEY!,\n * service: 'my-app',\n * environment: 'production',\n * version: '2.1.0',\n * enableLogs: true,\n * }));\n * ```\n *\n * @example Using local Datadog Agent\n * ```typescript\n * init(createDatadogConfig({\n * service: 'my-api',\n * useAgent: true,\n * agentHost: 'datadog-agent.default.svc.cluster.local', // Kubernetes\n * }));\n * ```\n */\nexport function createDatadogConfig(\n config: DatadogPresetConfig,\n): AutotelConfig {\n const {\n apiKey,\n site = 'datadoghq.com',\n service,\n environment,\n version,\n enableLogs = false,\n useAgent = false,\n agentHost = 'localhost',\n agentPort = 4318,\n logRecordProcessors,\n } = config;\n\n // Validation: API key required for direct ingestion\n if (!useAgent && !apiKey) {\n throw new Error(\n 'Datadog API key is required for direct cloud ingestion. ' +\n 'Either provide apiKey or set useAgent: true to use local Datadog Agent.',\n );\n }\n\n const baseConfig: AutotelConfig = {\n service,\n environment,\n version,\n };\n\n // Local Datadog Agent configuration\n if (useAgent) {\n const agentEndpoint = `http://${agentHost}:${agentPort}`;\n\n // Auto-configure env vars for pino-opentelemetry-transport in agent mode\n if (enableLogs) {\n const logsEndpoint = `http://${agentHost}:${agentPort}/v1/logs`;\n\n if (!process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = logsEndpoint;\n }\n\n if (!process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL = 'http/protobuf';\n }\n\n // No API key header needed for agent mode - Agent handles authentication\n\n const resourceAttrs = [\n `service.name=${service}`,\n environment ? `deployment.environment=${environment}` : null,\n version ? `service.version=${version}` : null,\n ]\n .filter(Boolean)\n .join(',');\n\n if (!process.env.OTEL_RESOURCE_ATTRIBUTES) {\n process.env.OTEL_RESOURCE_ATTRIBUTES = resourceAttrs;\n }\n }\n\n return {\n ...baseConfig,\n endpoint: agentEndpoint,\n // No API key or headers needed - Agent handles authentication\n };\n }\n\n // Direct cloud ingestion configuration\n // Datadog OTLP endpoint: base URL without path (SDK appends /v1/traces, /v1/metrics, /v1/logs)\n const otlpEndpoint = `https://otlp.${site}`;\n const authHeaders = `dd-api-key=${apiKey}`;\n\n const cloudConfig: AutotelConfig = {\n ...baseConfig,\n endpoint: otlpEndpoint,\n headers: authHeaders,\n };\n\n // Add log export if enabled\n if (enableLogs) {\n // Auto-configure env vars for pino-opentelemetry-transport and other OTel log transports\n // These are read by pino-opentelemetry-transport, otlp-logger, and similar libraries\n const logsEndpoint = useAgent\n ? `http://${agentHost}:${agentPort}/v1/logs`\n : `https://otlp.${site}/v1/logs`;\n\n // Only set if not already configured (allow user override)\n if (!process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = logsEndpoint;\n }\n\n if (!process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL = 'http/protobuf';\n }\n\n // Only set API key header for direct cloud ingestion (not agent mode)\n if (!useAgent && apiKey && !process.env.OTEL_EXPORTER_OTLP_LOGS_HEADERS) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_HEADERS = `dd-api-key=${apiKey}`;\n }\n\n // Set resource attributes for service identification\n const resourceAttrs = [\n `service.name=${service}`,\n environment ? `deployment.environment=${environment}` : null,\n version ? `service.version=${version}` : null,\n ]\n .filter(Boolean)\n .join(',');\n\n if (!process.env.OTEL_RESOURCE_ATTRIBUTES) {\n process.env.OTEL_RESOURCE_ATTRIBUTES = resourceAttrs;\n }\n\n if (logRecordProcessors) {\n // Use custom processors if provided\n cloudConfig.logRecordProcessors = logRecordProcessors;\n } else {\n // Create default OTLP log exporter\n try {\n // Lazy-load to preserve optional peer dependencies\n // Use createRequire to resolve from user's project directory\n const userRequire = createRequire(process.cwd() + '/package.json');\n\n const { BatchLogRecordProcessor } = userRequire(\n '@opentelemetry/sdk-logs',\n );\n const { OTLPLogExporter } = userRequire(\n '@opentelemetry/exporter-logs-otlp-http',\n );\n\n cloudConfig.logRecordProcessors = [\n new BatchLogRecordProcessor(\n new OTLPLogExporter({\n // Logs use /v1/logs path (SDK appends this to endpoint)\n url: `${otlpEndpoint}/v1/logs`,\n headers: {\n 'dd-api-key': apiKey,\n },\n }),\n ),\n ];\n } catch {\n throw new Error(\n 'Log export requires peer dependencies: @opentelemetry/sdk-logs and @opentelemetry/exporter-logs-otlp-http. ' +\n 'Install them with: npm install @opentelemetry/sdk-logs @opentelemetry/exporter-logs-otlp-http',\n );\n }\n }\n }\n\n return cloudConfig;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/datadog.ts"],"names":[],"mappings":"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","file":"datadog.js","sourcesContent":["/**\n * Datadog preset for autotel\n *\n * Provides a simplified configuration helper for Datadog integration\n * with best practices built-in.\n *\n * @example Direct cloud ingestion (serverless, edge)\n * ```typescript\n * import { init } from 'autotel';\n * import { createDatadogConfig } from 'autotel-backends/datadog';\n *\n * init(createDatadogConfig({\n * apiKey: process.env.DATADOG_API_KEY!,\n * service: 'my-lambda',\n * enableLogs: true,\n * }));\n * ```\n *\n * @example Local Datadog Agent (long-running services, Kubernetes)\n * ```typescript\n * import { init } from 'autotel';\n * import { createDatadogConfig } from 'autotel-backends/datadog';\n *\n * init(createDatadogConfig({\n * service: 'my-api',\n * useAgent: true, // No API key needed - Agent handles it\n * }));\n * ```\n */\n\nimport { createRequire } from 'node:module';\nimport type { AutotelConfig } from 'autotel';\nimport type { LogRecordProcessor } from '@opentelemetry/sdk-logs';\n\n/**\n * Datadog site regions\n */\nexport type DatadogSite =\n | 'datadoghq.com' // US1 (default)\n | 'datadoghq.eu' // EU\n | 'us3.datadoghq.com' // US3\n | 'us5.datadoghq.com' // US5\n | 'ap1.datadoghq.com' // AP1\n | 'ddog-gov.com'; // US1-FED\n\n/**\n * Configuration options for Datadog preset\n */\nexport interface DatadogPresetConfig {\n /**\n * Datadog API key (required for direct cloud ingestion).\n * Not needed if using local Datadog Agent (useAgent: true).\n *\n * Get your API key from:\n * https://app.datadoghq.com/organization-settings/api-keys\n */\n apiKey?: string;\n\n /**\n * Datadog site/region.\n * Determines which Datadog intake endpoint to use.\n *\n * @default 'datadoghq.com' (US1)\n */\n site?: DatadogSite;\n\n /**\n * Service name (required).\n * Appears in Datadog APM, Service Catalog, and all telemetry.\n */\n service: string;\n\n /**\n * Deployment environment (e.g., 'production', 'staging', 'development').\n * Used for environment filtering in Datadog.\n *\n * @default process.env.DD_ENV || process.env.NODE_ENV || 'development'\n */\n environment?: string;\n\n /**\n * Service version for deployment tracking.\n * Enables Deployment Tracking in Datadog APM.\n *\n * @default process.env.DD_VERSION || auto-detected from package.json\n */\n version?: string;\n\n /**\n * Enable log export to Datadog via OTLP.\n *\n * When enabled, this:\n * 1. Sets up OTel Logs SDK with OTLP exporter (for direct OTel logs API usage)\n * 2. Auto-configures OTEL_EXPORTER_OTLP_LOGS_* env vars for pino-opentelemetry-transport\n *\n * For Pino users: Just add pino-opentelemetry-transport to your logger config:\n * ```typescript\n * const logger = pino({\n * transport: {\n * targets: [\n * { target: 'pino-pretty' },\n * { target: 'pino-opentelemetry-transport' }, // Auto-configured!\n * ],\n * },\n * });\n * ```\n *\n * @default false\n */\n enableLogs?: boolean;\n\n /**\n * Use local Datadog Agent instead of direct cloud ingestion.\n *\n * Benefits:\n * - Lower egress costs (Agent aggregates locally)\n * - Advanced features: trace-log correlation, multi-line logs, data scrubbing\n * - 500+ integrations for enrichment\n * - Infrastructure metrics collection\n *\n * Requires: Datadog Agent 7.35+ with OTLP enabled\n *\n * @default false\n */\n useAgent?: boolean;\n\n /**\n * Datadog Agent hostname (when useAgent: true).\n *\n * @default 'localhost'\n */\n agentHost?: string;\n\n /**\n * Datadog Agent OTLP port (when useAgent: true).\n *\n * @default 4318 (OTLP HTTP)\n */\n agentPort?: number;\n\n /**\n * Custom log record processors (advanced).\n * Overrides the default log processor if enableLogs is true.\n */\n logRecordProcessors?: LogRecordProcessor[];\n}\n\n/**\n * Create an autotel configuration optimized for Datadog.\n *\n * This preset handles:\n * - Proper OTLP endpoint configuration (Agent vs direct ingestion)\n * - Direct: https://otlp.{site} → SDK appends /v1/traces, /v1/metrics, /v1/logs\n * - Agent: http://localhost:4318 (default)\n * - Datadog API key authentication headers (direct ingestion only)\n * - Unified service tagging (service, env, version)\n * - Resource attribute best practices\n * - Optional log export configuration\n *\n * @param config - Datadog-specific configuration options\n * @returns AutotelConfig ready to pass to init()\n *\n * @example Simple cloud ingestion\n * ```typescript\n * init(createDatadogConfig({\n * apiKey: process.env.DATADOG_API_KEY!,\n * service: 'my-app',\n * }));\n * ```\n *\n * @example With logs and custom environment\n * ```typescript\n * init(createDatadogConfig({\n * apiKey: process.env.DATADOG_API_KEY!,\n * service: 'my-app',\n * environment: 'production',\n * version: '2.1.0',\n * enableLogs: true,\n * }));\n * ```\n *\n * @example Using local Datadog Agent\n * ```typescript\n * init(createDatadogConfig({\n * service: 'my-api',\n * useAgent: true,\n * agentHost: 'datadog-agent.default.svc.cluster.local', // Kubernetes\n * }));\n * ```\n */\nexport function createDatadogConfig(\n config: DatadogPresetConfig,\n): AutotelConfig {\n const {\n apiKey,\n site = 'datadoghq.com',\n service,\n environment,\n version,\n enableLogs = false,\n useAgent = false,\n agentHost = 'localhost',\n agentPort = 4318,\n logRecordProcessors,\n } = config;\n\n // Validation: API key required for direct ingestion\n if (!useAgent && !apiKey) {\n throw new Error(\n 'Datadog API key is required for direct cloud ingestion. ' +\n 'Either provide apiKey or set useAgent: true to use local Datadog Agent.',\n );\n }\n\n const baseConfig: AutotelConfig = {\n service,\n environment,\n version,\n };\n\n // Local Datadog Agent configuration\n if (useAgent) {\n const agentEndpoint = `http://${agentHost}:${agentPort}`;\n\n // Auto-configure env vars for pino-opentelemetry-transport in agent mode\n if (enableLogs) {\n const logsEndpoint = `http://${agentHost}:${agentPort}/v1/logs`;\n\n if (!process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = logsEndpoint;\n }\n\n if (!process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL = 'http/protobuf';\n }\n\n // No API key header needed for agent mode - Agent handles authentication\n\n const resourceAttrs = [\n `service.name=${service}`,\n environment ? `deployment.environment=${environment}` : null,\n version ? `service.version=${version}` : null,\n ]\n .filter(Boolean)\n .join(',');\n\n if (!process.env.OTEL_RESOURCE_ATTRIBUTES) {\n process.env.OTEL_RESOURCE_ATTRIBUTES = resourceAttrs;\n }\n }\n\n return {\n ...baseConfig,\n endpoint: agentEndpoint,\n // No API key or headers needed - Agent handles authentication\n };\n }\n\n // Direct cloud ingestion configuration\n // Datadog OTLP endpoint: base URL without path (SDK appends /v1/traces, /v1/metrics, /v1/logs)\n const otlpEndpoint = `https://otlp.${site}`;\n const authHeaders = `dd-api-key=${apiKey}`;\n\n const cloudConfig: AutotelConfig = {\n ...baseConfig,\n endpoint: otlpEndpoint,\n headers: authHeaders,\n };\n\n // Add log export if enabled\n if (enableLogs) {\n // Auto-configure env vars for pino-opentelemetry-transport and other OTel log transports\n // These are read by pino-opentelemetry-transport, otlp-logger, and similar libraries\n const logsEndpoint = useAgent\n ? `http://${agentHost}:${agentPort}/v1/logs`\n : `https://otlp.${site}/v1/logs`;\n\n // Only set if not already configured (allow user override)\n if (!process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = logsEndpoint;\n }\n\n if (!process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL = 'http/protobuf';\n }\n\n // Only set API key header for direct cloud ingestion (not agent mode)\n if (!useAgent && apiKey && !process.env.OTEL_EXPORTER_OTLP_LOGS_HEADERS) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_HEADERS = `dd-api-key=${apiKey}`;\n }\n\n // Set resource attributes for service identification\n const resourceAttrs = [\n `service.name=${service}`,\n environment ? `deployment.environment=${environment}` : null,\n version ? `service.version=${version}` : null,\n ]\n .filter(Boolean)\n .join(',');\n\n if (!process.env.OTEL_RESOURCE_ATTRIBUTES) {\n process.env.OTEL_RESOURCE_ATTRIBUTES = resourceAttrs;\n }\n\n if (logRecordProcessors) {\n // Use custom processors if provided\n cloudConfig.logRecordProcessors = logRecordProcessors;\n } else {\n // Create default OTLP log exporter\n try {\n const pkgRequire = createRequire(import.meta.url);\n const { BatchLogRecordProcessor } = pkgRequire(\n '@opentelemetry/sdk-logs',\n );\n const { OTLPLogExporter } = pkgRequire(\n '@opentelemetry/exporter-logs-otlp-http',\n );\n\n cloudConfig.logRecordProcessors = [\n new BatchLogRecordProcessor(\n new OTLPLogExporter({\n url: `${otlpEndpoint}/v1/logs`,\n headers: {\n 'dd-api-key': apiKey,\n },\n }),\n ),\n ];\n } catch {\n throw new Error(\n 'Log export requires @opentelemetry/sdk-logs and @opentelemetry/exporter-logs-otlp-http. ' +\n 'Install them or set enableLogs: false.',\n );\n }\n }\n }\n\n return cloudConfig;\n}\n"]}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { AutotelConfig } from 'autotel';
|
|
2
|
+
import { LogRecordProcessor } from '@opentelemetry/sdk-logs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Grafana Cloud preset for autotel
|
|
6
|
+
*
|
|
7
|
+
* Provides a simplified configuration helper for sending traces, metrics,
|
|
8
|
+
* and logs to Grafana Cloud via the OTLP gateway.
|
|
9
|
+
*
|
|
10
|
+
* Get your endpoint and headers from:
|
|
11
|
+
* Grafana Cloud Portal → your stack → Connections → OpenTelemetry → Configure
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { init } from 'autotel';
|
|
16
|
+
* import { createGrafanaConfig } from 'autotel-backends/grafana';
|
|
17
|
+
*
|
|
18
|
+
* init(createGrafanaConfig({
|
|
19
|
+
* endpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT!,
|
|
20
|
+
* headers: process.env.OTEL_EXPORTER_OTLP_HEADERS,
|
|
21
|
+
* service: 'my-app',
|
|
22
|
+
* enableLogs: true,
|
|
23
|
+
* }));
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Configuration options for Grafana Cloud preset
|
|
29
|
+
*/
|
|
30
|
+
interface GrafanaPresetConfig {
|
|
31
|
+
/**
|
|
32
|
+
* OTLP gateway endpoint (required).
|
|
33
|
+
* From Grafana Cloud: Stack → Connections → OpenTelemetry → Configure.
|
|
34
|
+
* Example: https://otlp-gateway-prod-gb-south-1.grafana.net/otlp
|
|
35
|
+
*/
|
|
36
|
+
endpoint: string;
|
|
37
|
+
/**
|
|
38
|
+
* OTLP authentication headers.
|
|
39
|
+
* From the same Configure tile; usually Basic auth.
|
|
40
|
+
* Example: "Authorization=Basic%20BASE64_INSTANCE_ID_AND_TOKEN"
|
|
41
|
+
* or object: { Authorization: 'Basic ...' }
|
|
42
|
+
*/
|
|
43
|
+
headers?: string | Record<string, string>;
|
|
44
|
+
/**
|
|
45
|
+
* Service name (required).
|
|
46
|
+
* Appears in Tempo, Mimir, and Loki as service_name.
|
|
47
|
+
*/
|
|
48
|
+
service: string;
|
|
49
|
+
/**
|
|
50
|
+
* Deployment environment (e.g. 'production', 'staging').
|
|
51
|
+
*
|
|
52
|
+
* @default process.env.NODE_ENV || 'development'
|
|
53
|
+
*/
|
|
54
|
+
environment?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Service version for deployment tracking.
|
|
57
|
+
*
|
|
58
|
+
* @default process.env.OTEL_SERVICE_VERSION
|
|
59
|
+
*/
|
|
60
|
+
version?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Enable log export to Grafana Cloud (Loki) via OTLP.
|
|
63
|
+
* When true, configures logRecordProcessors so OTel Logs API records are exported.
|
|
64
|
+
*
|
|
65
|
+
* @default true
|
|
66
|
+
*/
|
|
67
|
+
enableLogs?: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Custom log record processors (advanced).
|
|
70
|
+
* Overrides the default OTLP log processor when enableLogs is true.
|
|
71
|
+
*/
|
|
72
|
+
logRecordProcessors?: LogRecordProcessor[];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Create an autotel configuration for Grafana Cloud OTLP.
|
|
76
|
+
*
|
|
77
|
+
* Sends traces (Tempo), metrics (Mimir), and optionally logs (Loki) to the
|
|
78
|
+
* Grafana Cloud OTLP gateway. Endpoint and headers come from the stack's
|
|
79
|
+
* Connections → OpenTelemetry → Configure tile.
|
|
80
|
+
*
|
|
81
|
+
* @param config - Grafana Cloud configuration options
|
|
82
|
+
* @returns AutotelConfig ready to pass to init()
|
|
83
|
+
*/
|
|
84
|
+
declare function createGrafanaConfig(config: GrafanaPresetConfig): AutotelConfig;
|
|
85
|
+
|
|
86
|
+
export { type GrafanaPresetConfig, createGrafanaConfig };
|
package/dist/grafana.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { createRequire } from 'module';
|
|
2
|
+
|
|
3
|
+
// src/grafana.ts
|
|
4
|
+
function normalizeHeaders(headers) {
|
|
5
|
+
if (!headers) return void 0;
|
|
6
|
+
if (typeof headers === "object") return headers;
|
|
7
|
+
const out = {};
|
|
8
|
+
for (const pair of headers.split(",")) {
|
|
9
|
+
const [key, ...valueParts] = pair.split("=");
|
|
10
|
+
if (key && valueParts.length > 0) {
|
|
11
|
+
let value = valueParts.join("=").trim();
|
|
12
|
+
value = value.replaceAll("%20", " ");
|
|
13
|
+
out[key.trim()] = value;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
17
|
+
}
|
|
18
|
+
function createGrafanaConfig(config) {
|
|
19
|
+
const {
|
|
20
|
+
endpoint,
|
|
21
|
+
headers: headersInput,
|
|
22
|
+
service,
|
|
23
|
+
environment,
|
|
24
|
+
version,
|
|
25
|
+
enableLogs = true,
|
|
26
|
+
logRecordProcessors
|
|
27
|
+
} = config;
|
|
28
|
+
if (!endpoint) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
"Grafana Cloud endpoint is required. Get it from: Grafana Cloud \u2192 your stack \u2192 Connections \u2192 OpenTelemetry \u2192 Configure"
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
const headers = normalizeHeaders(headersInput);
|
|
34
|
+
const base = endpoint.replace(/\/v1\/(traces|metrics|logs)$/, "");
|
|
35
|
+
const logsUrl = `${base}${base.endsWith("/") ? "" : "/"}v1/logs`;
|
|
36
|
+
const result = {
|
|
37
|
+
service,
|
|
38
|
+
environment,
|
|
39
|
+
version,
|
|
40
|
+
endpoint,
|
|
41
|
+
headers,
|
|
42
|
+
metrics: true
|
|
43
|
+
};
|
|
44
|
+
if (enableLogs) {
|
|
45
|
+
if (logRecordProcessors) {
|
|
46
|
+
result.logRecordProcessors = logRecordProcessors;
|
|
47
|
+
} else {
|
|
48
|
+
try {
|
|
49
|
+
const pkgRequire = createRequire(import.meta.url);
|
|
50
|
+
const { BatchLogRecordProcessor } = pkgRequire(
|
|
51
|
+
"@opentelemetry/sdk-logs"
|
|
52
|
+
);
|
|
53
|
+
const { OTLPLogExporter } = pkgRequire(
|
|
54
|
+
"@opentelemetry/exporter-logs-otlp-http"
|
|
55
|
+
);
|
|
56
|
+
result.logRecordProcessors = [
|
|
57
|
+
new BatchLogRecordProcessor(
|
|
58
|
+
new OTLPLogExporter({
|
|
59
|
+
url: logsUrl,
|
|
60
|
+
headers
|
|
61
|
+
})
|
|
62
|
+
)
|
|
63
|
+
];
|
|
64
|
+
} catch {
|
|
65
|
+
throw new Error(
|
|
66
|
+
"Log export requires @opentelemetry/sdk-logs and @opentelemetry/exporter-logs-otlp-http. Install them or set enableLogs: false."
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export { createGrafanaConfig };
|
|
75
|
+
//# sourceMappingURL=grafana.js.map
|
|
76
|
+
//# sourceMappingURL=grafana.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/grafana.ts"],"names":[],"mappings":";;;AAiFA,SAAS,iBACP,OAAA,EACoC;AACpC,EAAA,IAAI,CAAC,SAAS,OAAO,MAAA;AACrB,EAAA,IAAI,OAAO,OAAA,KAAY,QAAA,EAAU,OAAO,OAAA;AACxC,EAAA,MAAM,MAA8B,EAAC;AACrC,EAAA,KAAA,MAAW,IAAA,IAAQ,OAAA,CAAQ,KAAA,CAAM,GAAG,CAAA,EAAG;AACrC,IAAA,MAAM,CAAC,GAAA,EAAK,GAAG,UAAU,CAAA,GAAI,IAAA,CAAK,MAAM,GAAG,CAAA;AAC3C,IAAA,IAAI,GAAA,IAAO,UAAA,CAAW,MAAA,GAAS,CAAA,EAAG;AAChC,MAAA,IAAI,KAAA,GAAQ,UAAA,CAAW,IAAA,CAAK,GAAG,EAAE,IAAA,EAAK;AACtC,MAAA,KAAA,GAAQ,KAAA,CAAM,UAAA,CAAW,KAAA,EAAO,GAAG,CAAA;AACnC,MAAA,GAAA,CAAI,GAAA,CAAI,IAAA,EAAM,CAAA,GAAI,KAAA;AAAA,IACpB;AAAA,EACF;AACA,EAAA,OAAO,OAAO,IAAA,CAAK,GAAG,CAAA,CAAE,MAAA,GAAS,IAAI,GAAA,GAAM,MAAA;AAC7C;AAYO,SAAS,oBACd,MAAA,EACe;AACf,EAAA,MAAM;AAAA,IACJ,QAAA;AAAA,IACA,OAAA,EAAS,YAAA;AAAA,IACT,OAAA;AAAA,IACA,WAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA,GAAa,IAAA;AAAA,IACb;AAAA,GACF,GAAI,MAAA;AAEJ,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,OAAA,GAAU,iBAAiB,YAAY,CAAA;AAC7C,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,OAAA,CAAQ,8BAAA,EAAgC,EAAE,CAAA;AAChE,EAAA,MAAM,OAAA,GAAU,GAAG,IAAI,CAAA,EAAG,KAAK,QAAA,CAAS,GAAG,CAAA,GAAI,EAAA,GAAK,GAAG,CAAA,OAAA,CAAA;AAEvD,EAAA,MAAM,MAAA,GAAwB;AAAA,IAC5B,OAAA;AAAA,IACA,WAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA,EAAS;AAAA,GACX;AAEA,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,IAAI,mBAAA,EAAqB;AACvB,MAAA,MAAA,CAAO,mBAAA,GAAsB,mBAAA;AAAA,IAC/B,CAAA,MAAO;AACL,MAAA,IAAI;AACF,QAAA,MAAM,UAAA,GAAa,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA;AAChD,QAAA,MAAM,EAAE,yBAAwB,GAAI,UAAA;AAAA,UAClC;AAAA,SACF;AACA,QAAA,MAAM,EAAE,iBAAgB,GAAI,UAAA;AAAA,UAC1B;AAAA,SACF;AACA,QAAA,MAAA,CAAO,mBAAA,GAAsB;AAAA,UAC3B,IAAI,uBAAA;AAAA,YACF,IAAI,eAAA,CAAgB;AAAA,cAClB,GAAA,EAAK,OAAA;AAAA,cACL;AAAA,aACD;AAAA;AACH,SACF;AAAA,MACF,CAAA,CAAA,MAAQ;AACN,QAAA,MAAM,IAAI,KAAA;AAAA,UACR;AAAA,SAEF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,MAAA;AACT","file":"grafana.js","sourcesContent":["/**\n * Grafana Cloud preset for autotel\n *\n * Provides a simplified configuration helper for sending traces, metrics,\n * and logs to Grafana Cloud via the OTLP gateway.\n *\n * Get your endpoint and headers from:\n * Grafana Cloud Portal → your stack → Connections → OpenTelemetry → Configure\n *\n * @example\n * ```typescript\n * import { init } from 'autotel';\n * import { createGrafanaConfig } from 'autotel-backends/grafana';\n *\n * init(createGrafanaConfig({\n * endpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT!,\n * headers: process.env.OTEL_EXPORTER_OTLP_HEADERS,\n * service: 'my-app',\n * enableLogs: true,\n * }));\n * ```\n */\n\nimport { createRequire } from 'node:module';\nimport type { AutotelConfig } from 'autotel';\nimport type { LogRecordProcessor } from '@opentelemetry/sdk-logs';\n\n/**\n * Configuration options for Grafana Cloud preset\n */\nexport interface GrafanaPresetConfig {\n /**\n * OTLP gateway endpoint (required).\n * From Grafana Cloud: Stack → Connections → OpenTelemetry → Configure.\n * Example: https://otlp-gateway-prod-gb-south-1.grafana.net/otlp\n */\n endpoint: string;\n\n /**\n * OTLP authentication headers.\n * From the same Configure tile; usually Basic auth.\n * Example: \"Authorization=Basic%20BASE64_INSTANCE_ID_AND_TOKEN\"\n * or object: { Authorization: 'Basic ...' }\n */\n headers?: string | Record<string, string>;\n\n /**\n * Service name (required).\n * Appears in Tempo, Mimir, and Loki as service_name.\n */\n service: string;\n\n /**\n * Deployment environment (e.g. 'production', 'staging').\n *\n * @default process.env.NODE_ENV || 'development'\n */\n environment?: string;\n\n /**\n * Service version for deployment tracking.\n *\n * @default process.env.OTEL_SERVICE_VERSION\n */\n version?: string;\n\n /**\n * Enable log export to Grafana Cloud (Loki) via OTLP.\n * When true, configures logRecordProcessors so OTel Logs API records are exported.\n *\n * @default true\n */\n enableLogs?: boolean;\n\n /**\n * Custom log record processors (advanced).\n * Overrides the default OTLP log processor when enableLogs is true.\n */\n logRecordProcessors?: LogRecordProcessor[];\n}\n\nfunction normalizeHeaders(\n headers: string | Record<string, string> | undefined,\n): Record<string, string> | undefined {\n if (!headers) return undefined;\n if (typeof headers === 'object') return headers;\n const out: Record<string, string> = {};\n for (const pair of headers.split(',')) {\n const [key, ...valueParts] = pair.split('=');\n if (key && valueParts.length > 0) {\n let value = valueParts.join('=').trim();\n value = value.replaceAll('%20', ' ');\n out[key.trim()] = value;\n }\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\n/**\n * Create an autotel configuration for Grafana Cloud OTLP.\n *\n * Sends traces (Tempo), metrics (Mimir), and optionally logs (Loki) to the\n * Grafana Cloud OTLP gateway. Endpoint and headers come from the stack's\n * Connections → OpenTelemetry → Configure tile.\n *\n * @param config - Grafana Cloud configuration options\n * @returns AutotelConfig ready to pass to init()\n */\nexport function createGrafanaConfig(\n config: GrafanaPresetConfig,\n): AutotelConfig {\n const {\n endpoint,\n headers: headersInput,\n service,\n environment,\n version,\n enableLogs = true,\n logRecordProcessors,\n } = config;\n\n if (!endpoint) {\n throw new Error(\n 'Grafana Cloud endpoint is required. Get it from: Grafana Cloud → your stack → Connections → OpenTelemetry → Configure',\n );\n }\n\n const headers = normalizeHeaders(headersInput);\n const base = endpoint.replace(/\\/v1\\/(traces|metrics|logs)$/, '');\n const logsUrl = `${base}${base.endsWith('/') ? '' : '/'}v1/logs`;\n\n const result: AutotelConfig = {\n service,\n environment,\n version,\n endpoint,\n headers,\n metrics: true,\n };\n\n if (enableLogs) {\n if (logRecordProcessors) {\n result.logRecordProcessors = logRecordProcessors;\n } else {\n try {\n const pkgRequire = createRequire(import.meta.url);\n const { BatchLogRecordProcessor } = pkgRequire(\n '@opentelemetry/sdk-logs',\n );\n const { OTLPLogExporter } = pkgRequire(\n '@opentelemetry/exporter-logs-otlp-http',\n );\n result.logRecordProcessors = [\n new BatchLogRecordProcessor(\n new OTLPLogExporter({\n url: logsUrl,\n headers,\n }),\n ),\n ];\n } catch {\n throw new Error(\n 'Log export requires @opentelemetry/sdk-logs and @opentelemetry/exporter-logs-otlp-http. ' +\n 'Install them or set enableLogs: false.',\n );\n }\n }\n }\n\n return result;\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { HoneycombPresetConfig, createHoneycombConfig } from './honeycomb.js';
|
|
2
2
|
export { DatadogPresetConfig, DatadogSite, createDatadogConfig } from './datadog.js';
|
|
3
3
|
export { GoogleCloudPresetConfig, createGoogleCloudConfig } from './google-cloud.js';
|
|
4
|
+
export { GrafanaPresetConfig, createGrafanaConfig } from './grafana.js';
|
|
4
5
|
import 'autotel';
|
|
5
6
|
import '@opentelemetry/sdk-logs';
|
package/dist/index.js
CHANGED
|
@@ -113,17 +113,16 @@ function createDatadogConfig(config) {
|
|
|
113
113
|
cloudConfig.logRecordProcessors = logRecordProcessors;
|
|
114
114
|
} else {
|
|
115
115
|
try {
|
|
116
|
-
const
|
|
117
|
-
const { BatchLogRecordProcessor } =
|
|
116
|
+
const pkgRequire = createRequire(import.meta.url);
|
|
117
|
+
const { BatchLogRecordProcessor } = pkgRequire(
|
|
118
118
|
"@opentelemetry/sdk-logs"
|
|
119
119
|
);
|
|
120
|
-
const { OTLPLogExporter } =
|
|
120
|
+
const { OTLPLogExporter } = pkgRequire(
|
|
121
121
|
"@opentelemetry/exporter-logs-otlp-http"
|
|
122
122
|
);
|
|
123
123
|
cloudConfig.logRecordProcessors = [
|
|
124
124
|
new BatchLogRecordProcessor(
|
|
125
125
|
new OTLPLogExporter({
|
|
126
|
-
// Logs use /v1/logs path (SDK appends this to endpoint)
|
|
127
126
|
url: `${otlpEndpoint}/v1/logs`,
|
|
128
127
|
headers: {
|
|
129
128
|
"dd-api-key": apiKey
|
|
@@ -133,7 +132,7 @@ function createDatadogConfig(config) {
|
|
|
133
132
|
];
|
|
134
133
|
} catch {
|
|
135
134
|
throw new Error(
|
|
136
|
-
"Log export requires
|
|
135
|
+
"Log export requires @opentelemetry/sdk-logs and @opentelemetry/exporter-logs-otlp-http. Install them or set enableLogs: false."
|
|
137
136
|
);
|
|
138
137
|
}
|
|
139
138
|
}
|
|
@@ -247,7 +246,76 @@ var GcpAuthSpanExporter = class {
|
|
|
247
246
|
return Promise.resolve();
|
|
248
247
|
}
|
|
249
248
|
};
|
|
249
|
+
function normalizeHeaders(headers) {
|
|
250
|
+
if (!headers) return void 0;
|
|
251
|
+
if (typeof headers === "object") return headers;
|
|
252
|
+
const out = {};
|
|
253
|
+
for (const pair of headers.split(",")) {
|
|
254
|
+
const [key, ...valueParts] = pair.split("=");
|
|
255
|
+
if (key && valueParts.length > 0) {
|
|
256
|
+
let value = valueParts.join("=").trim();
|
|
257
|
+
value = value.replaceAll("%20", " ");
|
|
258
|
+
out[key.trim()] = value;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return Object.keys(out).length > 0 ? out : void 0;
|
|
262
|
+
}
|
|
263
|
+
function createGrafanaConfig(config) {
|
|
264
|
+
const {
|
|
265
|
+
endpoint,
|
|
266
|
+
headers: headersInput,
|
|
267
|
+
service,
|
|
268
|
+
environment,
|
|
269
|
+
version,
|
|
270
|
+
enableLogs = true,
|
|
271
|
+
logRecordProcessors
|
|
272
|
+
} = config;
|
|
273
|
+
if (!endpoint) {
|
|
274
|
+
throw new Error(
|
|
275
|
+
"Grafana Cloud endpoint is required. Get it from: Grafana Cloud \u2192 your stack \u2192 Connections \u2192 OpenTelemetry \u2192 Configure"
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
const headers = normalizeHeaders(headersInput);
|
|
279
|
+
const base = endpoint.replace(/\/v1\/(traces|metrics|logs)$/, "");
|
|
280
|
+
const logsUrl = `${base}${base.endsWith("/") ? "" : "/"}v1/logs`;
|
|
281
|
+
const result = {
|
|
282
|
+
service,
|
|
283
|
+
environment,
|
|
284
|
+
version,
|
|
285
|
+
endpoint,
|
|
286
|
+
headers,
|
|
287
|
+
metrics: true
|
|
288
|
+
};
|
|
289
|
+
if (enableLogs) {
|
|
290
|
+
if (logRecordProcessors) {
|
|
291
|
+
result.logRecordProcessors = logRecordProcessors;
|
|
292
|
+
} else {
|
|
293
|
+
try {
|
|
294
|
+
const pkgRequire = createRequire(import.meta.url);
|
|
295
|
+
const { BatchLogRecordProcessor } = pkgRequire(
|
|
296
|
+
"@opentelemetry/sdk-logs"
|
|
297
|
+
);
|
|
298
|
+
const { OTLPLogExporter } = pkgRequire(
|
|
299
|
+
"@opentelemetry/exporter-logs-otlp-http"
|
|
300
|
+
);
|
|
301
|
+
result.logRecordProcessors = [
|
|
302
|
+
new BatchLogRecordProcessor(
|
|
303
|
+
new OTLPLogExporter({
|
|
304
|
+
url: logsUrl,
|
|
305
|
+
headers
|
|
306
|
+
})
|
|
307
|
+
)
|
|
308
|
+
];
|
|
309
|
+
} catch {
|
|
310
|
+
throw new Error(
|
|
311
|
+
"Log export requires @opentelemetry/sdk-logs and @opentelemetry/exporter-logs-otlp-http. Install them or set enableLogs: false."
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return result;
|
|
317
|
+
}
|
|
250
318
|
|
|
251
|
-
export { createDatadogConfig, createGoogleCloudConfig, createHoneycombConfig };
|
|
319
|
+
export { createDatadogConfig, createGoogleCloudConfig, createGrafanaConfig, createHoneycombConfig };
|
|
252
320
|
//# sourceMappingURL=index.js.map
|
|
253
321
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/honeycomb.ts","../src/datadog.ts","../src/google-cloud.ts"],"names":["createRequire"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Honeycomb preset for autotel\n *\n * Provides a simplified configuration helper for Honeycomb integration\n * with best practices built-in.\n *\n * @example Using Honeycomb with API key\n * ```typescript\n * import { init } from 'autotel';\n * import { createHoneycombConfig } from 'autotel-backends/honeycomb';\n *\n * init(createHoneycombConfig({\n * apiKey: process.env.HONEYCOMB_API_KEY!,\n * service: 'my-app',\n * }));\n * ```\n *\n * @example With custom dataset\n * ```typescript\n * import { init } from 'autotel';\n * import { createHoneycombConfig } from 'autotel-backends/honeycomb';\n *\n * init(createHoneycombConfig({\n * apiKey: process.env.HONEYCOMB_API_KEY!,\n * service: 'my-app',\n * dataset: 'production',\n * }));\n * ```\n */\n\nimport type { AutotelConfig } from 'autotel';\n\n/**\n * Configuration options for Honeycomb preset\n */\nexport interface HoneycombPresetConfig {\n /**\n * Honeycomb API key (required).\n *\n * Get your API key from:\n * https://ui.honeycomb.io/account\n *\n * For classic environments, use an environment-specific key.\n * For newer environments, use a team-level API key.\n */\n apiKey: string;\n\n /**\n * Service name (required).\n * Appears as service.name in Honeycomb traces and determines dataset routing.\n */\n service: string;\n\n /**\n * Dataset name (optional).\n * For classic Honeycomb accounts that use datasets.\n * Modern environments route based on service.name instead.\n *\n * @default service name\n */\n dataset?: string;\n\n /**\n * Deployment environment (e.g., 'production', 'staging', 'development').\n * Used for environment filtering in Honeycomb.\n *\n * @default process.env.NODE_ENV || 'development'\n */\n environment?: string;\n\n /**\n * Service version for deployment tracking.\n *\n * @default process.env.VERSION || auto-detected from package.json\n */\n version?: string;\n\n /**\n * Honeycomb API endpoint.\n * Use this to configure for different regions or on-premises installations.\n *\n * @default 'api.honeycomb.io:443'\n */\n endpoint?: string;\n\n /**\n * Sample rate for traces (1 = 100%, 10 = 10%, 100 = 1%).\n * Honeycomb's head-based sampling rate.\n *\n * Note: Autotel uses tail-based sampling by default.\n * This setting applies additional head-based sampling if specified.\n *\n * @default undefined (no head-based sampling, relies on tail sampling)\n */\n sampleRate?: number;\n}\n\n/**\n * Create an autotel configuration optimized for Honeycomb.\n *\n * This preset handles:\n * - gRPC protocol configuration (Honeycomb's preferred protocol)\n * - Proper endpoint and authentication headers\n * - Dataset routing (for classic accounts)\n * - Unified service tagging (service, env, version)\n *\n * Honeycomb uses gRPC by default for better performance and lower overhead.\n * This preset automatically configures the gRPC protocol.\n *\n * @param config - Honeycomb-specific configuration options\n * @returns AutotelConfig ready to pass to init()\n *\n * @example Simple configuration\n * ```typescript\n * init(createHoneycombConfig({\n * apiKey: process.env.HONEYCOMB_API_KEY!,\n * service: 'my-app',\n * }));\n * ```\n *\n * @example With custom dataset and environment\n * ```typescript\n * init(createHoneycombConfig({\n * apiKey: process.env.HONEYCOMB_API_KEY!,\n * service: 'my-app',\n * dataset: 'production',\n * environment: 'production',\n * version: '2.1.0',\n * }));\n * ```\n *\n * @example With sample rate\n * ```typescript\n * init(createHoneycombConfig({\n * apiKey: process.env.HONEYCOMB_API_KEY!,\n * service: 'my-app',\n * sampleRate: 10, // Sample 10% of traces (head-based sampling)\n * }));\n * ```\n */\nexport function createHoneycombConfig(\n config: HoneycombPresetConfig,\n): AutotelConfig {\n const {\n apiKey,\n service,\n dataset,\n environment,\n version,\n endpoint = 'api.honeycomb.io:443',\n sampleRate,\n } = config;\n\n // Validation: API key is required\n if (!apiKey) {\n throw new Error(\n 'Honeycomb API key is required. Get your API key from: https://ui.honeycomb.io/account',\n );\n }\n\n // Build headers\n const headers: Record<string, string> = {\n 'x-honeycomb-team': apiKey,\n };\n\n // Add dataset header if specified (for classic Honeycomb accounts)\n if (dataset) {\n headers['x-honeycomb-dataset'] = dataset;\n }\n\n // Add sample rate header if specified\n if (sampleRate !== undefined) {\n headers['x-honeycomb-samplerate'] = String(sampleRate);\n }\n\n return {\n service,\n environment,\n version,\n protocol: 'grpc', // Honeycomb uses gRPC for better performance\n endpoint,\n headers,\n };\n}\n","/**\n * Datadog preset for autotel\n *\n * Provides a simplified configuration helper for Datadog integration\n * with best practices built-in.\n *\n * @example Direct cloud ingestion (serverless, edge)\n * ```typescript\n * import { init } from 'autotel';\n * import { createDatadogConfig } from 'autotel-backends/datadog';\n *\n * init(createDatadogConfig({\n * apiKey: process.env.DATADOG_API_KEY!,\n * service: 'my-lambda',\n * enableLogs: true,\n * }));\n * ```\n *\n * @example Local Datadog Agent (long-running services, Kubernetes)\n * ```typescript\n * import { init } from 'autotel';\n * import { createDatadogConfig } from 'autotel-backends/datadog';\n *\n * init(createDatadogConfig({\n * service: 'my-api',\n * useAgent: true, // No API key needed - Agent handles it\n * }));\n * ```\n */\n\nimport { createRequire } from 'node:module';\nimport type { AutotelConfig } from 'autotel';\nimport type { LogRecordProcessor } from '@opentelemetry/sdk-logs';\n\n/**\n * Datadog site regions\n */\nexport type DatadogSite =\n | 'datadoghq.com' // US1 (default)\n | 'datadoghq.eu' // EU\n | 'us3.datadoghq.com' // US3\n | 'us5.datadoghq.com' // US5\n | 'ap1.datadoghq.com' // AP1\n | 'ddog-gov.com'; // US1-FED\n\n/**\n * Configuration options for Datadog preset\n */\nexport interface DatadogPresetConfig {\n /**\n * Datadog API key (required for direct cloud ingestion).\n * Not needed if using local Datadog Agent (useAgent: true).\n *\n * Get your API key from:\n * https://app.datadoghq.com/organization-settings/api-keys\n */\n apiKey?: string;\n\n /**\n * Datadog site/region.\n * Determines which Datadog intake endpoint to use.\n *\n * @default 'datadoghq.com' (US1)\n */\n site?: DatadogSite;\n\n /**\n * Service name (required).\n * Appears in Datadog APM, Service Catalog, and all telemetry.\n */\n service: string;\n\n /**\n * Deployment environment (e.g., 'production', 'staging', 'development').\n * Used for environment filtering in Datadog.\n *\n * @default process.env.DD_ENV || process.env.NODE_ENV || 'development'\n */\n environment?: string;\n\n /**\n * Service version for deployment tracking.\n * Enables Deployment Tracking in Datadog APM.\n *\n * @default process.env.DD_VERSION || auto-detected from package.json\n */\n version?: string;\n\n /**\n * Enable log export to Datadog via OTLP.\n *\n * When enabled, this:\n * 1. Sets up OTel Logs SDK with OTLP exporter (for direct OTel logs API usage)\n * 2. Auto-configures OTEL_EXPORTER_OTLP_LOGS_* env vars for pino-opentelemetry-transport\n *\n * For Pino users: Just add pino-opentelemetry-transport to your logger config:\n * ```typescript\n * const logger = pino({\n * transport: {\n * targets: [\n * { target: 'pino-pretty' },\n * { target: 'pino-opentelemetry-transport' }, // Auto-configured!\n * ],\n * },\n * });\n * ```\n *\n * Requires peer dependencies: @opentelemetry/sdk-logs, @opentelemetry/exporter-logs-otlp-http\n *\n * @default false\n */\n enableLogs?: boolean;\n\n /**\n * Use local Datadog Agent instead of direct cloud ingestion.\n *\n * Benefits:\n * - Lower egress costs (Agent aggregates locally)\n * - Advanced features: trace-log correlation, multi-line logs, data scrubbing\n * - 500+ integrations for enrichment\n * - Infrastructure metrics collection\n *\n * Requires: Datadog Agent 7.35+ with OTLP enabled\n *\n * @default false\n */\n useAgent?: boolean;\n\n /**\n * Datadog Agent hostname (when useAgent: true).\n *\n * @default 'localhost'\n */\n agentHost?: string;\n\n /**\n * Datadog Agent OTLP port (when useAgent: true).\n *\n * @default 4318 (OTLP HTTP)\n */\n agentPort?: number;\n\n /**\n * Custom log record processors (advanced).\n * Overrides the default log processor if enableLogs is true.\n */\n logRecordProcessors?: LogRecordProcessor[];\n}\n\n/**\n * Create an autotel configuration optimized for Datadog.\n *\n * This preset handles:\n * - Proper OTLP endpoint configuration (Agent vs direct ingestion)\n * - Direct: https://otlp.{site} → SDK appends /v1/traces, /v1/metrics, /v1/logs\n * - Agent: http://localhost:4318 (default)\n * - Datadog API key authentication headers (direct ingestion only)\n * - Unified service tagging (service, env, version)\n * - Resource attribute best practices\n * - Optional log export configuration\n *\n * @param config - Datadog-specific configuration options\n * @returns AutotelConfig ready to pass to init()\n *\n * @example Simple cloud ingestion\n * ```typescript\n * init(createDatadogConfig({\n * apiKey: process.env.DATADOG_API_KEY!,\n * service: 'my-app',\n * }));\n * ```\n *\n * @example With logs and custom environment\n * ```typescript\n * init(createDatadogConfig({\n * apiKey: process.env.DATADOG_API_KEY!,\n * service: 'my-app',\n * environment: 'production',\n * version: '2.1.0',\n * enableLogs: true,\n * }));\n * ```\n *\n * @example Using local Datadog Agent\n * ```typescript\n * init(createDatadogConfig({\n * service: 'my-api',\n * useAgent: true,\n * agentHost: 'datadog-agent.default.svc.cluster.local', // Kubernetes\n * }));\n * ```\n */\nexport function createDatadogConfig(\n config: DatadogPresetConfig,\n): AutotelConfig {\n const {\n apiKey,\n site = 'datadoghq.com',\n service,\n environment,\n version,\n enableLogs = false,\n useAgent = false,\n agentHost = 'localhost',\n agentPort = 4318,\n logRecordProcessors,\n } = config;\n\n // Validation: API key required for direct ingestion\n if (!useAgent && !apiKey) {\n throw new Error(\n 'Datadog API key is required for direct cloud ingestion. ' +\n 'Either provide apiKey or set useAgent: true to use local Datadog Agent.',\n );\n }\n\n const baseConfig: AutotelConfig = {\n service,\n environment,\n version,\n };\n\n // Local Datadog Agent configuration\n if (useAgent) {\n const agentEndpoint = `http://${agentHost}:${agentPort}`;\n\n // Auto-configure env vars for pino-opentelemetry-transport in agent mode\n if (enableLogs) {\n const logsEndpoint = `http://${agentHost}:${agentPort}/v1/logs`;\n\n if (!process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = logsEndpoint;\n }\n\n if (!process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL = 'http/protobuf';\n }\n\n // No API key header needed for agent mode - Agent handles authentication\n\n const resourceAttrs = [\n `service.name=${service}`,\n environment ? `deployment.environment=${environment}` : null,\n version ? `service.version=${version}` : null,\n ]\n .filter(Boolean)\n .join(',');\n\n if (!process.env.OTEL_RESOURCE_ATTRIBUTES) {\n process.env.OTEL_RESOURCE_ATTRIBUTES = resourceAttrs;\n }\n }\n\n return {\n ...baseConfig,\n endpoint: agentEndpoint,\n // No API key or headers needed - Agent handles authentication\n };\n }\n\n // Direct cloud ingestion configuration\n // Datadog OTLP endpoint: base URL without path (SDK appends /v1/traces, /v1/metrics, /v1/logs)\n const otlpEndpoint = `https://otlp.${site}`;\n const authHeaders = `dd-api-key=${apiKey}`;\n\n const cloudConfig: AutotelConfig = {\n ...baseConfig,\n endpoint: otlpEndpoint,\n headers: authHeaders,\n };\n\n // Add log export if enabled\n if (enableLogs) {\n // Auto-configure env vars for pino-opentelemetry-transport and other OTel log transports\n // These are read by pino-opentelemetry-transport, otlp-logger, and similar libraries\n const logsEndpoint = useAgent\n ? `http://${agentHost}:${agentPort}/v1/logs`\n : `https://otlp.${site}/v1/logs`;\n\n // Only set if not already configured (allow user override)\n if (!process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = logsEndpoint;\n }\n\n if (!process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL = 'http/protobuf';\n }\n\n // Only set API key header for direct cloud ingestion (not agent mode)\n if (!useAgent && apiKey && !process.env.OTEL_EXPORTER_OTLP_LOGS_HEADERS) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_HEADERS = `dd-api-key=${apiKey}`;\n }\n\n // Set resource attributes for service identification\n const resourceAttrs = [\n `service.name=${service}`,\n environment ? `deployment.environment=${environment}` : null,\n version ? `service.version=${version}` : null,\n ]\n .filter(Boolean)\n .join(',');\n\n if (!process.env.OTEL_RESOURCE_ATTRIBUTES) {\n process.env.OTEL_RESOURCE_ATTRIBUTES = resourceAttrs;\n }\n\n if (logRecordProcessors) {\n // Use custom processors if provided\n cloudConfig.logRecordProcessors = logRecordProcessors;\n } else {\n // Create default OTLP log exporter\n try {\n // Lazy-load to preserve optional peer dependencies\n // Use createRequire to resolve from user's project directory\n const userRequire = createRequire(process.cwd() + '/package.json');\n\n const { BatchLogRecordProcessor } = userRequire(\n '@opentelemetry/sdk-logs',\n );\n const { OTLPLogExporter } = userRequire(\n '@opentelemetry/exporter-logs-otlp-http',\n );\n\n cloudConfig.logRecordProcessors = [\n new BatchLogRecordProcessor(\n new OTLPLogExporter({\n // Logs use /v1/logs path (SDK appends this to endpoint)\n url: `${otlpEndpoint}/v1/logs`,\n headers: {\n 'dd-api-key': apiKey,\n },\n }),\n ),\n ];\n } catch {\n throw new Error(\n 'Log export requires peer dependencies: @opentelemetry/sdk-logs and @opentelemetry/exporter-logs-otlp-http. ' +\n 'Install them with: npm install @opentelemetry/sdk-logs @opentelemetry/exporter-logs-otlp-http',\n );\n }\n }\n }\n\n return cloudConfig;\n}\n","/**\n * Google Cloud preset for autotel\n *\n * Sends traces (and optionally metrics) to Google Cloud Observability via the\n * Telemetry (OTLP) API. Uses Application Default Credentials (ADC) for auth.\n *\n * @example Direct export to GCP (with google-auth-library)\n * ```typescript\n * import { init } from 'autotel';\n * import { createGoogleCloudConfig } from 'autotel-backends/google-cloud';\n *\n * init(createGoogleCloudConfig({\n * projectId: process.env.GOOGLE_CLOUD_PROJECT!,\n * service: 'my-app',\n * }));\n * ```\n *\n * @example Via OpenTelemetry Collector (no auth in app)\n * ```typescript\n * init(createGoogleCloudConfig({\n * projectId: process.env.GOOGLE_CLOUD_PROJECT!,\n * service: 'my-app',\n * useCollector: true,\n * collectorEndpoint: 'http://localhost:4318',\n * }));\n * ```\n */\n\nimport { createRequire } from 'node:module';\nimport type { AutotelConfig } from 'autotel';\n\n/** Minimal SpanExporter-compatible interface (avoids @opentelemetry/sdk-trace-base peer at build time). */\ninterface SpanExporterLike {\n export(\n spans: unknown[],\n resultCallback: (result: { code: number; error?: Error }) => void,\n ): void | Promise<void>;\n forceFlush?(): Promise<void>;\n shutdown?(): Promise<void>;\n}\n\n/** Default Telemetry API base URL (OTLP). */\nconst DEFAULT_ENDPOINT = 'https://telemetry.googleapis.com';\n\n/**\n * Configuration options for Google Cloud preset\n */\nexport interface GoogleCloudPresetConfig {\n /**\n * Google Cloud project ID (required for direct export).\n * Used for quota and resource attribution. Set GOOGLE_CLOUD_PROJECT or\n * GOOGLE_APPLICATION_CREDENTIALS for ADC.\n *\n * @default process.env.GOOGLE_CLOUD_PROJECT\n */\n projectId: string;\n\n /**\n * Service name (required).\n * Appears as service.name in Cloud Trace and Monitoring.\n */\n service: string;\n\n /**\n * Deployment environment (e.g., 'production', 'staging').\n *\n * @default process.env.NODE_ENV || 'development'\n */\n environment?: string;\n\n /**\n * Service version for deployment tracking.\n *\n * @default process.env.GCP_VERSION || process.env.VERSION\n */\n version?: string;\n\n /**\n * Use an OpenTelemetry Collector instead of exporting directly to GCP.\n * When true, the app sends OTLP to collectorEndpoint; the Collector\n * handles authentication to the Telemetry API. No google-auth-library needed.\n *\n * @default false\n */\n useCollector?: boolean;\n\n /**\n * Collector OTLP endpoint (when useCollector is true).\n *\n * @default 'http://localhost:4318'\n */\n collectorEndpoint?: string;\n\n /**\n * Telemetry API base URL (when useCollector is false).\n * Only override for testing or special endpoints.\n *\n * @default 'https://telemetry.googleapis.com'\n */\n endpoint?: string;\n}\n\n/**\n * Create an autotel configuration for Google Cloud Observability (Telemetry API).\n *\n * - With useCollector: false (default), exports directly to the Telemetry API\n * using Application Default Credentials. Requires optional peer dependency\n * google-auth-library for auth. Install: pnpm add google-auth-library\n *\n * - With useCollector: true, sends OTLP to a local Collector; the Collector\n * forwards to GCP with ADC. No google-auth-library needed in the app.\n *\n * @param config - Google Cloud preset options\n * @returns AutotelConfig ready to pass to init()\n */\nexport function createGoogleCloudConfig(\n config: GoogleCloudPresetConfig,\n): AutotelConfig {\n const {\n projectId,\n service,\n environment,\n version,\n useCollector = false,\n collectorEndpoint = 'http://localhost:4318',\n endpoint = DEFAULT_ENDPOINT,\n } = config;\n\n if (!projectId) {\n throw new Error(\n 'Google Cloud projectId is required. Set it or use process.env.GOOGLE_CLOUD_PROJECT.',\n );\n }\n\n const baseConfig: AutotelConfig = {\n service,\n environment,\n version,\n };\n\n if (useCollector) {\n return {\n ...baseConfig,\n endpoint: collectorEndpoint,\n // x-goog-user-project for quota when Collector forwards to GCP\n headers: { 'x-goog-user-project': projectId },\n };\n }\n\n // Direct export: need ADC via google-auth-library\n try {\n const userRequire = createRequire(process.cwd() + '/package.json');\n const { GoogleAuth } = userRequire('google-auth-library');\n const { OTLPTraceExporter } = userRequire(\n '@opentelemetry/exporter-trace-otlp-http',\n );\n\n const tracesUrl = `${endpoint}/v1/traces`;\n const auth = new GoogleAuth({\n scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n });\n\n const gcpTraceExporter = createGcpAuthTraceExporter(\n tracesUrl,\n projectId,\n auth,\n OTLPTraceExporter,\n );\n\n return {\n ...baseConfig,\n // Structurally compatible with SpanExporter from @opentelemetry/sdk-trace-base\n spanExporters: [\n gcpTraceExporter as NonNullable<AutotelConfig['spanExporters']>[number],\n ],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (\n message.includes('google-auth-library') ||\n message.includes('Cannot find module')\n ) {\n throw new Error(\n 'Direct export to Google Cloud requires google-auth-library. ' +\n 'Install it: pnpm add google-auth-library. ' +\n 'Or use useCollector: true and run an OpenTelemetry Collector with GCP auth.',\n { cause: error },\n );\n }\n throw error;\n }\n}\n\n/** Minimal auth client: getClient() returns a client with getAccessToken(). */\ninterface GoogleAuthLike {\n getClient(): Promise<{ getAccessToken(): Promise<{ token: string | null }> }>;\n}\n\ntype OTLPTraceExporterCtor = new (config: {\n url: string;\n headers?: Record<string, string>;\n}) => SpanExporterLike;\n\nfunction createGcpAuthTraceExporter(\n url: string,\n projectId: string,\n auth: GoogleAuthLike,\n OTLPTraceExporterCtor: OTLPTraceExporterCtor,\n): SpanExporterLike {\n return new GcpAuthSpanExporter(url, projectId, auth, OTLPTraceExporterCtor);\n}\n\nclass GcpAuthSpanExporter implements SpanExporterLike {\n constructor(\n private readonly url: string,\n private readonly projectId: string,\n private readonly auth: GoogleAuthLike,\n private readonly OTLPTraceExporterCtor: OTLPTraceExporterCtor,\n ) {}\n\n async export(\n spans: unknown[],\n resultCallback: (result: { code: number; error?: Error }) => void,\n ): Promise<void> {\n try {\n const client = await this.auth.getClient();\n const tokenResponse = await client.getAccessToken();\n const token = tokenResponse.token;\n if (!token) {\n resultCallback({\n code: 1,\n error: new Error('No access token from ADC'),\n });\n return;\n }\n const exporter = new this.OTLPTraceExporterCtor({\n url: this.url,\n headers: {\n Authorization: `Bearer ${token}`,\n 'x-goog-user-project': this.projectId,\n },\n });\n exporter.export(spans, resultCallback);\n } catch (error) {\n resultCallback({\n code: 1,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n }\n\n forceFlush(): Promise<void> {\n return Promise.resolve();\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/honeycomb.ts","../src/datadog.ts","../src/google-cloud.ts","../src/grafana.ts"],"names":["createRequire"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Honeycomb preset for autotel\n *\n * Provides a simplified configuration helper for Honeycomb integration\n * with best practices built-in.\n *\n * @example Using Honeycomb with API key\n * ```typescript\n * import { init } from 'autotel';\n * import { createHoneycombConfig } from 'autotel-backends/honeycomb';\n *\n * init(createHoneycombConfig({\n * apiKey: process.env.HONEYCOMB_API_KEY!,\n * service: 'my-app',\n * }));\n * ```\n *\n * @example With custom dataset\n * ```typescript\n * import { init } from 'autotel';\n * import { createHoneycombConfig } from 'autotel-backends/honeycomb';\n *\n * init(createHoneycombConfig({\n * apiKey: process.env.HONEYCOMB_API_KEY!,\n * service: 'my-app',\n * dataset: 'production',\n * }));\n * ```\n */\n\nimport type { AutotelConfig } from 'autotel';\n\n/**\n * Configuration options for Honeycomb preset\n */\nexport interface HoneycombPresetConfig {\n /**\n * Honeycomb API key (required).\n *\n * Get your API key from:\n * https://ui.honeycomb.io/account\n *\n * For classic environments, use an environment-specific key.\n * For newer environments, use a team-level API key.\n */\n apiKey: string;\n\n /**\n * Service name (required).\n * Appears as service.name in Honeycomb traces and determines dataset routing.\n */\n service: string;\n\n /**\n * Dataset name (optional).\n * For classic Honeycomb accounts that use datasets.\n * Modern environments route based on service.name instead.\n *\n * @default service name\n */\n dataset?: string;\n\n /**\n * Deployment environment (e.g., 'production', 'staging', 'development').\n * Used for environment filtering in Honeycomb.\n *\n * @default process.env.NODE_ENV || 'development'\n */\n environment?: string;\n\n /**\n * Service version for deployment tracking.\n *\n * @default process.env.VERSION || auto-detected from package.json\n */\n version?: string;\n\n /**\n * Honeycomb API endpoint.\n * Use this to configure for different regions or on-premises installations.\n *\n * @default 'api.honeycomb.io:443'\n */\n endpoint?: string;\n\n /**\n * Sample rate for traces (1 = 100%, 10 = 10%, 100 = 1%).\n * Honeycomb's head-based sampling rate.\n *\n * Note: Autotel uses tail-based sampling by default.\n * This setting applies additional head-based sampling if specified.\n *\n * @default undefined (no head-based sampling, relies on tail sampling)\n */\n sampleRate?: number;\n}\n\n/**\n * Create an autotel configuration optimized for Honeycomb.\n *\n * This preset handles:\n * - gRPC protocol configuration (Honeycomb's preferred protocol)\n * - Proper endpoint and authentication headers\n * - Dataset routing (for classic accounts)\n * - Unified service tagging (service, env, version)\n *\n * Honeycomb uses gRPC by default for better performance and lower overhead.\n * This preset automatically configures the gRPC protocol.\n *\n * @param config - Honeycomb-specific configuration options\n * @returns AutotelConfig ready to pass to init()\n *\n * @example Simple configuration\n * ```typescript\n * init(createHoneycombConfig({\n * apiKey: process.env.HONEYCOMB_API_KEY!,\n * service: 'my-app',\n * }));\n * ```\n *\n * @example With custom dataset and environment\n * ```typescript\n * init(createHoneycombConfig({\n * apiKey: process.env.HONEYCOMB_API_KEY!,\n * service: 'my-app',\n * dataset: 'production',\n * environment: 'production',\n * version: '2.1.0',\n * }));\n * ```\n *\n * @example With sample rate\n * ```typescript\n * init(createHoneycombConfig({\n * apiKey: process.env.HONEYCOMB_API_KEY!,\n * service: 'my-app',\n * sampleRate: 10, // Sample 10% of traces (head-based sampling)\n * }));\n * ```\n */\nexport function createHoneycombConfig(\n config: HoneycombPresetConfig,\n): AutotelConfig {\n const {\n apiKey,\n service,\n dataset,\n environment,\n version,\n endpoint = 'api.honeycomb.io:443',\n sampleRate,\n } = config;\n\n // Validation: API key is required\n if (!apiKey) {\n throw new Error(\n 'Honeycomb API key is required. Get your API key from: https://ui.honeycomb.io/account',\n );\n }\n\n // Build headers\n const headers: Record<string, string> = {\n 'x-honeycomb-team': apiKey,\n };\n\n // Add dataset header if specified (for classic Honeycomb accounts)\n if (dataset) {\n headers['x-honeycomb-dataset'] = dataset;\n }\n\n // Add sample rate header if specified\n if (sampleRate !== undefined) {\n headers['x-honeycomb-samplerate'] = String(sampleRate);\n }\n\n return {\n service,\n environment,\n version,\n protocol: 'grpc', // Honeycomb uses gRPC for better performance\n endpoint,\n headers,\n };\n}\n","/**\n * Datadog preset for autotel\n *\n * Provides a simplified configuration helper for Datadog integration\n * with best practices built-in.\n *\n * @example Direct cloud ingestion (serverless, edge)\n * ```typescript\n * import { init } from 'autotel';\n * import { createDatadogConfig } from 'autotel-backends/datadog';\n *\n * init(createDatadogConfig({\n * apiKey: process.env.DATADOG_API_KEY!,\n * service: 'my-lambda',\n * enableLogs: true,\n * }));\n * ```\n *\n * @example Local Datadog Agent (long-running services, Kubernetes)\n * ```typescript\n * import { init } from 'autotel';\n * import { createDatadogConfig } from 'autotel-backends/datadog';\n *\n * init(createDatadogConfig({\n * service: 'my-api',\n * useAgent: true, // No API key needed - Agent handles it\n * }));\n * ```\n */\n\nimport { createRequire } from 'node:module';\nimport type { AutotelConfig } from 'autotel';\nimport type { LogRecordProcessor } from '@opentelemetry/sdk-logs';\n\n/**\n * Datadog site regions\n */\nexport type DatadogSite =\n | 'datadoghq.com' // US1 (default)\n | 'datadoghq.eu' // EU\n | 'us3.datadoghq.com' // US3\n | 'us5.datadoghq.com' // US5\n | 'ap1.datadoghq.com' // AP1\n | 'ddog-gov.com'; // US1-FED\n\n/**\n * Configuration options for Datadog preset\n */\nexport interface DatadogPresetConfig {\n /**\n * Datadog API key (required for direct cloud ingestion).\n * Not needed if using local Datadog Agent (useAgent: true).\n *\n * Get your API key from:\n * https://app.datadoghq.com/organization-settings/api-keys\n */\n apiKey?: string;\n\n /**\n * Datadog site/region.\n * Determines which Datadog intake endpoint to use.\n *\n * @default 'datadoghq.com' (US1)\n */\n site?: DatadogSite;\n\n /**\n * Service name (required).\n * Appears in Datadog APM, Service Catalog, and all telemetry.\n */\n service: string;\n\n /**\n * Deployment environment (e.g., 'production', 'staging', 'development').\n * Used for environment filtering in Datadog.\n *\n * @default process.env.DD_ENV || process.env.NODE_ENV || 'development'\n */\n environment?: string;\n\n /**\n * Service version for deployment tracking.\n * Enables Deployment Tracking in Datadog APM.\n *\n * @default process.env.DD_VERSION || auto-detected from package.json\n */\n version?: string;\n\n /**\n * Enable log export to Datadog via OTLP.\n *\n * When enabled, this:\n * 1. Sets up OTel Logs SDK with OTLP exporter (for direct OTel logs API usage)\n * 2. Auto-configures OTEL_EXPORTER_OTLP_LOGS_* env vars for pino-opentelemetry-transport\n *\n * For Pino users: Just add pino-opentelemetry-transport to your logger config:\n * ```typescript\n * const logger = pino({\n * transport: {\n * targets: [\n * { target: 'pino-pretty' },\n * { target: 'pino-opentelemetry-transport' }, // Auto-configured!\n * ],\n * },\n * });\n * ```\n *\n * @default false\n */\n enableLogs?: boolean;\n\n /**\n * Use local Datadog Agent instead of direct cloud ingestion.\n *\n * Benefits:\n * - Lower egress costs (Agent aggregates locally)\n * - Advanced features: trace-log correlation, multi-line logs, data scrubbing\n * - 500+ integrations for enrichment\n * - Infrastructure metrics collection\n *\n * Requires: Datadog Agent 7.35+ with OTLP enabled\n *\n * @default false\n */\n useAgent?: boolean;\n\n /**\n * Datadog Agent hostname (when useAgent: true).\n *\n * @default 'localhost'\n */\n agentHost?: string;\n\n /**\n * Datadog Agent OTLP port (when useAgent: true).\n *\n * @default 4318 (OTLP HTTP)\n */\n agentPort?: number;\n\n /**\n * Custom log record processors (advanced).\n * Overrides the default log processor if enableLogs is true.\n */\n logRecordProcessors?: LogRecordProcessor[];\n}\n\n/**\n * Create an autotel configuration optimized for Datadog.\n *\n * This preset handles:\n * - Proper OTLP endpoint configuration (Agent vs direct ingestion)\n * - Direct: https://otlp.{site} → SDK appends /v1/traces, /v1/metrics, /v1/logs\n * - Agent: http://localhost:4318 (default)\n * - Datadog API key authentication headers (direct ingestion only)\n * - Unified service tagging (service, env, version)\n * - Resource attribute best practices\n * - Optional log export configuration\n *\n * @param config - Datadog-specific configuration options\n * @returns AutotelConfig ready to pass to init()\n *\n * @example Simple cloud ingestion\n * ```typescript\n * init(createDatadogConfig({\n * apiKey: process.env.DATADOG_API_KEY!,\n * service: 'my-app',\n * }));\n * ```\n *\n * @example With logs and custom environment\n * ```typescript\n * init(createDatadogConfig({\n * apiKey: process.env.DATADOG_API_KEY!,\n * service: 'my-app',\n * environment: 'production',\n * version: '2.1.0',\n * enableLogs: true,\n * }));\n * ```\n *\n * @example Using local Datadog Agent\n * ```typescript\n * init(createDatadogConfig({\n * service: 'my-api',\n * useAgent: true,\n * agentHost: 'datadog-agent.default.svc.cluster.local', // Kubernetes\n * }));\n * ```\n */\nexport function createDatadogConfig(\n config: DatadogPresetConfig,\n): AutotelConfig {\n const {\n apiKey,\n site = 'datadoghq.com',\n service,\n environment,\n version,\n enableLogs = false,\n useAgent = false,\n agentHost = 'localhost',\n agentPort = 4318,\n logRecordProcessors,\n } = config;\n\n // Validation: API key required for direct ingestion\n if (!useAgent && !apiKey) {\n throw new Error(\n 'Datadog API key is required for direct cloud ingestion. ' +\n 'Either provide apiKey or set useAgent: true to use local Datadog Agent.',\n );\n }\n\n const baseConfig: AutotelConfig = {\n service,\n environment,\n version,\n };\n\n // Local Datadog Agent configuration\n if (useAgent) {\n const agentEndpoint = `http://${agentHost}:${agentPort}`;\n\n // Auto-configure env vars for pino-opentelemetry-transport in agent mode\n if (enableLogs) {\n const logsEndpoint = `http://${agentHost}:${agentPort}/v1/logs`;\n\n if (!process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = logsEndpoint;\n }\n\n if (!process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL = 'http/protobuf';\n }\n\n // No API key header needed for agent mode - Agent handles authentication\n\n const resourceAttrs = [\n `service.name=${service}`,\n environment ? `deployment.environment=${environment}` : null,\n version ? `service.version=${version}` : null,\n ]\n .filter(Boolean)\n .join(',');\n\n if (!process.env.OTEL_RESOURCE_ATTRIBUTES) {\n process.env.OTEL_RESOURCE_ATTRIBUTES = resourceAttrs;\n }\n }\n\n return {\n ...baseConfig,\n endpoint: agentEndpoint,\n // No API key or headers needed - Agent handles authentication\n };\n }\n\n // Direct cloud ingestion configuration\n // Datadog OTLP endpoint: base URL without path (SDK appends /v1/traces, /v1/metrics, /v1/logs)\n const otlpEndpoint = `https://otlp.${site}`;\n const authHeaders = `dd-api-key=${apiKey}`;\n\n const cloudConfig: AutotelConfig = {\n ...baseConfig,\n endpoint: otlpEndpoint,\n headers: authHeaders,\n };\n\n // Add log export if enabled\n if (enableLogs) {\n // Auto-configure env vars for pino-opentelemetry-transport and other OTel log transports\n // These are read by pino-opentelemetry-transport, otlp-logger, and similar libraries\n const logsEndpoint = useAgent\n ? `http://${agentHost}:${agentPort}/v1/logs`\n : `https://otlp.${site}/v1/logs`;\n\n // Only set if not already configured (allow user override)\n if (!process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = logsEndpoint;\n }\n\n if (!process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL = 'http/protobuf';\n }\n\n // Only set API key header for direct cloud ingestion (not agent mode)\n if (!useAgent && apiKey && !process.env.OTEL_EXPORTER_OTLP_LOGS_HEADERS) {\n process.env.OTEL_EXPORTER_OTLP_LOGS_HEADERS = `dd-api-key=${apiKey}`;\n }\n\n // Set resource attributes for service identification\n const resourceAttrs = [\n `service.name=${service}`,\n environment ? `deployment.environment=${environment}` : null,\n version ? `service.version=${version}` : null,\n ]\n .filter(Boolean)\n .join(',');\n\n if (!process.env.OTEL_RESOURCE_ATTRIBUTES) {\n process.env.OTEL_RESOURCE_ATTRIBUTES = resourceAttrs;\n }\n\n if (logRecordProcessors) {\n // Use custom processors if provided\n cloudConfig.logRecordProcessors = logRecordProcessors;\n } else {\n // Create default OTLP log exporter\n try {\n const pkgRequire = createRequire(import.meta.url);\n const { BatchLogRecordProcessor } = pkgRequire(\n '@opentelemetry/sdk-logs',\n );\n const { OTLPLogExporter } = pkgRequire(\n '@opentelemetry/exporter-logs-otlp-http',\n );\n\n cloudConfig.logRecordProcessors = [\n new BatchLogRecordProcessor(\n new OTLPLogExporter({\n url: `${otlpEndpoint}/v1/logs`,\n headers: {\n 'dd-api-key': apiKey,\n },\n }),\n ),\n ];\n } catch {\n throw new Error(\n 'Log export requires @opentelemetry/sdk-logs and @opentelemetry/exporter-logs-otlp-http. ' +\n 'Install them or set enableLogs: false.',\n );\n }\n }\n }\n\n return cloudConfig;\n}\n","/**\n * Google Cloud preset for autotel\n *\n * Sends traces (and optionally metrics) to Google Cloud Observability via the\n * Telemetry (OTLP) API. Uses Application Default Credentials (ADC) for auth.\n *\n * @example Direct export to GCP (with google-auth-library)\n * ```typescript\n * import { init } from 'autotel';\n * import { createGoogleCloudConfig } from 'autotel-backends/google-cloud';\n *\n * init(createGoogleCloudConfig({\n * projectId: process.env.GOOGLE_CLOUD_PROJECT!,\n * service: 'my-app',\n * }));\n * ```\n *\n * @example Via OpenTelemetry Collector (no auth in app)\n * ```typescript\n * init(createGoogleCloudConfig({\n * projectId: process.env.GOOGLE_CLOUD_PROJECT!,\n * service: 'my-app',\n * useCollector: true,\n * collectorEndpoint: 'http://localhost:4318',\n * }));\n * ```\n */\n\nimport { createRequire } from 'node:module';\nimport type { AutotelConfig } from 'autotel';\n\n/** Minimal SpanExporter-compatible interface (avoids @opentelemetry/sdk-trace-base peer at build time). */\ninterface SpanExporterLike {\n export(\n spans: unknown[],\n resultCallback: (result: { code: number; error?: Error }) => void,\n ): void | Promise<void>;\n forceFlush?(): Promise<void>;\n shutdown?(): Promise<void>;\n}\n\n/** Default Telemetry API base URL (OTLP). */\nconst DEFAULT_ENDPOINT = 'https://telemetry.googleapis.com';\n\n/**\n * Configuration options for Google Cloud preset\n */\nexport interface GoogleCloudPresetConfig {\n /**\n * Google Cloud project ID (required for direct export).\n * Used for quota and resource attribution. Set GOOGLE_CLOUD_PROJECT or\n * GOOGLE_APPLICATION_CREDENTIALS for ADC.\n *\n * @default process.env.GOOGLE_CLOUD_PROJECT\n */\n projectId: string;\n\n /**\n * Service name (required).\n * Appears as service.name in Cloud Trace and Monitoring.\n */\n service: string;\n\n /**\n * Deployment environment (e.g., 'production', 'staging').\n *\n * @default process.env.NODE_ENV || 'development'\n */\n environment?: string;\n\n /**\n * Service version for deployment tracking.\n *\n * @default process.env.GCP_VERSION || process.env.VERSION\n */\n version?: string;\n\n /**\n * Use an OpenTelemetry Collector instead of exporting directly to GCP.\n * When true, the app sends OTLP to collectorEndpoint; the Collector\n * handles authentication to the Telemetry API. No google-auth-library needed.\n *\n * @default false\n */\n useCollector?: boolean;\n\n /**\n * Collector OTLP endpoint (when useCollector is true).\n *\n * @default 'http://localhost:4318'\n */\n collectorEndpoint?: string;\n\n /**\n * Telemetry API base URL (when useCollector is false).\n * Only override for testing or special endpoints.\n *\n * @default 'https://telemetry.googleapis.com'\n */\n endpoint?: string;\n}\n\n/**\n * Create an autotel configuration for Google Cloud Observability (Telemetry API).\n *\n * - With useCollector: false (default), exports directly to the Telemetry API\n * using Application Default Credentials. Requires optional peer dependency\n * google-auth-library for auth. Install: pnpm add google-auth-library\n *\n * - With useCollector: true, sends OTLP to a local Collector; the Collector\n * forwards to GCP with ADC. No google-auth-library needed in the app.\n *\n * @param config - Google Cloud preset options\n * @returns AutotelConfig ready to pass to init()\n */\nexport function createGoogleCloudConfig(\n config: GoogleCloudPresetConfig,\n): AutotelConfig {\n const {\n projectId,\n service,\n environment,\n version,\n useCollector = false,\n collectorEndpoint = 'http://localhost:4318',\n endpoint = DEFAULT_ENDPOINT,\n } = config;\n\n if (!projectId) {\n throw new Error(\n 'Google Cloud projectId is required. Set it or use process.env.GOOGLE_CLOUD_PROJECT.',\n );\n }\n\n const baseConfig: AutotelConfig = {\n service,\n environment,\n version,\n };\n\n if (useCollector) {\n return {\n ...baseConfig,\n endpoint: collectorEndpoint,\n // x-goog-user-project for quota when Collector forwards to GCP\n headers: { 'x-goog-user-project': projectId },\n };\n }\n\n // Direct export: need ADC via google-auth-library\n try {\n const userRequire = createRequire(process.cwd() + '/package.json');\n const { GoogleAuth } = userRequire('google-auth-library');\n const { OTLPTraceExporter } = userRequire(\n '@opentelemetry/exporter-trace-otlp-http',\n );\n\n const tracesUrl = `${endpoint}/v1/traces`;\n const auth = new GoogleAuth({\n scopes: ['https://www.googleapis.com/auth/cloud-platform'],\n });\n\n const gcpTraceExporter = createGcpAuthTraceExporter(\n tracesUrl,\n projectId,\n auth,\n OTLPTraceExporter,\n );\n\n return {\n ...baseConfig,\n // Structurally compatible with SpanExporter from @opentelemetry/sdk-trace-base\n spanExporters: [\n gcpTraceExporter as NonNullable<AutotelConfig['spanExporters']>[number],\n ],\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (\n message.includes('google-auth-library') ||\n message.includes('Cannot find module')\n ) {\n throw new Error(\n 'Direct export to Google Cloud requires google-auth-library. ' +\n 'Install it: pnpm add google-auth-library. ' +\n 'Or use useCollector: true and run an OpenTelemetry Collector with GCP auth.',\n { cause: error },\n );\n }\n throw error;\n }\n}\n\n/** Minimal auth client: getClient() returns a client with getAccessToken(). */\ninterface GoogleAuthLike {\n getClient(): Promise<{ getAccessToken(): Promise<{ token: string | null }> }>;\n}\n\ntype OTLPTraceExporterCtor = new (config: {\n url: string;\n headers?: Record<string, string>;\n}) => SpanExporterLike;\n\nfunction createGcpAuthTraceExporter(\n url: string,\n projectId: string,\n auth: GoogleAuthLike,\n OTLPTraceExporterCtor: OTLPTraceExporterCtor,\n): SpanExporterLike {\n return new GcpAuthSpanExporter(url, projectId, auth, OTLPTraceExporterCtor);\n}\n\nclass GcpAuthSpanExporter implements SpanExporterLike {\n constructor(\n private readonly url: string,\n private readonly projectId: string,\n private readonly auth: GoogleAuthLike,\n private readonly OTLPTraceExporterCtor: OTLPTraceExporterCtor,\n ) {}\n\n async export(\n spans: unknown[],\n resultCallback: (result: { code: number; error?: Error }) => void,\n ): Promise<void> {\n try {\n const client = await this.auth.getClient();\n const tokenResponse = await client.getAccessToken();\n const token = tokenResponse.token;\n if (!token) {\n resultCallback({\n code: 1,\n error: new Error('No access token from ADC'),\n });\n return;\n }\n const exporter = new this.OTLPTraceExporterCtor({\n url: this.url,\n headers: {\n Authorization: `Bearer ${token}`,\n 'x-goog-user-project': this.projectId,\n },\n });\n exporter.export(spans, resultCallback);\n } catch (error) {\n resultCallback({\n code: 1,\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n }\n\n forceFlush(): Promise<void> {\n return Promise.resolve();\n }\n\n shutdown(): Promise<void> {\n return Promise.resolve();\n }\n}\n","/**\n * Grafana Cloud preset for autotel\n *\n * Provides a simplified configuration helper for sending traces, metrics,\n * and logs to Grafana Cloud via the OTLP gateway.\n *\n * Get your endpoint and headers from:\n * Grafana Cloud Portal → your stack → Connections → OpenTelemetry → Configure\n *\n * @example\n * ```typescript\n * import { init } from 'autotel';\n * import { createGrafanaConfig } from 'autotel-backends/grafana';\n *\n * init(createGrafanaConfig({\n * endpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT!,\n * headers: process.env.OTEL_EXPORTER_OTLP_HEADERS,\n * service: 'my-app',\n * enableLogs: true,\n * }));\n * ```\n */\n\nimport { createRequire } from 'node:module';\nimport type { AutotelConfig } from 'autotel';\nimport type { LogRecordProcessor } from '@opentelemetry/sdk-logs';\n\n/**\n * Configuration options for Grafana Cloud preset\n */\nexport interface GrafanaPresetConfig {\n /**\n * OTLP gateway endpoint (required).\n * From Grafana Cloud: Stack → Connections → OpenTelemetry → Configure.\n * Example: https://otlp-gateway-prod-gb-south-1.grafana.net/otlp\n */\n endpoint: string;\n\n /**\n * OTLP authentication headers.\n * From the same Configure tile; usually Basic auth.\n * Example: \"Authorization=Basic%20BASE64_INSTANCE_ID_AND_TOKEN\"\n * or object: { Authorization: 'Basic ...' }\n */\n headers?: string | Record<string, string>;\n\n /**\n * Service name (required).\n * Appears in Tempo, Mimir, and Loki as service_name.\n */\n service: string;\n\n /**\n * Deployment environment (e.g. 'production', 'staging').\n *\n * @default process.env.NODE_ENV || 'development'\n */\n environment?: string;\n\n /**\n * Service version for deployment tracking.\n *\n * @default process.env.OTEL_SERVICE_VERSION\n */\n version?: string;\n\n /**\n * Enable log export to Grafana Cloud (Loki) via OTLP.\n * When true, configures logRecordProcessors so OTel Logs API records are exported.\n *\n * @default true\n */\n enableLogs?: boolean;\n\n /**\n * Custom log record processors (advanced).\n * Overrides the default OTLP log processor when enableLogs is true.\n */\n logRecordProcessors?: LogRecordProcessor[];\n}\n\nfunction normalizeHeaders(\n headers: string | Record<string, string> | undefined,\n): Record<string, string> | undefined {\n if (!headers) return undefined;\n if (typeof headers === 'object') return headers;\n const out: Record<string, string> = {};\n for (const pair of headers.split(',')) {\n const [key, ...valueParts] = pair.split('=');\n if (key && valueParts.length > 0) {\n let value = valueParts.join('=').trim();\n value = value.replaceAll('%20', ' ');\n out[key.trim()] = value;\n }\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\n/**\n * Create an autotel configuration for Grafana Cloud OTLP.\n *\n * Sends traces (Tempo), metrics (Mimir), and optionally logs (Loki) to the\n * Grafana Cloud OTLP gateway. Endpoint and headers come from the stack's\n * Connections → OpenTelemetry → Configure tile.\n *\n * @param config - Grafana Cloud configuration options\n * @returns AutotelConfig ready to pass to init()\n */\nexport function createGrafanaConfig(\n config: GrafanaPresetConfig,\n): AutotelConfig {\n const {\n endpoint,\n headers: headersInput,\n service,\n environment,\n version,\n enableLogs = true,\n logRecordProcessors,\n } = config;\n\n if (!endpoint) {\n throw new Error(\n 'Grafana Cloud endpoint is required. Get it from: Grafana Cloud → your stack → Connections → OpenTelemetry → Configure',\n );\n }\n\n const headers = normalizeHeaders(headersInput);\n const base = endpoint.replace(/\\/v1\\/(traces|metrics|logs)$/, '');\n const logsUrl = `${base}${base.endsWith('/') ? '' : '/'}v1/logs`;\n\n const result: AutotelConfig = {\n service,\n environment,\n version,\n endpoint,\n headers,\n metrics: true,\n };\n\n if (enableLogs) {\n if (logRecordProcessors) {\n result.logRecordProcessors = logRecordProcessors;\n } else {\n try {\n const pkgRequire = createRequire(import.meta.url);\n const { BatchLogRecordProcessor } = pkgRequire(\n '@opentelemetry/sdk-logs',\n );\n const { OTLPLogExporter } = pkgRequire(\n '@opentelemetry/exporter-logs-otlp-http',\n );\n result.logRecordProcessors = [\n new BatchLogRecordProcessor(\n new OTLPLogExporter({\n url: logsUrl,\n headers,\n }),\n ),\n ];\n } catch {\n throw new Error(\n 'Log export requires @opentelemetry/sdk-logs and @opentelemetry/exporter-logs-otlp-http. ' +\n 'Install them or set enableLogs: false.',\n );\n }\n }\n }\n\n return result;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autotel-backends",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.11.0",
|
|
4
4
|
"description": "Vendor backend configurations for Autotel (Honeycomb, Datadog, etc.)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,6 +22,10 @@
|
|
|
22
22
|
"./google-cloud": {
|
|
23
23
|
"types": "./dist/google-cloud.d.ts",
|
|
24
24
|
"import": "./dist/google-cloud.js"
|
|
25
|
+
},
|
|
26
|
+
"./grafana": {
|
|
27
|
+
"types": "./dist/grafana.d.ts",
|
|
28
|
+
"import": "./dist/grafana.js"
|
|
25
29
|
}
|
|
26
30
|
},
|
|
27
31
|
"files": [
|
|
@@ -47,29 +51,23 @@
|
|
|
47
51
|
"author": "Jag Reehal <jag@jagreehal.com> (https://jagreehal.com)",
|
|
48
52
|
"license": "MIT",
|
|
49
53
|
"dependencies": {
|
|
50
|
-
"
|
|
54
|
+
"@opentelemetry/exporter-logs-otlp-http": ">=0.212.0",
|
|
55
|
+
"@opentelemetry/sdk-logs": ">=0.212.0",
|
|
56
|
+
"autotel": "2.22.0"
|
|
51
57
|
},
|
|
52
58
|
"peerDependencies": {
|
|
53
|
-
"@opentelemetry/exporter-
|
|
54
|
-
"@opentelemetry/exporter-
|
|
55
|
-
"@opentelemetry/
|
|
56
|
-
"
|
|
57
|
-
"@opentelemetry/sdk-metrics": ">=2.5.0",
|
|
58
|
-
"google-auth-library": ">=10.5.0"
|
|
59
|
+
"@opentelemetry/exporter-metrics-otlp-http": ">=0.212.0",
|
|
60
|
+
"@opentelemetry/exporter-trace-otlp-http": ">=0.212.0",
|
|
61
|
+
"@opentelemetry/sdk-metrics": ">=2.5.1",
|
|
62
|
+
"google-auth-library": ">=10.6.1"
|
|
59
63
|
},
|
|
60
64
|
"peerDependenciesMeta": {
|
|
61
|
-
"@opentelemetry/exporter-logs-otlp-http": {
|
|
62
|
-
"optional": true
|
|
63
|
-
},
|
|
64
65
|
"@opentelemetry/exporter-metrics-otlp-http": {
|
|
65
66
|
"optional": true
|
|
66
67
|
},
|
|
67
68
|
"@opentelemetry/exporter-trace-otlp-http": {
|
|
68
69
|
"optional": true
|
|
69
70
|
},
|
|
70
|
-
"@opentelemetry/sdk-logs": {
|
|
71
|
-
"optional": true
|
|
72
|
-
},
|
|
73
71
|
"@opentelemetry/sdk-metrics": {
|
|
74
72
|
"optional": true
|
|
75
73
|
},
|
|
@@ -78,9 +76,9 @@
|
|
|
78
76
|
}
|
|
79
77
|
},
|
|
80
78
|
"devDependencies": {
|
|
81
|
-
"@types/node": "^25.
|
|
82
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
83
|
-
"@typescript-eslint/parser": "^8.
|
|
79
|
+
"@types/node": "^25.3.3",
|
|
80
|
+
"@typescript-eslint/eslint-plugin": "^8.56.1",
|
|
81
|
+
"@typescript-eslint/parser": "^8.56.1",
|
|
84
82
|
"eslint-config-prettier": "^10.1.8",
|
|
85
83
|
"eslint-plugin-unicorn": "^63.0.0",
|
|
86
84
|
"tsup": "^8.5.1",
|
package/src/datadog.ts
CHANGED
|
@@ -105,8 +105,6 @@ export interface DatadogPresetConfig {
|
|
|
105
105
|
* });
|
|
106
106
|
* ```
|
|
107
107
|
*
|
|
108
|
-
* Requires peer dependencies: @opentelemetry/sdk-logs, @opentelemetry/exporter-logs-otlp-http
|
|
109
|
-
*
|
|
110
108
|
* @default false
|
|
111
109
|
*/
|
|
112
110
|
enableLogs?: boolean;
|
|
@@ -310,21 +308,17 @@ export function createDatadogConfig(
|
|
|
310
308
|
} else {
|
|
311
309
|
// Create default OTLP log exporter
|
|
312
310
|
try {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
const userRequire = createRequire(process.cwd() + '/package.json');
|
|
316
|
-
|
|
317
|
-
const { BatchLogRecordProcessor } = userRequire(
|
|
311
|
+
const pkgRequire = createRequire(import.meta.url);
|
|
312
|
+
const { BatchLogRecordProcessor } = pkgRequire(
|
|
318
313
|
'@opentelemetry/sdk-logs',
|
|
319
314
|
);
|
|
320
|
-
const { OTLPLogExporter } =
|
|
315
|
+
const { OTLPLogExporter } = pkgRequire(
|
|
321
316
|
'@opentelemetry/exporter-logs-otlp-http',
|
|
322
317
|
);
|
|
323
318
|
|
|
324
319
|
cloudConfig.logRecordProcessors = [
|
|
325
320
|
new BatchLogRecordProcessor(
|
|
326
321
|
new OTLPLogExporter({
|
|
327
|
-
// Logs use /v1/logs path (SDK appends this to endpoint)
|
|
328
322
|
url: `${otlpEndpoint}/v1/logs`,
|
|
329
323
|
headers: {
|
|
330
324
|
'dd-api-key': apiKey,
|
|
@@ -334,8 +328,8 @@ export function createDatadogConfig(
|
|
|
334
328
|
];
|
|
335
329
|
} catch {
|
|
336
330
|
throw new Error(
|
|
337
|
-
'Log export requires
|
|
338
|
-
'Install them
|
|
331
|
+
'Log export requires @opentelemetry/sdk-logs and @opentelemetry/exporter-logs-otlp-http. ' +
|
|
332
|
+
'Install them or set enableLogs: false.',
|
|
339
333
|
);
|
|
340
334
|
}
|
|
341
335
|
}
|
package/src/grafana.ts
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grafana Cloud preset for autotel
|
|
3
|
+
*
|
|
4
|
+
* Provides a simplified configuration helper for sending traces, metrics,
|
|
5
|
+
* and logs to Grafana Cloud via the OTLP gateway.
|
|
6
|
+
*
|
|
7
|
+
* Get your endpoint and headers from:
|
|
8
|
+
* Grafana Cloud Portal → your stack → Connections → OpenTelemetry → Configure
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { init } from 'autotel';
|
|
13
|
+
* import { createGrafanaConfig } from 'autotel-backends/grafana';
|
|
14
|
+
*
|
|
15
|
+
* init(createGrafanaConfig({
|
|
16
|
+
* endpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT!,
|
|
17
|
+
* headers: process.env.OTEL_EXPORTER_OTLP_HEADERS,
|
|
18
|
+
* service: 'my-app',
|
|
19
|
+
* enableLogs: true,
|
|
20
|
+
* }));
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { createRequire } from 'node:module';
|
|
25
|
+
import type { AutotelConfig } from 'autotel';
|
|
26
|
+
import type { LogRecordProcessor } from '@opentelemetry/sdk-logs';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Configuration options for Grafana Cloud preset
|
|
30
|
+
*/
|
|
31
|
+
export interface GrafanaPresetConfig {
|
|
32
|
+
/**
|
|
33
|
+
* OTLP gateway endpoint (required).
|
|
34
|
+
* From Grafana Cloud: Stack → Connections → OpenTelemetry → Configure.
|
|
35
|
+
* Example: https://otlp-gateway-prod-gb-south-1.grafana.net/otlp
|
|
36
|
+
*/
|
|
37
|
+
endpoint: string;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* OTLP authentication headers.
|
|
41
|
+
* From the same Configure tile; usually Basic auth.
|
|
42
|
+
* Example: "Authorization=Basic%20BASE64_INSTANCE_ID_AND_TOKEN"
|
|
43
|
+
* or object: { Authorization: 'Basic ...' }
|
|
44
|
+
*/
|
|
45
|
+
headers?: string | Record<string, string>;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Service name (required).
|
|
49
|
+
* Appears in Tempo, Mimir, and Loki as service_name.
|
|
50
|
+
*/
|
|
51
|
+
service: string;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Deployment environment (e.g. 'production', 'staging').
|
|
55
|
+
*
|
|
56
|
+
* @default process.env.NODE_ENV || 'development'
|
|
57
|
+
*/
|
|
58
|
+
environment?: string;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Service version for deployment tracking.
|
|
62
|
+
*
|
|
63
|
+
* @default process.env.OTEL_SERVICE_VERSION
|
|
64
|
+
*/
|
|
65
|
+
version?: string;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Enable log export to Grafana Cloud (Loki) via OTLP.
|
|
69
|
+
* When true, configures logRecordProcessors so OTel Logs API records are exported.
|
|
70
|
+
*
|
|
71
|
+
* @default true
|
|
72
|
+
*/
|
|
73
|
+
enableLogs?: boolean;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Custom log record processors (advanced).
|
|
77
|
+
* Overrides the default OTLP log processor when enableLogs is true.
|
|
78
|
+
*/
|
|
79
|
+
logRecordProcessors?: LogRecordProcessor[];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function normalizeHeaders(
|
|
83
|
+
headers: string | Record<string, string> | undefined,
|
|
84
|
+
): Record<string, string> | undefined {
|
|
85
|
+
if (!headers) return undefined;
|
|
86
|
+
if (typeof headers === 'object') return headers;
|
|
87
|
+
const out: Record<string, string> = {};
|
|
88
|
+
for (const pair of headers.split(',')) {
|
|
89
|
+
const [key, ...valueParts] = pair.split('=');
|
|
90
|
+
if (key && valueParts.length > 0) {
|
|
91
|
+
let value = valueParts.join('=').trim();
|
|
92
|
+
value = value.replaceAll('%20', ' ');
|
|
93
|
+
out[key.trim()] = value;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Create an autotel configuration for Grafana Cloud OTLP.
|
|
101
|
+
*
|
|
102
|
+
* Sends traces (Tempo), metrics (Mimir), and optionally logs (Loki) to the
|
|
103
|
+
* Grafana Cloud OTLP gateway. Endpoint and headers come from the stack's
|
|
104
|
+
* Connections → OpenTelemetry → Configure tile.
|
|
105
|
+
*
|
|
106
|
+
* @param config - Grafana Cloud configuration options
|
|
107
|
+
* @returns AutotelConfig ready to pass to init()
|
|
108
|
+
*/
|
|
109
|
+
export function createGrafanaConfig(
|
|
110
|
+
config: GrafanaPresetConfig,
|
|
111
|
+
): AutotelConfig {
|
|
112
|
+
const {
|
|
113
|
+
endpoint,
|
|
114
|
+
headers: headersInput,
|
|
115
|
+
service,
|
|
116
|
+
environment,
|
|
117
|
+
version,
|
|
118
|
+
enableLogs = true,
|
|
119
|
+
logRecordProcessors,
|
|
120
|
+
} = config;
|
|
121
|
+
|
|
122
|
+
if (!endpoint) {
|
|
123
|
+
throw new Error(
|
|
124
|
+
'Grafana Cloud endpoint is required. Get it from: Grafana Cloud → your stack → Connections → OpenTelemetry → Configure',
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const headers = normalizeHeaders(headersInput);
|
|
129
|
+
const base = endpoint.replace(/\/v1\/(traces|metrics|logs)$/, '');
|
|
130
|
+
const logsUrl = `${base}${base.endsWith('/') ? '' : '/'}v1/logs`;
|
|
131
|
+
|
|
132
|
+
const result: AutotelConfig = {
|
|
133
|
+
service,
|
|
134
|
+
environment,
|
|
135
|
+
version,
|
|
136
|
+
endpoint,
|
|
137
|
+
headers,
|
|
138
|
+
metrics: true,
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
if (enableLogs) {
|
|
142
|
+
if (logRecordProcessors) {
|
|
143
|
+
result.logRecordProcessors = logRecordProcessors;
|
|
144
|
+
} else {
|
|
145
|
+
try {
|
|
146
|
+
const pkgRequire = createRequire(import.meta.url);
|
|
147
|
+
const { BatchLogRecordProcessor } = pkgRequire(
|
|
148
|
+
'@opentelemetry/sdk-logs',
|
|
149
|
+
);
|
|
150
|
+
const { OTLPLogExporter } = pkgRequire(
|
|
151
|
+
'@opentelemetry/exporter-logs-otlp-http',
|
|
152
|
+
);
|
|
153
|
+
result.logRecordProcessors = [
|
|
154
|
+
new BatchLogRecordProcessor(
|
|
155
|
+
new OTLPLogExporter({
|
|
156
|
+
url: logsUrl,
|
|
157
|
+
headers,
|
|
158
|
+
}),
|
|
159
|
+
),
|
|
160
|
+
];
|
|
161
|
+
} catch {
|
|
162
|
+
throw new Error(
|
|
163
|
+
'Log export requires @opentelemetry/sdk-logs and @opentelemetry/exporter-logs-otlp-http. ' +
|
|
164
|
+
'Install them or set enableLogs: false.',
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return result;
|
|
171
|
+
}
|