autotel-backends 2.12.29 → 2.12.30

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.
@@ -1,118 +1,121 @@
1
- import { createRequire } from 'module';
2
-
3
- // src/google-cloud.ts
4
- var DEFAULT_ENDPOINT = "https://telemetry.googleapis.com";
1
+ import { createRequire } from "node:module";
2
+ //#region src/google-cloud.ts
3
+ /**
4
+ * Google Cloud preset for autotel
5
+ *
6
+ * Sends traces (and optionally metrics) to Google Cloud Observability via the
7
+ * Telemetry (OTLP) API. Uses Application Default Credentials (ADC) for auth.
8
+ *
9
+ * @example Direct export to GCP (with google-auth-library)
10
+ * ```typescript
11
+ * import { init } from 'autotel';
12
+ * import { createGoogleCloudConfig } from 'autotel-backends/google-cloud';
13
+ *
14
+ * init(createGoogleCloudConfig({
15
+ * projectId: process.env.GOOGLE_CLOUD_PROJECT!,
16
+ * service: 'my-app',
17
+ * }));
18
+ * ```
19
+ *
20
+ * @example Via OpenTelemetry Collector (no auth in app)
21
+ * ```typescript
22
+ * init(createGoogleCloudConfig({
23
+ * projectId: process.env.GOOGLE_CLOUD_PROJECT!,
24
+ * service: 'my-app',
25
+ * useCollector: true,
26
+ * collectorEndpoint: 'http://localhost:4318',
27
+ * }));
28
+ * ```
29
+ */
30
+ /** Default Telemetry API base URL (OTLP). */
31
+ const DEFAULT_ENDPOINT = "https://telemetry.googleapis.com";
32
+ /**
33
+ * Create an autotel configuration for Google Cloud Observability (Telemetry API).
34
+ *
35
+ * - With useCollector: false (default), exports directly to the Telemetry API
36
+ * using Application Default Credentials. Requires optional peer dependency
37
+ * google-auth-library for auth. Install: pnpm add google-auth-library
38
+ *
39
+ * - With useCollector: true, sends OTLP to a local Collector; the Collector
40
+ * forwards to GCP with ADC. No google-auth-library needed in the app.
41
+ *
42
+ * @param config - Google Cloud preset options
43
+ * @returns AutotelConfig ready to pass to init()
44
+ */
5
45
  function createGoogleCloudConfig(config) {
6
- const {
7
- projectId,
8
- service,
9
- environment,
10
- version,
11
- useCollector = false,
12
- collectorEndpoint = "http://localhost:4318",
13
- endpoint = DEFAULT_ENDPOINT
14
- } = config;
15
- if (!projectId) {
16
- throw new Error(
17
- "Google Cloud projectId is required. Set it or use process.env.GOOGLE_CLOUD_PROJECT."
18
- );
19
- }
20
- const baseConfig = {
21
- service,
22
- environment,
23
- version
24
- };
25
- if (useCollector) {
26
- return {
27
- ...baseConfig,
28
- endpoint: collectorEndpoint,
29
- // x-goog-user-project for quota when Collector forwards to GCP
30
- headers: { "x-goog-user-project": projectId }
31
- };
32
- }
33
- try {
34
- const userRequire = createRequire(process.cwd() + "/package.json");
35
- const { GoogleAuth } = userRequire("google-auth-library");
36
- const { OTLPTraceExporter } = userRequire(
37
- "@opentelemetry/exporter-trace-otlp-http"
38
- );
39
- const tracesUrl = `${endpoint}/v1/traces`;
40
- const auth = new GoogleAuth({
41
- scopes: ["https://www.googleapis.com/auth/cloud-platform"]
42
- });
43
- const gcpTraceExporter = createGcpAuthTraceExporter(
44
- tracesUrl,
45
- projectId,
46
- auth,
47
- OTLPTraceExporter
48
- );
49
- return {
50
- ...baseConfig,
51
- // Structurally compatible with SpanExporter from @opentelemetry/sdk-trace-base
52
- spanExporters: [
53
- gcpTraceExporter
54
- ]
55
- };
56
- } catch (error) {
57
- const message = error instanceof Error ? error.message : String(error);
58
- if (message.includes("google-auth-library") || message.includes("Cannot find module")) {
59
- throw new Error(
60
- "Direct export to Google Cloud requires google-auth-library. Install it: pnpm add google-auth-library. Or use useCollector: true and run an OpenTelemetry Collector with GCP auth.",
61
- { cause: error }
62
- );
63
- }
64
- throw error;
65
- }
46
+ const { projectId, service, environment, version, useCollector = false, collectorEndpoint = "http://localhost:4318", endpoint = DEFAULT_ENDPOINT } = config;
47
+ if (!projectId) throw new Error("Google Cloud projectId is required. Set it or use process.env.GOOGLE_CLOUD_PROJECT.");
48
+ const baseConfig = {
49
+ service,
50
+ environment,
51
+ version
52
+ };
53
+ if (useCollector) return {
54
+ ...baseConfig,
55
+ endpoint: collectorEndpoint,
56
+ headers: { "x-goog-user-project": projectId }
57
+ };
58
+ try {
59
+ const userRequire = createRequire(process.cwd() + "/package.json");
60
+ const { GoogleAuth } = userRequire("google-auth-library");
61
+ const { OTLPTraceExporter } = userRequire("@opentelemetry/exporter-trace-otlp-http");
62
+ const gcpTraceExporter = createGcpAuthTraceExporter(`${endpoint}/v1/traces`, projectId, new GoogleAuth({ scopes: ["https://www.googleapis.com/auth/cloud-platform"] }), OTLPTraceExporter);
63
+ return {
64
+ ...baseConfig,
65
+ spanExporters: [gcpTraceExporter]
66
+ };
67
+ } catch (error) {
68
+ const message = error instanceof Error ? error.message : String(error);
69
+ if (message.includes("google-auth-library") || message.includes("Cannot find module")) throw new Error("Direct export to Google Cloud requires google-auth-library. Install it: pnpm add google-auth-library. Or use useCollector: true and run an OpenTelemetry Collector with GCP auth.", { cause: error });
70
+ throw error;
71
+ }
66
72
  }
