@logtape/otel 1.3.0-dev.379 → 1.3.0-dev.381

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/deno.json CHANGED
@@ -1,18 +1,20 @@
1
1
  {
2
2
  "name": "@logtape/otel",
3
- "version": "1.3.0-dev.379+84654e7a",
3
+ "version": "1.3.0-dev.381+eef5c598",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./src/mod.ts"
7
7
  },
8
8
  "imports": {
9
9
  "@opentelemetry/api": "npm:@opentelemetry/api@^1.9.0",
10
- "@opentelemetry/api-logs": "npm:@opentelemetry/api-logs@^0.202.0",
11
- "@opentelemetry/exporter-logs-otlp-http": "npm:@opentelemetry/exporter-logs-otlp-http@^0.202.0",
12
- "@opentelemetry/otlp-exporter-base": "npm:@opentelemetry/otlp-exporter-base@^0.202.0",
13
- "@opentelemetry/resources": "npm:@opentelemetry/resources@^2.0.1",
14
- "@opentelemetry/sdk-logs": "npm:@opentelemetry/sdk-logs@^0.202.0",
15
- "@opentelemetry/semantic-conventions": "npm:@opentelemetry/semantic-conventions@^1.34.0"
10
+ "@opentelemetry/api-logs": "npm:@opentelemetry/api-logs@^0.208.0",
11
+ "@opentelemetry/exporter-logs-otlp-grpc": "npm:@opentelemetry/exporter-logs-otlp-grpc@^0.208.0",
12
+ "@opentelemetry/exporter-logs-otlp-http": "npm:@opentelemetry/exporter-logs-otlp-http@^0.208.0",
13
+ "@opentelemetry/exporter-logs-otlp-proto": "npm:@opentelemetry/exporter-logs-otlp-proto@^0.208.0",
14
+ "@opentelemetry/otlp-exporter-base": "npm:@opentelemetry/otlp-exporter-base@^0.208.0",
15
+ "@opentelemetry/resources": "npm:@opentelemetry/resources@^2.2.0",
16
+ "@opentelemetry/sdk-logs": "npm:@opentelemetry/sdk-logs@^0.208.0",
17
+ "@opentelemetry/semantic-conventions": "npm:@opentelemetry/semantic-conventions@^1.38.0"
16
18
  },