67
73
  function createGcpAuthTraceExporter(url, projectId, auth, OTLPTraceExporterCtor) {
68
- return new GcpAuthSpanExporter(url, projectId, auth, OTLPTraceExporterCtor);
74
+ return new GcpAuthSpanExporter(url, projectId, auth, OTLPTraceExporterCtor);
69
75
  }
70
76
  var GcpAuthSpanExporter = class {
71
- constructor(url, projectId, auth, OTLPTraceExporterCtor) {
72
- this.url = url;
73
- this.projectId = projectId;
74
- this.auth = auth;
75
- this.OTLPTraceExporterCtor = OTLPTraceExporterCtor;
76
- }
77
- url;
78
- projectId;
79
- auth;
80
- OTLPTraceExporterCtor;
81
- async export(spans, resultCallback) {
82
- try {
83
- const client = await this.auth.getClient();
84
- const tokenResponse = await client.getAccessToken();
85
- const token = tokenResponse.token;
86
- if (!token) {
87
- resultCallback({
88
- code: 1,
89
- error: new Error("No access token from ADC")
90
- });
91
- return;
92
- }
93
- const exporter = new this.OTLPTraceExporterCtor({
94
- url: this.url,
95
- headers: {
96
- Authorization: `Bearer ${token}`,
97
- "x-goog-user-project": this.projectId
98
- }
99
- });
100
- exporter.export(spans, resultCallback);
101
- } catch (error) {
102
- resultCallback({
103
- code: 1,
104
- error: error instanceof Error ? error : new Error(String(error))
105
- });
106
- }
107
- }
108
- forceFlush() {
109
- return Promise.resolve();
110
- }
111
- shutdown() {
112
- return Promise.resolve();
113
- }
77
+ url;
78
+ projectId;
79
+ auth;
80
+ OTLPTraceExporterCtor;
81
+ constructor(url, projectId, auth, OTLPTraceExporterCtor) {
82
+ this.url = url;
83
+ this.projectId = projectId;
84
+ this.auth = auth;
85
+ this.OTLPTraceExporterCtor = OTLPTraceExporterCtor;
86
+ }
87
+ async export(spans, resultCallback) {
88
+ try {
89
+ const token = (await (await this.auth.getClient()).getAccessToken()).token;
90
+ if (!token) {
91
+ resultCallback({
92
+ code: 1,
93
+ error: /* @__PURE__ */ new Error("No access token from ADC")
94
+ });
95
+ return;
96
+ }
97
+ new this.OTLPTraceExporterCtor({
98
+ url: this.url,
99
+ headers: {
100
+ Authorization: `Bearer ${token}`,
101
+ "x-goog-user-project": this.projectId
102
+ }
103
+ }).export(spans, resultCallback);
104
+ } catch (error) {
105
+ resultCallback({
106
+ code: 1,
107
+ error: error instanceof Error ? error : new Error(String(error))
108
+ });
109
+ }
110
+ }
111
+ forceFlush() {
112
+ return Promise.resolve();
113
+ }
114
+ shutdown() {
115
+ return Promise.resolve();
116
+ }
114
117
  };
115
-
118
+ //#endregion
116
119
  export { createGoogleCloudConfig };
117
- //# sourceMappingURL=google-cloud.js.map
120
+
118
121
  //# sourceMappingURL=google-cloud.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/google-cloud.ts"],"names":[],"mappings":"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","file":"google-cloud.js","sourcesContent":["/**\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,"file":"google-cloud.js","names":[],"sources":["../src/google-cloud.ts"],"sourcesContent":["/**\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"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,MAAM,mBAAmB;;;;;;;;;;;;;;AAyEzB,SAAgB,wBACd,QACe;CACf,MAAM,EACJ,WACA,SACA,aACA,SACA,eAAe,OACf,oBAAoB,yBACpB,WAAW,qBACT;CAEJ,IAAI,CAAC,WACH,MAAM,IAAI,MACR,qFACF;CAGF,MAAM,aAA4B;EAChC;EACA;EACA;CACF;CAEA,IAAI,cACF,OAAO;EACL,GAAG;EACH,UAAU;EAEV,SAAS,EAAE,uBAAuB,UAAU;CAC9C;CAIF,IAAI;EACF,MAAM,cAAc,cAAc,QAAQ,IAAI,IAAI,eAAe;EACjE,MAAM,EAAE,eAAe,YAAY,qBAAqB;EACxD,MAAM,EAAE,sBAAsB,YAC5B,yCACF;EAOA,MAAM,mBAAmB,2BACvB,GANmB,SAAS,aAO5B,WACA,IAPe,WAAW,EAC1B,QAAQ,CAAC,gDAAgD,EAC3D,CAKK,GACH,iBACF;EAEA,OAAO;GACL,GAAG;GAEH,eAAe,CACb,gBACF;EACF;CACF,SAAS,OAAO;EACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EACrE,IACE,QAAQ,SAAS,qBAAqB,KACtC,QAAQ,SAAS,oBAAoB,GAErC,MAAM,IAAI,MACR,qLAGA,EAAE,OAAO,MAAM,CACjB;EAEF,MAAM;CACR;AACF;AAYA,SAAS,2BACP,KACA,WACA,MACA,uBACkB;CAClB,OAAO,IAAI,oBAAoB,KAAK,WAAW,MAAM,qBAAqB;AAC5E;AAEA,IAAM,sBAAN,MAAsD;CAEjC;CACA;CACA;CACA;CAJnB,YACE,KACA,WACA,MACA,uBACA;EAJiB,KAAA,MAAA;EACA,KAAA,YAAA;EACA,KAAA,OAAA;EACA,KAAA,wBAAA;CAChB;CAEH,MAAM,OACJ,OACA,gBACe;EACf,IAAI;GAGF,MAAM,SAAQ,OADc,MADP,KAAK,KAAK,UAAU,EAAA,CACN,eAAe,EAAA,CACtB;GAC5B,IAAI,CAAC,OAAO;IACV,eAAe;KACb,MAAM;KACN,uBAAO,IAAI,MAAM,0BAA0B;IAC7C,CAAC;IACD;GACF;GAQA,IAPqB,KAAK,sBAAsB;IAC9C,KAAK,KAAK;IACV,SAAS;KACP,eAAe,UAAU;KACzB,uBAAuB,KAAK;IAC9B;GACF,CACO,CAAC,CAAC,OAAO,OAAO,cAAc;EACvC,SAAS,OAAO;GACd,eAAe;IACb,MAAM;IACN,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;GACjE,CAAC;EACH;CACF;CAEA,aAA4B;EAC1B,OAAO,QAAQ,QAAQ;CACzB;CAEA,WAA0B;EACxB,OAAO,QAAQ,QAAQ;CACzB;AACF"}