17
19
  "tasks": {
18
20
  "build": "pnpm build",
package/dist/deno.cjs CHANGED
@@ -1,17 +1,19 @@
1
1
 
2
2
  //#region deno.json
3
3
  var name = "@logtape/otel";
4
- var version = "1.3.0-dev.379+84654e7a";
4
+ var version = "1.3.0-dev.381+eef5c598";
5
5
  var license = "MIT";
6
6
  var exports$1 = { ".": "./src/mod.ts" };
7
7
  var imports = {
8
8
  "@opentelemetry/api": "npm:@opentelemetry/api@^1.9.0",
9
- "@opentelemetry/api-logs": "npm:@opentelemetry/api-logs@^0.202.0",
10
- "@opentelemetry/exporter-logs-otlp-http": "npm:@opentelemetry/exporter-logs-otlp-http@^0.202.0",
11
- "@opentelemetry/otlp-exporter-base": "npm:@opentelemetry/otlp-exporter-base@^0.202.0",
12
- "@opentelemetry/resources": "npm:@opentelemetry/resources@^2.0.1",
13
- "@opentelemetry/sdk-logs": "npm:@opentelemetry/sdk-logs@^0.202.0",
14
- "@opentelemetry/semantic-conventions": "npm:@opentelemetry/semantic-conventions@^1.34.0"
9
+ "@opentelemetry/api-logs": "npm:@opentelemetry/api-logs@^0.208.0",
10
+ "@opentelemetry/exporter-logs-otlp-grpc": "npm:@opentelemetry/exporter-logs-otlp-grpc@^0.208.0",
11
+ "@opentelemetry/exporter-logs-otlp-http": "npm:@opentelemetry/exporter-logs-otlp-http@^0.208.0",
12
+ "@opentelemetry/exporter-logs-otlp-proto": "npm:@opentelemetry/exporter-logs-otlp-proto@^0.208.0",
13
+ "@opentelemetry/otlp-exporter-base": "npm:@opentelemetry/otlp-exporter-base@^0.208.0",
14
+ "@opentelemetry/resources": "npm:@opentelemetry/resources@^2.2.0",
15
+ "@opentelemetry/sdk-logs": "npm:@opentelemetry/sdk-logs@^0.208.0",
16
+ "@opentelemetry/semantic-conventions": "npm:@opentelemetry/semantic-conventions@^1.38.0"
15
17
  };
16
18
  var tasks = {
17
19
  "build": "pnpm build",
package/dist/deno.js CHANGED
@@ -1,16 +1,18 @@
1
1
  //#region deno.json
2
2
  var name = "@logtape/otel";
3
- var version = "1.3.0-dev.379+84654e7a";
3
+ var version = "1.3.0-dev.381+eef5c598";
4
4
  var license = "MIT";
5
5
  var exports = { ".": "./src/mod.ts" };
6
6
  var imports = {
7
7
  "@opentelemetry/api": "npm:@opentelemetry/api@^1.9.0",
8
- "@opentelemetry/api-logs": "npm:@opentelemetry/api-logs@^0.202.0",
9
- "@opentelemetry/exporter-logs-otlp-http": "npm:@opentelemetry/exporter-logs-otlp-http@^0.202.0",
10
- "@opentelemetry/otlp-exporter-base": "npm:@opentelemetry/otlp-exporter-base@^0.202.0",
11
- "@opentelemetry/resources": "npm:@opentelemetry/resources@^2.0.1",
12
- "@opentelemetry/sdk-logs": "npm:@opentelemetry/sdk-logs@^0.202.0",
13
- "@opentelemetry/semantic-conventions": "npm:@opentelemetry/semantic-conventions@^1.34.0"
8
+ "@opentelemetry/api-logs": "npm:@opentelemetry/api-logs@^0.208.0",
9
+ "@opentelemetry/exporter-logs-otlp-grpc": "npm:@opentelemetry/exporter-logs-otlp-grpc@^0.208.0",
10
+ "@opentelemetry/exporter-logs-otlp-http": "npm:@opentelemetry/exporter-logs-otlp-http@^0.208.0",
11
+ "@opentelemetry/exporter-logs-otlp-proto": "npm:@opentelemetry/exporter-logs-otlp-proto@^0.208.0",
12
+ "@opentelemetry/otlp-exporter-base": "npm:@opentelemetry/otlp-exporter-base@^0.208.0",
13
+ "@opentelemetry/resources": "npm:@opentelemetry/resources@^2.2.0",
14
+ "@opentelemetry/sdk-logs": "npm:@opentelemetry/sdk-logs@^0.208.0",
15
+ "@opentelemetry/semantic-conventions": "npm:@opentelemetry/semantic-conventions@^1.38.0"
14
16
  };
15
17
  var tasks = {
16
18
  "build": "pnpm build",
package/dist/deno.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"deno.js","names":[],"sources":["../deno.json"],"sourcesContent":["{\n \"name\": \"@logtape/otel\",\n \"version\": \"1.3.0-dev.379+84654e7a\",\n \"license\": \"MIT\",\n \"exports\": {\n \".\": \"./src/mod.ts\"\n },\n \"imports\": {\n \"@opentelemetry/api\": \"npm:@opentelemetry/api@^1.9.0\",\n \"@opentelemetry/api-logs\": \"npm:@opentelemetry/api-logs@^0.202.0\",\n \"@opentelemetry/exporter-logs-otlp-http\": \"npm:@opentelemetry/exporter-logs-otlp-http@^0.202.0\",\n \"@opentelemetry/otlp-exporter-base\": \"npm:@opentelemetry/otlp-exporter-base@^0.202.0\",\n \"@opentelemetry/resources\": \"npm:@opentelemetry/resources@^2.0.1\",\n \"@opentelemetry/sdk-logs\": \"npm:@opentelemetry/sdk-logs@^0.202.0\",\n \"@opentelemetry/semantic-conventions\": \"npm:@opentelemetry/semantic-conventions@^1.34.0\"\n },\n \"tasks\": {\n \"build\": \"pnpm build\",\n \"test\": \"deno test --allow-net --allow-env\"\n }\n}\n"],"mappings":";WACU;cACG;cACA;cACA,EACT,KAAK,eACN;cACU;CACT,sBAAsB;CACtB,2BAA2B;CAC3B,0CAA0C;CAC1C,qCAAqC;CACrC,4BAA4B;CAC5B,2BAA2B;CAC3B,uCAAuC;AACxC;YACQ;CACP,SAAS;CACT,QAAQ;AACT;mBAnBH;;;;;;;AAoBC"}
1
+ {"version":3,"file":"deno.js","names":[],"sources":["../deno.json"],"sourcesContent":["{\n \"name\": \"@logtape/otel\",\n \"version\": \"1.3.0-dev.381+eef5c598\",\n \"license\": \"MIT\",\n \"exports\": {\n \".\": \"./src/mod.ts\"\n },\n \"imports\": {\n \"@opentelemetry/api\": \"npm:@opentelemetry/api@^1.9.0\",\n \"@opentelemetry/api-logs\": \"npm:@opentelemetry/api-logs@^0.208.0\",\n \"@opentelemetry/exporter-logs-otlp-grpc\": \"npm:@opentelemetry/exporter-logs-otlp-grpc@^0.208.0\",\n \"@opentelemetry/exporter-logs-otlp-http\": \"npm:@opentelemetry/exporter-logs-otlp-http@^0.208.0\",\n \"@opentelemetry/exporter-logs-otlp-proto\": \"npm:@opentelemetry/exporter-logs-otlp-proto@^0.208.0\",\n \"@opentelemetry/otlp-exporter-base\": \"npm:@opentelemetry/otlp-exporter-base@^0.208.0\",\n \"@opentelemetry/resources\": \"npm:@opentelemetry/resources@^2.2.0\",\n \"@opentelemetry/sdk-logs\": \"npm:@opentelemetry/sdk-logs@^0.208.0\",\n \"@opentelemetry/semantic-conventions\": \"npm:@opentelemetry/semantic-conventions@^1.38.0\"\n },\n \"tasks\": {\n \"build\": \"pnpm build\",\n \"test\": \"deno test --allow-net --allow-env\"\n }\n}\n"],"mappings":";WACU;cACG;cACA;cACA,EACT,KAAK,eACN;cACU;CACT,sBAAsB;CACtB,2BAA2B;CAC3B,0CAA0C;CAC1C,0CAA0C;CAC1C,2CAA2C;CAC3C,qCAAqC;CACrC,4BAA4B;CAC5B,2BAA2B;CAC3B,uCAAuC;AACxC;YACQ;CACP,SAAS;CACT,QAAQ;AACT;mBArBH;;;;;;;AAsBC"}
package/dist/mod.cjs CHANGED
@@ -3,7 +3,6 @@ const require_deno = require('./deno.cjs');
3
3
  const __logtape_logtape = require_rolldown_runtime.__toESM(require("@logtape/logtape"));
4
4
  const __opentelemetry_api = require_rolldown_runtime.__toESM(require("@opentelemetry/api"));
5
5
  const __opentelemetry_api_logs = require_rolldown_runtime.__toESM(require("@opentelemetry/api-logs"));
6
- const __opentelemetry_exporter_logs_otlp_http = require_rolldown_runtime.__toESM(require("@opentelemetry/exporter-logs-otlp-http"));
7
6
  const __opentelemetry_resources = require_rolldown_runtime.__toESM(require("@opentelemetry/resources"));
8
7
  const __opentelemetry_sdk_logs = require_rolldown_runtime.__toESM(require("@opentelemetry/sdk-logs"));
9
8
  const __opentelemetry_semantic_conventions = require_rolldown_runtime.__toESM(require("@opentelemetry/semantic-conventions"));
@@ -24,39 +23,160 @@ function getEnvironmentVariable(name) {
24
23
  return void 0;
25
24
  }
26
25
  /**
26
+ * Checks if an OTLP endpoint is configured via environment variables or options.
27
+ * Checks the following environment variables:
28
+ * - `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` (logs-specific endpoint)
29
+ * - `OTEL_EXPORTER_OTLP_ENDPOINT` (general OTLP endpoint)
30
+ *
31
+ * @param config Optional exporter configuration that may contain a URL.
32
+ * @returns `true` if an endpoint is configured, `false` otherwise.
33
+ */
34
+ function hasOtlpEndpoint(config) {
35
+ if (config?.url) return true;
36
+ const logsEndpoint = getEnvironmentVariable("OTEL_EXPORTER_OTLP_LOGS_ENDPOINT");
37
+ if (logsEndpoint) return true;
38
+ const endpoint = getEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT");
39
+ if (endpoint) return true;
40
+ return false;
41
+ }
42
+ /**
43
+ * Detects the OTLP protocol from environment variables.
44
+ * Priority:
45
+ * 1. `OTEL_EXPORTER_OTLP_LOGS_PROTOCOL`
46
+ * 2. `OTEL_EXPORTER_OTLP_PROTOCOL`
47
+ * 3. Default: `"http/json"` (for backward compatibility)
48
+ *
49
+ * @returns The detected OTLP protocol.
50
+ */
51
+ function detectOtlpProtocol() {
52
+ const logsProtocol = getEnvironmentVariable("OTEL_EXPORTER_OTLP_LOGS_PROTOCOL");
53
+ if (logsProtocol === "grpc" || logsProtocol === "http/protobuf" || logsProtocol === "http/json") return logsProtocol;
54
+ const protocol = getEnvironmentVariable("OTEL_EXPORTER_OTLP_PROTOCOL");
55
+ if (protocol === "grpc" || protocol === "http/protobuf" || protocol === "http/json") return protocol;
56
+ return "http/json";
57
+ }
58
+ /**
59
+ * Creates an OTLP log exporter based on the detected protocol.
60
+ * Uses dynamic imports to maintain browser compatibility when gRPC is not used.
61
+ * @param config Optional exporter configuration.
62
+ * @returns A promise that resolves to the appropriate OTLP log exporter.
63
+ */
64
+ async function createOtlpExporter(config) {
65
+ const protocol = detectOtlpProtocol();
66
+ switch (protocol) {
67
+ case "grpc": {
68
+ const { OTLPLogExporter } = await import("@opentelemetry/exporter-logs-otlp-grpc");
69
+ return new OTLPLogExporter(config);
70
+ }
71
+ case "http/protobuf": {
72
+ const { OTLPLogExporter } = await import("@opentelemetry/exporter-logs-otlp-proto");
73
+ return new OTLPLogExporter(config);
74
+ }
75
+ case "http/json":
76
+ default: {
77
+ const { OTLPLogExporter } = await import("@opentelemetry/exporter-logs-otlp-http");
78
+ return new OTLPLogExporter(config);
79
+ }
80
+ }
81
+ }
82
+ /**
83
+ * A no-op logger provider that returns NOOP_LOGGER for all requests.
84
+ * Used when no OTLP endpoint is configured to avoid repeated connection errors.
85
+ */
86
+ const noopLoggerProvider = { getLogger: () => __opentelemetry_api_logs.NOOP_LOGGER };
87
+ /**
88
+ * Initializes the logger provider asynchronously.
89
+ * This is used when the user doesn't provide a custom logger provider.
90
+ *
91
+ * If no OTLP endpoint is configured (via options or environment variables),
92
+ * returns a noop logger provider to avoid repeated connection errors.
93
+ *
94
+ * @param options The exporter options.
95
+ * @returns A promise that resolves to the initialized logger provider.
96
+ */
97
+ async function initializeLoggerProvider(options) {
98
+ if (!hasOtlpEndpoint(options.otlpExporterConfig)) return noopLoggerProvider;
99
+ const resource = (0, __opentelemetry_resources.defaultResource)().merge((0, __opentelemetry_resources.resourceFromAttributes)({ [__opentelemetry_semantic_conventions.ATTR_SERVICE_NAME]: options.serviceName ?? getEnvironmentVariable("OTEL_SERVICE_NAME") }));
100
+ const otlpExporter = await createOtlpExporter(options.otlpExporterConfig);
101
+ const loggerProvider = new __opentelemetry_sdk_logs.LoggerProvider({
102
+ resource,
103
+ processors: [new __opentelemetry_sdk_logs.SimpleLogRecordProcessor(otlpExporter)]
104
+ });
105
+ return loggerProvider;
106
+ }
107
+ /**
108
+ * Emits a log record to the OpenTelemetry logger.
109
+ * @param logger The OpenTelemetry logger.
110
+ * @param record The LogTape log record.
111
+ * @param options The sink options.
112
+ */
113
+ function emitLogRecord(logger, record, options) {
114
+ const objectRenderer = options.objectRenderer ?? "inspect";
115
+ const { category, level, message, timestamp, properties } = record;
116
+ const severityNumber = mapLevelToSeverityNumber(level);
117
+ const attributes = convertToAttributes(properties, objectRenderer);
118
+ attributes["category"] = [...category];
119
+ logger.emit({
120
+ severityNumber,
121
+ severityText: level,
122
+ body: typeof options.messageType === "function" ? convertMessageToCustomBodyFormat(message, objectRenderer, options.messageType) : options.messageType === "array" ? convertMessageToArray(message, objectRenderer) : convertMessageToString(message, objectRenderer),
123
+ attributes,
124
+ timestamp: new Date(timestamp)
125
+ });
126
+ }
127
+ /**
27
128
  * Creates a sink that forwards log records to OpenTelemetry.
129
+ *
130
+ * When a custom `loggerProvider` is provided, it is used directly.
131
+ * Otherwise, the sink will lazily initialize a logger provider on the first
132
+ * log record, using the protocol determined by environment variables.
133
+ *
28
134
  * @param options Options for creating the sink.
29
135
  * @returns The sink.
30
136
  */
31
137
  function getOpenTelemetrySink(options = {}) {
32
138
  if (options.diagnostics) __opentelemetry_api.diag.setLogger(new DiagLoggerAdaptor(), __opentelemetry_api.DiagLogLevel.DEBUG);
33
- let loggerProvider;
34
- if (options.loggerProvider == null) {
35
- const resource = (0, __opentelemetry_resources.defaultResource)().merge((0, __opentelemetry_resources.resourceFromAttributes)({ [__opentelemetry_semantic_conventions.ATTR_SERVICE_NAME]: options.serviceName ?? getEnvironmentVariable("OTEL_SERVICE_NAME") }));
36
- loggerProvider = new __opentelemetry_sdk_logs.LoggerProvider({ resource });
37
- const otlpExporter = new __opentelemetry_exporter_logs_otlp_http.OTLPLogExporter(options.otlpExporterConfig);
38
- loggerProvider.addLogRecordProcessor(new __opentelemetry_sdk_logs.SimpleLogRecordProcessor(otlpExporter));
39
- } else loggerProvider = options.loggerProvider;
40
- const objectRenderer = options.objectRenderer ?? "inspect";
41
- const logger = loggerProvider.getLogger(require_deno.default.name, require_deno.default.version);
42
- const sink = (record) => {
43
- const { category, level, message, timestamp, properties } = record;
139
+ if (options.loggerProvider != null) {
140
+ const loggerProvider$1 = options.loggerProvider;
141
+ const logger$1 = loggerProvider$1.getLogger(require_deno.default.name, require_deno.default.version);
142
+ const shutdown = loggerProvider$1.shutdown?.bind(loggerProvider$1);
143
+ const sink$1 = Object.assign((record) => {
144
+ const { category } = record;
145
+ if (category[0] === "logtape" && category[1] === "meta" && category[2] === "otel") return;
146
+ emitLogRecord(logger$1, record, options);
147
+ }, { async [Symbol.asyncDispose]() {
148
+ if (shutdown != null) await shutdown();
149
+ } });
150
+ return sink$1;
151
+ }
152
+ let loggerProvider = null;
153
+ let logger = null;
154
+ let initPromise = null;
155
+ let initError = null;
156
+ const sink = Object.assign((record) => {
157
+ const { category } = record;
44
158
  if (category[0] === "logtape" && category[1] === "meta" && category[2] === "otel") return;
45
- const severityNumber = mapLevelToSeverityNumber(level);
46
- const attributes = convertToAttributes(properties, objectRenderer);
47
- attributes["category"] = [...category];
48
- logger.emit({
49
- severityNumber,
50
- severityText: level,
51
- body: typeof options.messageType === "function" ? convertMessageToCustomBodyFormat(message, objectRenderer, options.messageType) : options.messageType === "array" ? convertMessageToArray(message, objectRenderer) : convertMessageToString(message, objectRenderer),
52
- attributes,
53
- timestamp: new Date(timestamp)
159
+ if (logger != null) {
160
+ emitLogRecord(logger, record, options);
161
+ return;
162
+ }
163
+ if (initError != null) return;
164
+ if (initPromise == null) initPromise = initializeLoggerProvider(options).then((provider) => {
165
+ loggerProvider = provider;
166
+ logger = provider.getLogger(require_deno.default.name, require_deno.default.version);
167
+ emitLogRecord(logger, record, options);
168
+ }).catch((error) => {
169
+ initError = error;
170
+ console.error("Failed to initialize OpenTelemetry logger:", error);
54
171
  });
55
- };
56
- if (loggerProvider.shutdown != null) {
57
- const shutdown = loggerProvider.shutdown.bind(loggerProvider);
58
- sink[Symbol.asyncDispose] = shutdown;
59
- }
172
+ }, { async [Symbol.asyncDispose]() {
173
+ if (initPromise != null) try {
174
+ await initPromise;
175
+ } catch {
176
+ return;
177
+ }
178
+ if (loggerProvider?.shutdown != null) await loggerProvider.shutdown();
179
+ } });
60
180
  return sink;
61
181
  }
62
182
  function mapLevelToSeverityNumber(level) {
package/dist/mod.d.cts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { Sink } from "@logtape/logtape";
2
2
  import { AnyValue, LoggerProvider } from "@opentelemetry/api-logs";
3
3
  import { OTLPExporterNodeConfigBase } from "@opentelemetry/otlp-exporter-base";
4
- import { LogRecordProcessor } from "@opentelemetry/sdk-logs";
5
4
 
6
5
  //#region src/mod.d.ts
7
6
 
@@ -9,11 +8,6 @@ import { LogRecordProcessor } from "@opentelemetry/sdk-logs";
9
8
  * The OpenTelemetry logger provider.
10
9
  */
11
10
  type ILoggerProvider = LoggerProvider & {
12
- /**
13
- * Adds a new {@link LogRecordProcessor} to this logger.
14
- * @param processor the new LogRecordProcessor to be added.
15
- */
16
- addLogRecordProcessor(processor: LogRecordProcessor): void;
17
11
  /**
18
12
  * Flush all buffered data and shut down the LoggerProvider and all registered
19
13
  * LogRecordProcessor.
@@ -36,13 +30,14 @@ type Message = (string | null | undefined)[];
36
30
  */
37
31
  type BodyFormatter = (message: Message) => AnyValue;
38
32
  /**
39
- * Options for creating an OpenTelemetry sink.
33
+ * The OTLP protocol to use for exporting logs.
34
+ * @since 0.9.0
40
35
  */
41
- interface OpenTelemetrySinkOptions {
42
- /**
43
- * The OpenTelemetry logger provider to use.
44
- */
45
- loggerProvider?: ILoggerProvider;
36
+ type OtlpProtocol = "grpc" | "http/protobuf" | "http/json";
37
+ /**
38
+ * Base options shared by all OpenTelemetry sink configurations.
39
+ */
40
+ interface OpenTelemetrySinkOptionsBase {
46
41
  /**
47
42
  * The way to render the message in the log record. If `"string"`,
48
43
  * the message is rendered as a single string with the values are
@@ -66,24 +61,94 @@ interface OpenTelemetrySinkOptions {
66
61
  * Turned off by default.
67
62
  */
68
63
  diagnostics?: boolean;
64
+ }
65
+ /**
66
+ * Options for creating an OpenTelemetry sink with a custom logger provider.
67
+ * When using this configuration, you are responsible for setting up the
68
+ * logger provider with appropriate exporters and processors.
69
+ *
70
+ * This is the recommended approach for production use as it gives you
71
+ * full control over the OpenTelemetry configuration.
72
+ * @since 0.9.0
73
+ */
74
+ interface OpenTelemetrySinkProviderOptions extends OpenTelemetrySinkOptionsBase {
75
+ /**
76
+ * The OpenTelemetry logger provider to use.
77
+ */
78
+ loggerProvider: ILoggerProvider;
79
+ }
80
+ /**
81
+ * Options for creating an OpenTelemetry sink with automatic exporter creation.
82
+ * The protocol is determined by environment variables:
83
+ * - `OTEL_EXPORTER_OTLP_LOGS_PROTOCOL` (highest priority)
84
+ * - `OTEL_EXPORTER_OTLP_PROTOCOL` (fallback)
85
+ * - Default: `"http/json"`
86
+ *
87
+ * For production use, consider providing your own {@link ILoggerProvider}
88
+ * via {@link OpenTelemetrySinkProviderOptions} for more control.
89
+ * @since 0.9.0
90
+ */
91
+ interface OpenTelemetrySinkExporterOptions extends OpenTelemetrySinkOptionsBase {
92
+ /**
93
+ * The OpenTelemetry logger provider to use.
94
+ * Must be undefined or omitted when using exporter options.
95
+ */
96
+ loggerProvider?: undefined;
69
97
  /**
70
98
  * The OpenTelemetry OTLP exporter configuration to use.
71
- * Ignored if `loggerProvider` is provided.
72
99
  */
73
100
  otlpExporterConfig?: OTLPExporterNodeConfigBase;
74
101
  /**
75
102
  * The service name to use. If not provided, the service name is
76
103
  * taken from the `OTEL_SERVICE_NAME` environment variable.
77
- * Ignored if `loggerProvider` is provided.
78
104
  */
79
105
  serviceName?: string;
80
106
  }
107
+ /**
108
+ * Options for creating an OpenTelemetry sink.
109
+ *
110
+ * This is a union type that accepts either:
111
+ * - {@link OpenTelemetrySinkProviderOptions}: Provide your own `loggerProvider`
112
+ * (recommended for production)
113
+ * - {@link OpenTelemetrySinkExporterOptions}: Let the sink create an exporter
114
+ * automatically based on environment variables
115
+ *
116
+ * When no `loggerProvider` is provided, the protocol is determined by:
117
+ * 1. `OTEL_EXPORTER_OTLP_LOGS_PROTOCOL` environment variable
118
+ * 2. `OTEL_EXPORTER_OTLP_PROTOCOL` environment variable
119
+ * 3. Default: `"http/json"`
120
+ *
121
+ * @example Using a custom logger provider (recommended)
122
+ * ```typescript
123
+ * import { LoggerProvider, SimpleLogRecordProcessor } from "@opentelemetry/sdk-logs";
124
+ * import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-grpc";
125
+ *
126
+ * const provider = new LoggerProvider();
127
+ * provider.addLogRecordProcessor(new SimpleLogRecordProcessor(new OTLPLogExporter()));
128
+ *
129
+ * const sink = getOpenTelemetrySink({ loggerProvider: provider });
130
+ * ```
131
+ *
132
+ * @example Using automatic exporter creation
133
+ * ```typescript
134
+ * // Protocol determined by OTEL_EXPORTER_OTLP_PROTOCOL env var
135
+ * const sink = getOpenTelemetrySink({
136
+ * serviceName: "my-service",
137
+ * });
138
+ * ```
139
+ */
140
+ type OpenTelemetrySinkOptions = OpenTelemetrySinkProviderOptions | OpenTelemetrySinkExporterOptions;
81
141
  /**
82
142
  * Creates a sink that forwards log records to OpenTelemetry.
143
+ *
144
+ * When a custom `loggerProvider` is provided, it is used directly.
145
+ * Otherwise, the sink will lazily initialize a logger provider on the first
146
+ * log record, using the protocol determined by environment variables.
147
+ *
83
148
  * @param options Options for creating the sink.
84
149
  * @returns The sink.
85
150
  */
86
- declare function getOpenTelemetrySink(options?: OpenTelemetrySinkOptions): Sink;
151
+ declare function getOpenTelemetrySink(options?: OpenTelemetrySinkOptions): Sink & AsyncDisposable;
87
152
  //#endregion
88
- export { BodyFormatter, ObjectRenderer, OpenTelemetrySinkOptions, getOpenTelemetrySink };
153
+ export { BodyFormatter, ObjectRenderer, OpenTelemetrySinkExporterOptions, OpenTelemetrySinkOptions, OpenTelemetrySinkProviderOptions, OtlpProtocol, getOpenTelemetrySink };
89
154
  //# sourceMappingURL=mod.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.cts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAuBiC;KAyC5B,eAAA,GAAkB,cAAH,GAAA;EAAA;;;AAaM;EASd,qBAAc,CAAA,SAAA,EAjBS,kBAiBT,CAAA,EAAA,IAAA;EAErB;AAML;;;;AAA0D;EAKzC,QAAA,CAAA,EAAA,GAAA,GAtBE,OAsBF,CAAA,IAAwB,CAAA;CAAA;;;;;AAoCQ;AAejD;AAAoC,KAhExB,cAAA,GAgEwB,MAAA,GAAA,SAAA;KA9D/B,OAAA,GA+DM,CAAA,MAAA,GAAA,IAAA,GAAA,SAAA,CAAA,EAAA;;AACJ;;;KA1DK,aAAA,aAA0B,YAAY;;;;UAKjC,wBAAA;;;;mBAIE;;;;;;;;;;qCAWkB;;;;;;;mBAQlB;;;;;;;;;;;uBAaI;;;;;;;;;;;;;iBAeP,oBAAA,WACL,2BACR"}
1
+ {"version":3,"file":"mod.d.cts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAeoF;KAoJ/E,eAAA,GAAkB,cAAH,GAAA;EAAA;;AAOM;AAS1B;AAAgD;AAQhD;EAAyB,QAAA,CAAA,EAAA,GAAA,GAjBN,OAiBM,CAAA,IAAA,CAAA;CAAA;;AAAiC;AAM1D;AAAkE;;;AAuB/C,KArCP,cAAA,GAqCO,MAAA,GAAA,SAAA;AAAc,KAnC5B,OAAA,GAmC4B,CAAA,MAAA,GAAA,IAAA,GAAA,SAAA,CAAA,EAAA;AAmBjC;;;;AACsC,KAjD1B,aAAA,GAiD0B,CAAA,OAAA,EAjDA,OAiDA,EAAA,GAjDY,QAiDZ;AAkBtC;;;;AACsC,KA9D1B,YAAA,GA8D0B,MAAA,GAAA,eAAA,GAAA,WAAA;AAoDtC;;;UA7GU,4BAAA,CA+GN;EAAgC;AA2FpC;;;;;AAEyB;;;qCAlMY;;;;;;;mBAQlB;;;;;;;;;;;;;;;;;UAmBF,gCAAA,SACP;;;;kBAIQ;;;;;;;;;;;;;UAcD,gCAAA,SACP;;;;;;;;;uBAUa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA0CX,wBAAA,GACR,mCACA;;;;;;;;;;;iBA2FY,oBAAA,WACL,2BACR,OAAO"}
package/dist/mod.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { Sink } from "@logtape/logtape";
2
2
  import { AnyValue, LoggerProvider } from "@opentelemetry/api-logs";
3
- import { LogRecordProcessor } from "@opentelemetry/sdk-logs";
4
3
  import { OTLPExporterNodeConfigBase } from "@opentelemetry/otlp-exporter-base";
5
4
 
6
5
  //#region src/mod.d.ts
@@ -9,11 +8,6 @@ import { OTLPExporterNodeConfigBase } from "@opentelemetry/otlp-exporter-base";
9
8
  * The OpenTelemetry logger provider.
10
9
  */
11
10
  type ILoggerProvider = LoggerProvider & {
12
- /**
13
- * Adds a new {@link LogRecordProcessor} to this logger.
14
- * @param processor the new LogRecordProcessor to be added.
15
- */
16
- addLogRecordProcessor(processor: LogRecordProcessor): void;
17
11
  /**
18
12
  * Flush all buffered data and shut down the LoggerProvider and all registered
19
13
  * LogRecordProcessor.
@@ -36,13 +30,14 @@ type Message = (string | null | undefined)[];
36
30
  */
37
31
  type BodyFormatter = (message: Message) => AnyValue;
38
32
  /**
39
- * Options for creating an OpenTelemetry sink.
33
+ * The OTLP protocol to use for exporting logs.
34
+ * @since 0.9.0
40
35
  */
41
- interface OpenTelemetrySinkOptions {
42
- /**
43
- * The OpenTelemetry logger provider to use.
44
- */
45
- loggerProvider?: ILoggerProvider;
36
+ type OtlpProtocol = "grpc" | "http/protobuf" | "http/json";
37
+ /**
38
+ * Base options shared by all OpenTelemetry sink configurations.
39
+ */
40
+ interface OpenTelemetrySinkOptionsBase {
46
41
  /**
47
42
  * The way to render the message in the log record. If `"string"`,
48
43
  * the message is rendered as a single string with the values are
@@ -66,24 +61,94 @@ interface OpenTelemetrySinkOptions {
66
61
  * Turned off by default.
67
62
  */
68
63
  diagnostics?: boolean;
64
+ }
65
+ /**
66
+ * Options for creating an OpenTelemetry sink with a custom logger provider.
67
+ * When using this configuration, you are responsible for setting up the
68
+ * logger provider with appropriate exporters and processors.
69
+ *
70
+ * This is the recommended approach for production use as it gives you
71
+ * full control over the OpenTelemetry configuration.
72
+ * @since 0.9.0
73
+ */
74
+ interface OpenTelemetrySinkProviderOptions extends OpenTelemetrySinkOptionsBase {
75
+ /**
76
+ * The OpenTelemetry logger provider to use.
77
+ */
78
+ loggerProvider: ILoggerProvider;
79
+ }
80
+ /**
81
+ * Options for creating an OpenTelemetry sink with automatic exporter creation.
82
+ * The protocol is determined by environment variables:
83
+ * - `OTEL_EXPORTER_OTLP_LOGS_PROTOCOL` (highest priority)
84
+ * - `OTEL_EXPORTER_OTLP_PROTOCOL` (fallback)
85
+ * - Default: `"http/json"`
86
+ *
87
+ * For production use, consider providing your own {@link ILoggerProvider}
88
+ * via {@link OpenTelemetrySinkProviderOptions} for more control.
89
+ * @since 0.9.0
90
+ */
91
+ interface OpenTelemetrySinkExporterOptions extends OpenTelemetrySinkOptionsBase {
92
+ /**
93
+ * The OpenTelemetry logger provider to use.
94
+ * Must be undefined or omitted when using exporter options.
95
+ */
96
+ loggerProvider?: undefined;
69
97
  /**
70
98
  * The OpenTelemetry OTLP exporter configuration to use.
71
- * Ignored if `loggerProvider` is provided.
72
99
  */
73
100
  otlpExporterConfig?: OTLPExporterNodeConfigBase;
74
101
  /**
75
102
  * The service name to use. If not provided, the service name is
76
103
  * taken from the `OTEL_SERVICE_NAME` environment variable.
77
- * Ignored if `loggerProvider` is provided.
78
104
  */
79
105
  serviceName?: string;
80
106
  }
107
+ /**
108
+ * Options for creating an OpenTelemetry sink.
109
+ *
110
+ * This is a union type that accepts either:
111
+ * - {@link OpenTelemetrySinkProviderOptions}: Provide your own `loggerProvider`
112
+ * (recommended for production)
113
+ * - {@link OpenTelemetrySinkExporterOptions}: Let the sink create an exporter
114
+ * automatically based on environment variables
115
+ *
116
+ * When no `loggerProvider` is provided, the protocol is determined by:
117
+ * 1. `OTEL_EXPORTER_OTLP_LOGS_PROTOCOL` environment variable
118
+ * 2. `OTEL_EXPORTER_OTLP_PROTOCOL` environment variable
119
+ * 3. Default: `"http/json"`
120
+ *
121
+ * @example Using a custom logger provider (recommended)
122
+ * ```typescript
123
+ * import { LoggerProvider, SimpleLogRecordProcessor } from "@opentelemetry/sdk-logs";
124
+ * import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-grpc";
125
+ *
126
+ * const provider = new LoggerProvider();
127
+ * provider.addLogRecordProcessor(new SimpleLogRecordProcessor(new OTLPLogExporter()));
128
+ *
129
+ * const sink = getOpenTelemetrySink({ loggerProvider: provider });
130
+ * ```
131
+ *
132
+ * @example Using automatic exporter creation
133
+ * ```typescript
134
+ * // Protocol determined by OTEL_EXPORTER_OTLP_PROTOCOL env var
135
+ * const sink = getOpenTelemetrySink({
136
+ * serviceName: "my-service",
137
+ * });
138
+ * ```
139
+ */
140
+ type OpenTelemetrySinkOptions = OpenTelemetrySinkProviderOptions | OpenTelemetrySinkExporterOptions;
81
141
  /**
82
142
  * Creates a sink that forwards log records to OpenTelemetry.
143
+ *
144
+ * When a custom `loggerProvider` is provided, it is used directly.
145
+ * Otherwise, the sink will lazily initialize a logger provider on the first
146
+ * log record, using the protocol determined by environment variables.
147
+ *
83
148
  * @param options Options for creating the sink.
84
149
  * @returns The sink.
85
150
  */
86
- declare function getOpenTelemetrySink(options?: OpenTelemetrySinkOptions): Sink;
151
+ declare function getOpenTelemetrySink(options?: OpenTelemetrySinkOptions): Sink & AsyncDisposable;
87
152
  //#endregion
88
- export { BodyFormatter, ObjectRenderer, OpenTelemetrySinkOptions, getOpenTelemetrySink };
153
+ export { BodyFormatter, ObjectRenderer, OpenTelemetrySinkExporterOptions, OpenTelemetrySinkOptions, OpenTelemetrySinkProviderOptions, OtlpProtocol, getOpenTelemetrySink };
89
154
  //# sourceMappingURL=mod.d.ts.map
package/dist/mod.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAuBiC;KAyC5B,eAAA,GAAkB,cAAH,GAAA;EAAA;;;AAaM;EASd,qBAAc,CAAA,SAAA,EAjBS,kBAiBT,CAAA,EAAA,IAAA;EAErB;AAML;;;;AAA0D;EAKzC,QAAA,CAAA,EAAA,GAAA,GAtBE,OAsBF,CAAA,IAAwB,CAAA;CAAA;;;;;AAoCQ;AAejD;AAAoC,KAhExB,cAAA,GAgEwB,MAAA,GAAA,SAAA;KA9D/B,OAAA,GA+DM,CAAA,MAAA,GAAA,IAAA,GAAA,SAAA,CAAA,EAAA;;AACJ;;;KA1DK,aAAA,aAA0B,YAAY;;;;UAKjC,wBAAA;;;;mBAIE;;;;;;;;;;qCAWkB;;;;;;;mBAQlB;;;;;;;;;;;uBAaI;;;;;;;;;;;;;iBAeP,oBAAA,WACL,2BACR"}
1
+ {"version":3,"file":"mod.d.ts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAeoF;KAoJ/E,eAAA,GAAkB,cAAH,GAAA;EAAA;;AAOM;AAS1B;AAAgD;AAQhD;EAAyB,QAAA,CAAA,EAAA,GAAA,GAjBN,OAiBM,CAAA,IAAA,CAAA;CAAA;;AAAiC;AAM1D;AAAkE;;;AAuB/C,KArCP,cAAA,GAqCO,MAAA,GAAA,SAAA;AAAc,KAnC5B,OAAA,GAmC4B,CAAA,MAAA,GAAA,IAAA,GAAA,SAAA,CAAA,EAAA;AAmBjC;;;;AACsC,KAjD1B,aAAA,GAiD0B,CAAA,OAAA,EAjDA,OAiDA,EAAA,GAjDY,QAiDZ;AAkBtC;;;;AACsC,KA9D1B,YAAA,GA8D0B,MAAA,GAAA,eAAA,GAAA,WAAA;AAoDtC;;;UA7GU,4BAAA,CA+GN;EAAgC;AA2FpC;;;;;AAEyB;;;qCAlMY;;;;;;;mBAQlB;;;;;;;;;;;;;;;;;UAmBF,gCAAA,SACP;;;;kBAIQ;;;;;;;;;;;;;UAcD,gCAAA,SACP;;;;;;;;;uBAUa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA0CX,wBAAA,GACR,mCACA;;;;;;;;;;;iBA2FY,oBAAA,WACL,2BACR,OAAO"}