package/dist/grafana.cjs CHANGED
@@ -1,81 +1,81 @@
1
- 'use strict';
2
-
3
- var module$1 = require('module');
4
-
5
- var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
6
- // src/grafana.ts
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let node_module = require("node:module");
3
+ //#region src/grafana.ts
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
+ */
7
26
  function normalizeHeaders(headers) {
8
- if (!headers) return void 0;
9
- if (typeof headers === "object") return headers;
10
- const out = {};
11
- for (const pair of headers.split(",")) {
12
- const [key, ...valueParts] = pair.split("=");
13
- if (key && valueParts.length > 0) {
14
- let value = valueParts.join("=").trim();
15
- value = value.replaceAll("%20", " ");
16
- out[key.trim()] = value;
17
- }
18
- }
19
- return Object.keys(out).length > 0 ? out : void 0;
27
+ if (!headers) return void 0;
28
+ if (typeof headers === "object") return headers;
29
+ const out = {};
30
+ for (const pair of headers.split(",")) {
31
+ const [key, ...valueParts] = pair.split("=");
32
+ if (key && valueParts.length > 0) {
33
+ let value = valueParts.join("=").trim();
34
+ value = value.replaceAll("%20", " ");
35
+ out[key.trim()] = value;
36
+ }
37
+ }
38
+ return Object.keys(out).length > 0 ? out : void 0;
20
39
  }
40
+ /**
41
+ * Create an autotel configuration for Grafana Cloud OTLP.
42
+ *
43
+ * Sends traces (Tempo), metrics (Mimir), and optionally logs (Loki) to the
44
+ * Grafana Cloud OTLP gateway. Endpoint and headers come from the stack's
45
+ * Connections → OpenTelemetry → Configure tile.
46
+ *
47
+ * @param config - Grafana Cloud configuration options
48
+ * @returns AutotelConfig ready to pass to init()
49
+ */
21
50
  function createGrafanaConfig(config) {
22
- const {
23
- endpoint,
24
- headers: headersInput,
25
- service,
26
- environment,
27
- version,
28
- enableLogs = true,
29
- logRecordProcessors
30
- } = config;
31
- if (!endpoint) {
32
- throw new Error(
33
- "Grafana Cloud endpoint is required. Get it from: Grafana Cloud \u2192 your stack \u2192 Connections \u2192 OpenTelemetry \u2192 Configure"
34
- );
35
- }
36
- const headers = normalizeHeaders(headersInput);
37
- const base = endpoint.replace(/\/v1\/(traces|metrics|logs)$/, "");
38
- const logsUrl = `${base}${base.endsWith("/") ? "" : "/"}v1/logs`;
39
- const result = {
40
- service,
41
- environment,
42
- version,
43
- endpoint,
44
- headers,
45
- metrics: true
46
- };
47
- if (enableLogs) {
48
- if (logRecordProcessors) {
49
- result.logRecordProcessors = logRecordProcessors;
50
- } else {
51
- try {
52
- const pkgRequire = module$1.createRequire(
53
- typeof __filename === "string" ? __filename : (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('grafana.cjs', document.baseURI).href))
54
- );
55
- const { BatchLogRecordProcessor } = pkgRequire(
56
- "@opentelemetry/sdk-logs"
57
- );
58
- const { OTLPLogExporter } = pkgRequire(
59
- "@opentelemetry/exporter-logs-otlp-http"
60
- );
61
- result.logRecordProcessors = [
62
- new BatchLogRecordProcessor(
63
- new OTLPLogExporter({
64
- url: logsUrl,
65
- headers
66
- })
67
- )
68
- ];
69
- } catch {
70
- throw new Error(
71
- "Log export requires @opentelemetry/sdk-logs and @opentelemetry/exporter-logs-otlp-http. Install them or set enableLogs: false."
72
- );
73
- }
74
- }
75
- }
76
- return result;
51
+ const { endpoint, headers: headersInput, service, environment, version, enableLogs = true, logRecordProcessors } = config;
52
+ if (!endpoint) throw new Error("Grafana Cloud endpoint is required. Get it from: Grafana Cloud → your stack → Connections → OpenTelemetry → Configure");
53
+ const headers = normalizeHeaders(headersInput);
54
+ const base = endpoint.replace(/\/v1\/(traces|metrics|logs)$/, "");
55
+ const logsUrl = `${base}${base.endsWith("/") ? "" : "/"}v1/logs`;
56
+ const result = {
57
+ service,
58
+ environment,
59
+ version,
60
+ endpoint,
61
+ headers,
62
+ metrics: true
63
+ };
64
+ if (enableLogs) if (logRecordProcessors) result.logRecordProcessors = logRecordProcessors;
65
+ else try {
66
+ const pkgRequire = (0, node_module.createRequire)(typeof __filename === "string" ? __filename : require("url").pathToFileURL(__filename).href);
67
+ const { BatchLogRecordProcessor } = pkgRequire("@opentelemetry/sdk-logs");
68
+ const { OTLPLogExporter } = pkgRequire("@opentelemetry/exporter-logs-otlp-http");
69
+ result.logRecordProcessors = [new BatchLogRecordProcessor(new OTLPLogExporter({
70
+ url: logsUrl,
71
+ headers
72
+ }))];
73
+ } catch {
74
+ throw new Error("Log export requires @opentelemetry/sdk-logs and @opentelemetry/exporter-logs-otlp-http. Install them or set enableLogs: false.");
75
+ }
76
+ return result;
77
77
  }
78
-
78
+ //#endregion
79
79
  exports.createGrafanaConfig = createGrafanaConfig;
80
- //# sourceMappingURL=grafana.cjs.map
80
+
81
81
  //# sourceMappingURL=grafana.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/grafana.ts"],"names":["createRequire"],"mappings":";;;;;;AAqFA,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,GAAaA,sBAAA;AAAA,UACjB,OAAO,UAAA,KAAe,QAAA,GAAW,UAAA,GAAa;AAAY,SAC5D;AACA,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.cjs","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// See packages/autotel/src/node-require.ts for why the __filename fallback\n// is necessary alongside import.meta.url.\ndeclare const __filename: string | undefined;\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(\n typeof __filename === 'string' ? __filename : import.meta.url,\n );\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"]}
1
+ {"version":3,"file":"grafana.cjs","names":[],"sources":["../src/grafana.ts"],"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// See packages/autotel/src/node-require.ts for why the __filename fallback\n// is necessary alongside import.meta.url.\ndeclare const __filename: string | undefined;\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(\n typeof __filename === 'string' ? __filename : import.meta.url,\n );\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"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAqFA,SAAS,iBACP,SACoC;CACpC,IAAI,CAAC,SAAS,OAAO,KAAA;CACrB,IAAI,OAAO,YAAY,UAAU,OAAO;CACxC,MAAM,MAA8B,CAAC;CACrC,KAAK,MAAM,QAAQ,QAAQ,MAAM,GAAG,GAAG;EACrC,MAAM,CAAC,KAAK,GAAG,cAAc,KAAK,MAAM,GAAG;EAC3C,IAAI,OAAO,WAAW,SAAS,GAAG;GAChC,IAAI,QAAQ,WAAW,KAAK,GAAG,CAAC,CAAC,KAAK;GACtC,QAAQ,MAAM,WAAW,OAAO,GAAG;GACnC,IAAI,IAAI,KAAK,KAAK;EACpB;CACF;CACA,OAAO,OAAO,KAAK,GAAG,CAAC,CAAC,SAAS,IAAI,MAAM,KAAA;AAC7C;;;;;;;;;;;AAYA,SAAgB,oBACd,QACe;CACf,MAAM,EACJ,UACA,SAAS,cACT,SACA,aACA,SACA,aAAa,MACb,wBACE;CAEJ,IAAI,CAAC,UACH,MAAM,IAAI,MACR,uHACF;CAGF,MAAM,UAAU,iBAAiB,YAAY;CAC7C,MAAM,OAAO,SAAS,QAAQ,gCAAgC,EAAE;CAChE,MAAM,UAAU,GAAG,OAAO,KAAK,SAAS,GAAG,IAAI,KAAK,IAAI;CAExD,MAAM,SAAwB;EAC5B;EACA;EACA;EACA;EACA;EACA,SAAS;CACX;CAEA,IAAI,YACF,IAAI,qBACF,OAAO,sBAAsB;MAE7B,IAAI;EACF,MAAM,cAAA,GAAA,YAAA,cAAA,CACJ,OAAO,eAAe,WAAW,aAAA,QAAA,KAAA,CAAA,CAAA,cAAA,UAAA,CAAA,CAAA,IACnC;EACA,MAAM,EAAE,4BAA4B,WAClC,yBACF;EACA,MAAM,EAAE,oBAAoB,WAC1B,wCACF;EACA,OAAO,sBAAsB,CAC3B,IAAI,wBACF,IAAI,gBAAgB;GAClB,KAAK;GACL;EACF,CAAC,CACH,CACF;CACF,QAAQ;EACN,MAAM,IAAI,MACR,gIAEF;CACF;CAIJ,OAAO;AACT"}
@@ -1,75 +1,53 @@
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
- */
1
+ import { AutotelConfig } from "autotel";
2
+ import { LogRecordProcessor } from "@opentelemetry/sdk-logs";
26
3
 
4
+ //#region src/grafana.d.ts
27
5
  /**
28
6
  * Configuration options for Grafana Cloud preset
29
7
  */
30
8
  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[];
9
+ /**
10
+ * OTLP gateway endpoint (required).
11
+ * From Grafana Cloud: Stack → Connections → OpenTelemetry → Configure.
12
+ * Example: https://otlp-gateway-prod-gb-south-1.grafana.net/otlp
13
+ */
14
+ endpoint: string;
15
+ /**
16
+ * OTLP authentication headers.
17
+ * From the same Configure tile; usually Basic auth.
18
+ * Example: "Authorization=Basic%20BASE64_INSTANCE_ID_AND_TOKEN"
19
+ * or object: { Authorization: 'Basic ...' }
20
+ */
21
+ headers?: string | Record<string, string>;
22
+ /**
23
+ * Service name (required).
24
+ * Appears in Tempo, Mimir, and Loki as service_name.
25
+ */
26
+ service: string;
27
+ /**
28
+ * Deployment environment (e.g. 'production', 'staging').
29
+ *
30
+ * @default process.env.NODE_ENV || 'development'
31
+ */
32
+ environment?: string;
33
+ /**
34
+ * Service version for deployment tracking.
35
+ *
36
+ * @default process.env.OTEL_SERVICE_VERSION
37
+ */
38
+ version?: string;
39
+ /**
40
+ * Enable log export to Grafana Cloud (Loki) via OTLP.
41
+ * When true, configures logRecordProcessors so OTel Logs API records are exported.
42
+ *
43
+ * @default true
44
+ */
45
+ enableLogs?: boolean;
46
+ /**
47
+ * Custom log record processors (advanced).
48
+ * Overrides the default OTLP log processor when enableLogs is true.
49
+ */
50
+ logRecordProcessors?: LogRecordProcessor[];
73
51
  }
74
52
  /**
75
53
  * Create an autotel configuration for Grafana Cloud OTLP.
@@ -82,5 +60,6 @@ interface GrafanaPresetConfig {
82
60
  * @returns AutotelConfig ready to pass to init()
83
61
  */
84
62
  declare function createGrafanaConfig(config: GrafanaPresetConfig): AutotelConfig;
85
-
86
- export { type GrafanaPresetConfig, createGrafanaConfig };
63
+ //#endregion
64
+ export { GrafanaPresetConfig, createGrafanaConfig };
65
+ //# sourceMappingURL=grafana.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grafana.d.cts","names":[],"sources":["../src/grafana.ts"],"mappings":";;;;;;;UAkCiB,mBAAA;;;;;;EAMf,QAAA;;;;;;;EAQA,OAAA,YAAmB,MAAA;;;;;EAMnB,OAAA;;;;;;EAOA,WAAA;;;;;;EAOA,OAAA;;;;;;;EAQA,UAAA;;;;;EAMA,mBAAA,GAAsB,kBAAkB;AAAA;;;;;;;;;;;iBA8B1B,mBAAA,CACd,MAAA,EAAQ,mBAAA,GACP,aAAa"}