@atrim/instrument-node 0.1.3-fea6398-20251118005809 → 0.4.0-08fae61-20251118193009
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/README.md +328 -7
- package/package.json +6 -5
- package/target/dist/index.cjs +177 -531
- package/target/dist/index.cjs.map +1 -1
- package/target/dist/index.d.cts +57 -3
- package/target/dist/index.d.ts +57 -3
- package/target/dist/index.js +104 -469
- package/target/dist/index.js.map +1 -1
- package/target/dist/integrations/effect/index.cjs +54 -409
- package/target/dist/integrations/effect/index.cjs.map +1 -1
- package/target/dist/integrations/effect/index.d.cts +17 -1
- package/target/dist/integrations/effect/index.d.ts +17 -1
- package/target/dist/integrations/effect/index.js +43 -398
- package/target/dist/integrations/effect/index.js.map +1 -1
package/target/dist/index.cjs
CHANGED
|
@@ -5,12 +5,12 @@ var sdkNode = require('@opentelemetry/sdk-node');
|
|
|
5
5
|
var sdkTraceBase = require('@opentelemetry/sdk-trace-base');
|
|
6
6
|
var autoInstrumentationsNode = require('@opentelemetry/auto-instrumentations-node');
|
|
7
7
|
var api = require('@opentelemetry/api');
|
|
8
|
-
var
|
|
9
|
-
var path = require('path');
|
|
10
|
-
var yaml = require('yaml');
|
|
11
|
-
var zod = require('zod');
|
|
8
|
+
var instrumentCore = require('@atrim/instrument-core');
|
|
12
9
|
var exporterTraceOtlpHttp = require('@opentelemetry/exporter-trace-otlp-http');
|
|
13
10
|
var promises = require('fs/promises');
|
|
11
|
+
var path = require('path');
|
|
12
|
+
var platformNode = require('@effect/platform-node');
|
|
13
|
+
var platform = require('@effect/platform');
|
|
14
14
|
|
|
15
15
|
var __defProp = Object.defineProperty;
|
|
16
16
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -21,451 +21,11 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
21
21
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
22
22
|
});
|
|
23
23
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
24
|
-
var __defProp2 = Object.defineProperty;
|
|
25
|
-
var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
26
|
-
var __publicField2 = (obj, key, value) => __defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
27
|
-
var PatternConfigSchema = zod.z.object({
|
|
28
|
-
pattern: zod.z.string(),
|
|
29
|
-
enabled: zod.z.boolean().optional(),
|
|
30
|
-
description: zod.z.string().optional()
|
|
31
|
-
});
|
|
32
|
-
var AutoIsolationConfigSchema = zod.z.object({
|
|
33
|
-
// Global enable/disable for auto-isolation
|
|
34
|
-
enabled: zod.z.boolean().default(false),
|
|
35
|
-
// Which operators to auto-isolate
|
|
36
|
-
operators: zod.z.object({
|
|
37
|
-
fiberset_run: zod.z.boolean().default(true),
|
|
38
|
-
effect_fork: zod.z.boolean().default(true),
|
|
39
|
-
effect_fork_daemon: zod.z.boolean().default(true),
|
|
40
|
-
effect_fork_in: zod.z.boolean().default(false)
|
|
41
|
-
}).default({}),
|
|
42
|
-
// Virtual parent tracking configuration
|
|
43
|
-
tracking: zod.z.object({
|
|
44
|
-
use_span_links: zod.z.boolean().default(true),
|
|
45
|
-
use_attributes: zod.z.boolean().default(true),
|
|
46
|
-
capture_logical_parent: zod.z.boolean().default(true)
|
|
47
|
-
}).default({}),
|
|
48
|
-
// Span categorization
|
|
49
|
-
attributes: zod.z.object({
|
|
50
|
-
category: zod.z.string().default("background_task"),
|
|
51
|
-
add_metadata: zod.z.boolean().default(true)
|
|
52
|
-
}).default({})
|
|
53
|
-
});
|
|
54
|
-
var HttpFilteringConfigSchema = zod.z.object({
|
|
55
|
-
// Patterns to ignore for outgoing HTTP requests (string patterns only in YAML)
|
|
56
|
-
ignore_outgoing_urls: zod.z.array(zod.z.string()).optional(),
|
|
57
|
-
// Patterns to ignore for incoming HTTP requests (string patterns only in YAML)
|
|
58
|
-
ignore_incoming_paths: zod.z.array(zod.z.string()).optional(),
|
|
59
|
-
// Require parent span for outgoing requests (prevents root spans for HTTP calls)
|
|
60
|
-
require_parent_for_outgoing_spans: zod.z.boolean().optional()
|
|
61
|
-
});
|
|
62
|
-
var InstrumentationConfigSchema = zod.z.object({
|
|
63
|
-
version: zod.z.string(),
|
|
64
|
-
instrumentation: zod.z.object({
|
|
65
|
-
enabled: zod.z.boolean(),
|
|
66
|
-
description: zod.z.string().optional(),
|
|
67
|
-
logging: zod.z.enum(["on", "off", "minimal"]).optional().default("on"),
|
|
68
|
-
instrument_patterns: zod.z.array(PatternConfigSchema),
|
|
69
|
-
ignore_patterns: zod.z.array(PatternConfigSchema)
|
|
70
|
-
}),
|
|
71
|
-
effect: zod.z.object({
|
|
72
|
-
auto_extract_metadata: zod.z.boolean(),
|
|
73
|
-
auto_isolation: AutoIsolationConfigSchema.optional()
|
|
74
|
-
}).optional(),
|
|
75
|
-
http: HttpFilteringConfigSchema.optional()
|
|
76
|
-
});
|
|
77
|
-
(class extends effect.Data.TaggedError("ConfigError") {
|
|
78
|
-
});
|
|
79
|
-
var ConfigUrlError = class extends effect.Data.TaggedError("ConfigUrlError") {
|
|
80
|
-
};
|
|
81
|
-
var ConfigValidationError = class extends effect.Data.TaggedError("ConfigValidationError") {
|
|
82
|
-
};
|
|
83
|
-
var ConfigFileError = class extends effect.Data.TaggedError("ConfigFileError") {
|
|
84
|
-
};
|
|
85
|
-
(class extends effect.Data.TaggedError("ServiceDetectionError") {
|
|
86
|
-
});
|
|
87
|
-
(class extends effect.Data.TaggedError("InitializationError") {
|
|
88
|
-
});
|
|
89
|
-
(class extends effect.Data.TaggedError("ExportError") {
|
|
90
|
-
});
|
|
91
|
-
(class extends effect.Data.TaggedError("ShutdownError") {
|
|
92
|
-
});
|
|
93
|
-
var SECURITY_DEFAULTS = {
|
|
94
|
-
maxConfigSize: 1e6,
|
|
95
|
-
// 1MB
|
|
96
|
-
requestTimeout: 5e3,
|
|
97
|
-
allowedProtocols: ["https:"],
|
|
98
|
-
// Only HTTPS for remote configs
|
|
99
|
-
cacheTimeout: 3e5
|
|
100
|
-
// 5 minutes
|
|
101
|
-
};
|
|
102
|
-
function getDefaultConfig() {
|
|
103
|
-
return {
|
|
104
|
-
version: "1.0",
|
|
105
|
-
instrumentation: {
|
|
106
|
-
enabled: true,
|
|
107
|
-
logging: "on",
|
|
108
|
-
description: "Default instrumentation configuration",
|
|
109
|
-
instrument_patterns: [
|
|
110
|
-
{ pattern: "^app\\.", enabled: true, description: "Application operations" },
|
|
111
|
-
{ pattern: "^http\\.server\\.", enabled: true, description: "HTTP server operations" },
|
|
112
|
-
{ pattern: "^http\\.client\\.", enabled: true, description: "HTTP client operations" }
|
|
113
|
-
],
|
|
114
|
-
ignore_patterns: [
|
|
115
|
-
{ pattern: "^test\\.", description: "Test utilities" },
|
|
116
|
-
{ pattern: "^internal\\.", description: "Internal operations" },
|
|
117
|
-
{ pattern: "^health\\.", description: "Health checks" }
|
|
118
|
-
]
|
|
119
|
-
},
|
|
120
|
-
effect: {
|
|
121
|
-
auto_extract_metadata: true
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
var validateConfigEffect = (rawConfig) => effect.Effect.try({
|
|
126
|
-
try: () => InstrumentationConfigSchema.parse(rawConfig),
|
|
127
|
-
catch: (error) => new ConfigValidationError({
|
|
128
|
-
reason: "Invalid configuration schema",
|
|
129
|
-
cause: error
|
|
130
|
-
})
|
|
131
|
-
});
|
|
132
|
-
var loadConfigFromFileEffect = (filePath) => effect.Effect.gen(function* () {
|
|
133
|
-
const fileContents = yield* effect.Effect.try({
|
|
134
|
-
try: () => fs.readFileSync(filePath, "utf8"),
|
|
135
|
-
catch: (error) => new ConfigFileError({
|
|
136
|
-
reason: `Failed to read config file at ${filePath}`,
|
|
137
|
-
cause: error
|
|
138
|
-
})
|
|
139
|
-
});
|
|
140
|
-
if (fileContents.length > SECURITY_DEFAULTS.maxConfigSize) {
|
|
141
|
-
return yield* effect.Effect.fail(
|
|
142
|
-
new ConfigFileError({
|
|
143
|
-
reason: `Config file exceeds maximum size of ${SECURITY_DEFAULTS.maxConfigSize} bytes`
|
|
144
|
-
})
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
let rawConfig;
|
|
148
|
-
try {
|
|
149
|
-
rawConfig = yaml.parse(fileContents);
|
|
150
|
-
} catch (error) {
|
|
151
|
-
return yield* effect.Effect.fail(
|
|
152
|
-
new ConfigValidationError({
|
|
153
|
-
reason: "Invalid YAML syntax",
|
|
154
|
-
cause: error
|
|
155
|
-
})
|
|
156
|
-
);
|
|
157
|
-
}
|
|
158
|
-
return yield* validateConfigEffect(rawConfig);
|
|
159
|
-
});
|
|
160
|
-
var fetchAndParseConfig = (url) => effect.Effect.gen(function* () {
|
|
161
|
-
let urlObj;
|
|
162
|
-
try {
|
|
163
|
-
urlObj = new URL(url);
|
|
164
|
-
} catch (error) {
|
|
165
|
-
return yield* effect.Effect.fail(
|
|
166
|
-
new ConfigUrlError({
|
|
167
|
-
reason: `Invalid URL: ${url}`,
|
|
168
|
-
cause: error
|
|
169
|
-
})
|
|
170
|
-
);
|
|
171
|
-
}
|
|
172
|
-
if (!SECURITY_DEFAULTS.allowedProtocols.includes(urlObj.protocol)) {
|
|
173
|
-
return yield* effect.Effect.fail(
|
|
174
|
-
new ConfigUrlError({
|
|
175
|
-
reason: `Insecure protocol ${urlObj.protocol}. Only ${SECURITY_DEFAULTS.allowedProtocols.join(", ")} are allowed`
|
|
176
|
-
})
|
|
177
|
-
);
|
|
178
|
-
}
|
|
179
|
-
const response = yield* effect.Effect.tryPromise({
|
|
180
|
-
try: () => fetch(url, {
|
|
181
|
-
redirect: "follow",
|
|
182
|
-
headers: {
|
|
183
|
-
Accept: "application/yaml, text/yaml, text/x-yaml"
|
|
184
|
-
}
|
|
185
|
-
}),
|
|
186
|
-
catch: (error) => new ConfigUrlError({
|
|
187
|
-
reason: `Failed to load config from URL ${url}`,
|
|
188
|
-
cause: error
|
|
189
|
-
})
|
|
190
|
-
}).pipe(
|
|
191
|
-
effect.Effect.timeout(effect.Duration.millis(SECURITY_DEFAULTS.requestTimeout)),
|
|
192
|
-
effect.Effect.retry({
|
|
193
|
-
times: 3,
|
|
194
|
-
schedule: effect.Schedule.exponential(effect.Duration.millis(100))
|
|
195
|
-
}),
|
|
196
|
-
effect.Effect.catchAll((error) => {
|
|
197
|
-
if (error._tag === "TimeoutException") {
|
|
198
|
-
return effect.Effect.fail(
|
|
199
|
-
new ConfigUrlError({
|
|
200
|
-
reason: `Config fetch timeout after ${SECURITY_DEFAULTS.requestTimeout}ms`
|
|
201
|
-
})
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
return effect.Effect.fail(error);
|
|
205
|
-
})
|
|
206
|
-
);
|
|
207
|
-
if (!response.ok) {
|
|
208
|
-
return yield* effect.Effect.fail(
|
|
209
|
-
new ConfigUrlError({
|
|
210
|
-
reason: `HTTP ${response.status}: ${response.statusText}`
|
|
211
|
-
})
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
const contentLength = response.headers.get("content-length");
|
|
215
|
-
if (contentLength && parseInt(contentLength) > SECURITY_DEFAULTS.maxConfigSize) {
|
|
216
|
-
return yield* effect.Effect.fail(
|
|
217
|
-
new ConfigUrlError({
|
|
218
|
-
reason: `Config exceeds maximum size of ${SECURITY_DEFAULTS.maxConfigSize} bytes`
|
|
219
|
-
})
|
|
220
|
-
);
|
|
221
|
-
}
|
|
222
|
-
const text = yield* effect.Effect.tryPromise({
|
|
223
|
-
try: () => response.text(),
|
|
224
|
-
catch: (error) => new ConfigUrlError({
|
|
225
|
-
reason: "Failed to read response body",
|
|
226
|
-
cause: error
|
|
227
|
-
})
|
|
228
|
-
});
|
|
229
|
-
if (text.length > SECURITY_DEFAULTS.maxConfigSize) {
|
|
230
|
-
return yield* effect.Effect.fail(
|
|
231
|
-
new ConfigUrlError({
|
|
232
|
-
reason: `Config exceeds maximum size of ${SECURITY_DEFAULTS.maxConfigSize} bytes`
|
|
233
|
-
})
|
|
234
|
-
);
|
|
235
|
-
}
|
|
236
|
-
let rawConfig;
|
|
237
|
-
try {
|
|
238
|
-
rawConfig = yaml.parse(text);
|
|
239
|
-
} catch (error) {
|
|
240
|
-
return yield* effect.Effect.fail(
|
|
241
|
-
new ConfigValidationError({
|
|
242
|
-
reason: "Invalid YAML syntax",
|
|
243
|
-
cause: error
|
|
244
|
-
})
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
return yield* validateConfigEffect(rawConfig);
|
|
248
|
-
});
|
|
249
|
-
var makeConfigCache = () => effect.Cache.make({
|
|
250
|
-
capacity: 100,
|
|
251
|
-
timeToLive: effect.Duration.minutes(5),
|
|
252
|
-
lookup: (url) => fetchAndParseConfig(url)
|
|
253
|
-
});
|
|
254
|
-
var cacheInstance = null;
|
|
255
|
-
var getCache = effect.Effect.gen(function* () {
|
|
256
|
-
if (!cacheInstance) {
|
|
257
|
-
cacheInstance = yield* makeConfigCache();
|
|
258
|
-
}
|
|
259
|
-
return cacheInstance;
|
|
260
|
-
});
|
|
261
|
-
var loadConfigFromUrlEffect = (url, cacheTimeout = SECURITY_DEFAULTS.cacheTimeout) => effect.Effect.gen(function* () {
|
|
262
|
-
if (cacheTimeout === 0) {
|
|
263
|
-
return yield* fetchAndParseConfig(url);
|
|
264
|
-
}
|
|
265
|
-
const cache = yield* getCache;
|
|
266
|
-
return yield* cache.get(url);
|
|
267
|
-
});
|
|
268
|
-
var loadConfigEffect = (options = {}) => effect.Effect.gen(function* () {
|
|
269
|
-
if (options.config) {
|
|
270
|
-
return yield* validateConfigEffect(options.config);
|
|
271
|
-
}
|
|
272
|
-
const envConfigPath = process.env.ATRIM_INSTRUMENTATION_CONFIG;
|
|
273
|
-
if (envConfigPath) {
|
|
274
|
-
if (envConfigPath.startsWith("http://") || envConfigPath.startsWith("https://")) {
|
|
275
|
-
return yield* loadConfigFromUrlEffect(envConfigPath, options.cacheTimeout);
|
|
276
|
-
}
|
|
277
|
-
return yield* loadConfigFromFileEffect(envConfigPath);
|
|
278
|
-
}
|
|
279
|
-
if (options.configUrl) {
|
|
280
|
-
return yield* loadConfigFromUrlEffect(options.configUrl, options.cacheTimeout);
|
|
281
|
-
}
|
|
282
|
-
if (options.configPath) {
|
|
283
|
-
return yield* loadConfigFromFileEffect(options.configPath);
|
|
284
|
-
}
|
|
285
|
-
const defaultPath = path.join(process.cwd(), "instrumentation.yaml");
|
|
286
|
-
const exists = yield* effect.Effect.sync(() => fs.existsSync(defaultPath));
|
|
287
|
-
if (exists) {
|
|
288
|
-
return yield* loadConfigFromFileEffect(defaultPath);
|
|
289
|
-
}
|
|
290
|
-
return getDefaultConfig();
|
|
291
|
-
});
|
|
292
|
-
async function loadConfig(options = {}) {
|
|
293
|
-
return effect.Effect.runPromise(
|
|
294
|
-
loadConfigEffect(options).pipe(
|
|
295
|
-
// Convert typed errors to regular Error with reason message for backward compatibility
|
|
296
|
-
effect.Effect.mapError((error) => {
|
|
297
|
-
const message = error.reason;
|
|
298
|
-
const newError = new Error(message);
|
|
299
|
-
newError.cause = error.cause;
|
|
300
|
-
return newError;
|
|
301
|
-
})
|
|
302
|
-
)
|
|
303
|
-
);
|
|
304
|
-
}
|
|
305
|
-
var PatternMatcher = class {
|
|
306
|
-
constructor(config) {
|
|
307
|
-
__publicField2(this, "ignorePatterns", []);
|
|
308
|
-
__publicField2(this, "instrumentPatterns", []);
|
|
309
|
-
__publicField2(this, "enabled", true);
|
|
310
|
-
this.enabled = config.instrumentation.enabled;
|
|
311
|
-
this.ignorePatterns = config.instrumentation.ignore_patterns.map((p) => this.compilePattern(p));
|
|
312
|
-
this.instrumentPatterns = config.instrumentation.instrument_patterns.filter((p) => p.enabled !== false).map((p) => this.compilePattern(p));
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Compile a pattern configuration into a RegExp
|
|
316
|
-
*/
|
|
317
|
-
compilePattern(pattern) {
|
|
318
|
-
try {
|
|
319
|
-
const compiled = {
|
|
320
|
-
regex: new RegExp(pattern.pattern),
|
|
321
|
-
enabled: pattern.enabled !== false
|
|
322
|
-
};
|
|
323
|
-
if (pattern.description !== void 0) {
|
|
324
|
-
compiled.description = pattern.description;
|
|
325
|
-
}
|
|
326
|
-
return compiled;
|
|
327
|
-
} catch (error) {
|
|
328
|
-
throw new Error(
|
|
329
|
-
`Failed to compile pattern "${pattern.pattern}": ${error instanceof Error ? error.message : String(error)}`
|
|
330
|
-
);
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
/**
|
|
334
|
-
* Check if a span should be instrumented
|
|
335
|
-
*
|
|
336
|
-
* Returns true if the span should be created, false otherwise.
|
|
337
|
-
*
|
|
338
|
-
* Logic:
|
|
339
|
-
* 1. If instrumentation disabled globally, return false
|
|
340
|
-
* 2. Check ignore patterns - if any match, return false
|
|
341
|
-
* 3. Check instrument patterns - if any match, return true
|
|
342
|
-
* 4. Default: return true (fail-open - create span if no patterns match)
|
|
343
|
-
*/
|
|
344
|
-
shouldInstrument(spanName) {
|
|
345
|
-
if (!this.enabled) {
|
|
346
|
-
return false;
|
|
347
|
-
}
|
|
348
|
-
for (const pattern of this.ignorePatterns) {
|
|
349
|
-
if (pattern.regex.test(spanName)) {
|
|
350
|
-
return false;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
for (const pattern of this.instrumentPatterns) {
|
|
354
|
-
if (pattern.enabled && pattern.regex.test(spanName)) {
|
|
355
|
-
return true;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
return true;
|
|
359
|
-
}
|
|
360
|
-
/**
|
|
361
|
-
* Get statistics about pattern matching (for debugging/monitoring)
|
|
362
|
-
*/
|
|
363
|
-
getStats() {
|
|
364
|
-
return {
|
|
365
|
-
enabled: this.enabled,
|
|
366
|
-
ignorePatternCount: this.ignorePatterns.length,
|
|
367
|
-
instrumentPatternCount: this.instrumentPatterns.filter((p) => p.enabled).length
|
|
368
|
-
};
|
|
369
|
-
}
|
|
370
|
-
};
|
|
371
|
-
var globalMatcher = null;
|
|
372
|
-
function initializePatternMatcher(config) {
|
|
373
|
-
globalMatcher = new PatternMatcher(config);
|
|
374
|
-
}
|
|
375
|
-
function shouldInstrumentSpan(spanName) {
|
|
376
|
-
if (!globalMatcher) {
|
|
377
|
-
return true;
|
|
378
|
-
}
|
|
379
|
-
return globalMatcher.shouldInstrument(spanName);
|
|
380
|
-
}
|
|
381
|
-
function getPatternMatcher() {
|
|
382
|
-
return globalMatcher;
|
|
383
|
-
}
|
|
384
|
-
var Logger = class {
|
|
385
|
-
constructor() {
|
|
386
|
-
__publicField2(this, "level", "on");
|
|
387
|
-
__publicField2(this, "hasLoggedMinimal", false);
|
|
388
|
-
}
|
|
389
|
-
/**
|
|
390
|
-
* Set the logging level
|
|
391
|
-
*/
|
|
392
|
-
setLevel(level) {
|
|
393
|
-
this.level = level;
|
|
394
|
-
this.hasLoggedMinimal = false;
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Get the current logging level
|
|
398
|
-
*/
|
|
399
|
-
getLevel() {
|
|
400
|
-
return this.level;
|
|
401
|
-
}
|
|
402
|
-
/**
|
|
403
|
-
* Log a minimal initialization message (only shown once in minimal mode)
|
|
404
|
-
*/
|
|
405
|
-
minimal(message) {
|
|
406
|
-
if (this.level === "off") {
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
if (this.level === "minimal" && !this.hasLoggedMinimal) {
|
|
410
|
-
console.log(message);
|
|
411
|
-
this.hasLoggedMinimal = true;
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
if (this.level === "on") {
|
|
415
|
-
console.log(message);
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
/**
|
|
419
|
-
* Log an informational message
|
|
420
|
-
*/
|
|
421
|
-
log(...args) {
|
|
422
|
-
if (this.level === "on") {
|
|
423
|
-
console.log(...args);
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
/**
|
|
427
|
-
* Log a warning message (shown in minimal mode)
|
|
428
|
-
*/
|
|
429
|
-
warn(...args) {
|
|
430
|
-
if (this.level !== "off") {
|
|
431
|
-
console.warn(...args);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
/**
|
|
435
|
-
* Log an error message (shown in minimal mode)
|
|
436
|
-
*/
|
|
437
|
-
error(...args) {
|
|
438
|
-
if (this.level !== "off") {
|
|
439
|
-
console.error(...args);
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
/**
|
|
443
|
-
* Check if full logging is enabled
|
|
444
|
-
*/
|
|
445
|
-
isEnabled() {
|
|
446
|
-
return this.level === "on";
|
|
447
|
-
}
|
|
448
|
-
/**
|
|
449
|
-
* Check if minimal logging is enabled
|
|
450
|
-
*/
|
|
451
|
-
isMinimal() {
|
|
452
|
-
return this.level === "minimal";
|
|
453
|
-
}
|
|
454
|
-
/**
|
|
455
|
-
* Check if logging is completely disabled
|
|
456
|
-
*/
|
|
457
|
-
isDisabled() {
|
|
458
|
-
return this.level === "off";
|
|
459
|
-
}
|
|
460
|
-
};
|
|
461
|
-
var logger = new Logger();
|
|
462
|
-
|
|
463
|
-
// src/core/span-processor.ts
|
|
464
24
|
var PatternSpanProcessor = class {
|
|
465
25
|
constructor(config, wrappedProcessor) {
|
|
466
26
|
__publicField(this, "matcher");
|
|
467
27
|
__publicField(this, "wrappedProcessor");
|
|
468
|
-
this.matcher = new PatternMatcher(config);
|
|
28
|
+
this.matcher = new instrumentCore.PatternMatcher(config);
|
|
469
29
|
this.wrappedProcessor = wrappedProcessor;
|
|
470
30
|
}
|
|
471
31
|
/**
|
|
@@ -538,8 +98,6 @@ function getOtlpEndpoint(options = {}) {
|
|
|
538
98
|
const endpoint = options.endpoint || process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT || process.env.OTEL_EXPORTER_OTLP_ENDPOINT || DEFAULT_OTLP_ENDPOINT;
|
|
539
99
|
return normalizeEndpoint(endpoint);
|
|
540
100
|
}
|
|
541
|
-
|
|
542
|
-
// src/core/safe-exporter.ts
|
|
543
101
|
var SafeSpanExporter = class {
|
|
544
102
|
// Log errors max once per minute
|
|
545
103
|
constructor(exporter) {
|
|
@@ -576,7 +134,7 @@ var SafeSpanExporter = class {
|
|
|
576
134
|
try {
|
|
577
135
|
await this.exporter.shutdown();
|
|
578
136
|
} catch (error) {
|
|
579
|
-
logger.error(
|
|
137
|
+
instrumentCore.logger.error(
|
|
580
138
|
"@atrim/instrumentation: Error during exporter shutdown (non-critical):",
|
|
581
139
|
error instanceof Error ? error.message : String(error)
|
|
582
140
|
);
|
|
@@ -605,14 +163,14 @@ var SafeSpanExporter = class {
|
|
|
605
163
|
if (shouldLog) {
|
|
606
164
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
607
165
|
if (this.isConnectionError(error)) {
|
|
608
|
-
logger.warn(`@atrim/instrumentation: Unable to export spans - collector not available`);
|
|
609
|
-
logger.warn(` Error: ${errorMessage}`);
|
|
610
|
-
logger.warn(` Spans will be dropped. Ensure OTEL collector is running.`);
|
|
166
|
+
instrumentCore.logger.warn(`@atrim/instrumentation: Unable to export spans - collector not available`);
|
|
167
|
+
instrumentCore.logger.warn(` Error: ${errorMessage}`);
|
|
168
|
+
instrumentCore.logger.warn(` Spans will be dropped. Ensure OTEL collector is running.`);
|
|
611
169
|
} else {
|
|
612
|
-
logger.error("@atrim/instrumentation: Span export failed:", errorMessage);
|
|
170
|
+
instrumentCore.logger.error("@atrim/instrumentation: Span export failed:", errorMessage);
|
|
613
171
|
}
|
|
614
172
|
if (this.errorCount > 1) {
|
|
615
|
-
logger.warn(` (${this.errorCount} errors total, throttled to 1/min)`);
|
|
173
|
+
instrumentCore.logger.warn(` (${this.errorCount} errors total, throttled to 1/min)`);
|
|
616
174
|
}
|
|
617
175
|
this.lastErrorTime = now;
|
|
618
176
|
this.errorCount = 0;
|
|
@@ -639,21 +197,21 @@ var SafeSpanExporter = class {
|
|
|
639
197
|
return false;
|
|
640
198
|
}
|
|
641
199
|
};
|
|
642
|
-
var
|
|
200
|
+
var ConfigError = class extends effect.Data.TaggedError("ConfigError") {
|
|
643
201
|
};
|
|
644
|
-
var
|
|
202
|
+
var ConfigUrlError = class extends effect.Data.TaggedError("ConfigUrlError") {
|
|
645
203
|
};
|
|
646
|
-
var
|
|
204
|
+
var ConfigValidationError = class extends effect.Data.TaggedError("ConfigValidationError") {
|
|
647
205
|
};
|
|
648
|
-
var
|
|
206
|
+
var ConfigFileError = class extends effect.Data.TaggedError("ConfigFileError") {
|
|
649
207
|
};
|
|
650
|
-
var
|
|
208
|
+
var ServiceDetectionError = class extends effect.Data.TaggedError("ServiceDetectionError") {
|
|
651
209
|
};
|
|
652
|
-
var
|
|
210
|
+
var InitializationError = class extends effect.Data.TaggedError("InitializationError") {
|
|
653
211
|
};
|
|
654
|
-
var
|
|
212
|
+
var ExportError = class extends effect.Data.TaggedError("ExportError") {
|
|
655
213
|
};
|
|
656
|
-
var
|
|
214
|
+
var ShutdownError = class extends effect.Data.TaggedError("ShutdownError") {
|
|
657
215
|
};
|
|
658
216
|
|
|
659
217
|
// src/core/service-detector.ts
|
|
@@ -670,7 +228,7 @@ var detectServiceInfo = effect.Effect.gen(
|
|
|
670
228
|
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
671
229
|
const packageJsonContent = yield* effect.Effect.tryPromise({
|
|
672
230
|
try: () => promises.readFile(packageJsonPath, "utf-8"),
|
|
673
|
-
catch: (error) => new
|
|
231
|
+
catch: (error) => new ServiceDetectionError({
|
|
674
232
|
reason: `Failed to read package.json at ${packageJsonPath}`,
|
|
675
233
|
cause: error
|
|
676
234
|
})
|
|
@@ -680,7 +238,7 @@ var detectServiceInfo = effect.Effect.gen(
|
|
|
680
238
|
parsed = JSON.parse(packageJsonContent);
|
|
681
239
|
} catch (error) {
|
|
682
240
|
yield* effect.Effect.fail(
|
|
683
|
-
new
|
|
241
|
+
new ServiceDetectionError({
|
|
684
242
|
reason: "Invalid JSON in package.json",
|
|
685
243
|
cause: error
|
|
686
244
|
})
|
|
@@ -696,7 +254,7 @@ var detectServiceInfo = effect.Effect.gen(
|
|
|
696
254
|
}
|
|
697
255
|
}
|
|
698
256
|
return yield* effect.Effect.fail(
|
|
699
|
-
new
|
|
257
|
+
new ServiceDetectionError({
|
|
700
258
|
reason: 'package.json exists but has no "name" field'
|
|
701
259
|
})
|
|
702
260
|
);
|
|
@@ -727,6 +285,84 @@ async function getServiceNameAsync() {
|
|
|
727
285
|
async function getServiceVersionAsync() {
|
|
728
286
|
return effect.Effect.runPromise(getServiceVersion);
|
|
729
287
|
}
|
|
288
|
+
var NodeConfigLoaderLive = instrumentCore.ConfigLoaderLive.pipe(
|
|
289
|
+
effect.Layer.provide(effect.Layer.mergeAll(platformNode.NodeContext.layer, platform.FetchHttpClient.layer))
|
|
290
|
+
);
|
|
291
|
+
var cachedLoaderPromise = null;
|
|
292
|
+
function getCachedLoader() {
|
|
293
|
+
if (!cachedLoaderPromise) {
|
|
294
|
+
cachedLoaderPromise = effect.Effect.runPromise(
|
|
295
|
+
effect.Effect.gen(function* () {
|
|
296
|
+
return yield* instrumentCore.ConfigLoader;
|
|
297
|
+
}).pipe(effect.Effect.provide(NodeConfigLoaderLive))
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
return cachedLoaderPromise;
|
|
301
|
+
}
|
|
302
|
+
function _resetConfigLoaderCache() {
|
|
303
|
+
cachedLoaderPromise = null;
|
|
304
|
+
}
|
|
305
|
+
async function loadConfig(uri, options) {
|
|
306
|
+
if (options?.cacheTimeout === 0) {
|
|
307
|
+
const program = effect.Effect.gen(function* () {
|
|
308
|
+
const loader2 = yield* instrumentCore.ConfigLoader;
|
|
309
|
+
return yield* loader2.loadFromUri(uri);
|
|
310
|
+
});
|
|
311
|
+
return effect.Effect.runPromise(program.pipe(effect.Effect.provide(NodeConfigLoaderLive)));
|
|
312
|
+
}
|
|
313
|
+
const loader = await getCachedLoader();
|
|
314
|
+
return effect.Effect.runPromise(loader.loadFromUri(uri));
|
|
315
|
+
}
|
|
316
|
+
async function loadConfigFromInline(content) {
|
|
317
|
+
const loader = await getCachedLoader();
|
|
318
|
+
return effect.Effect.runPromise(loader.loadFromInline(content));
|
|
319
|
+
}
|
|
320
|
+
function getDefaultConfig() {
|
|
321
|
+
return {
|
|
322
|
+
version: "1.0",
|
|
323
|
+
instrumentation: {
|
|
324
|
+
enabled: true,
|
|
325
|
+
logging: "on",
|
|
326
|
+
description: "Default instrumentation configuration",
|
|
327
|
+
instrument_patterns: [
|
|
328
|
+
{ pattern: "^app\\.", enabled: true, description: "Application operations" },
|
|
329
|
+
{ pattern: "^http\\.server\\.", enabled: true, description: "HTTP server operations" },
|
|
330
|
+
{ pattern: "^http\\.client\\.", enabled: true, description: "HTTP client operations" }
|
|
331
|
+
],
|
|
332
|
+
ignore_patterns: [
|
|
333
|
+
{ pattern: "^test\\.", description: "Test utilities" },
|
|
334
|
+
{ pattern: "^internal\\.", description: "Internal operations" },
|
|
335
|
+
{ pattern: "^health\\.", description: "Health checks" }
|
|
336
|
+
]
|
|
337
|
+
},
|
|
338
|
+
effect: {
|
|
339
|
+
auto_extract_metadata: true
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
async function loadConfigWithOptions(options = {}) {
|
|
344
|
+
const loadOptions = options.cacheTimeout !== void 0 ? { cacheTimeout: options.cacheTimeout } : void 0;
|
|
345
|
+
if (options.config) {
|
|
346
|
+
return loadConfigFromInline(options.config);
|
|
347
|
+
}
|
|
348
|
+
const envConfigPath = process.env.ATRIM_INSTRUMENTATION_CONFIG;
|
|
349
|
+
if (envConfigPath) {
|
|
350
|
+
return loadConfig(envConfigPath, loadOptions);
|
|
351
|
+
}
|
|
352
|
+
if (options.configUrl) {
|
|
353
|
+
return loadConfig(options.configUrl, loadOptions);
|
|
354
|
+
}
|
|
355
|
+
if (options.configPath) {
|
|
356
|
+
return loadConfig(options.configPath, loadOptions);
|
|
357
|
+
}
|
|
358
|
+
const { existsSync } = await import('fs');
|
|
359
|
+
const { join: join2 } = await import('path');
|
|
360
|
+
const defaultPath = join2(process.cwd(), "instrumentation.yaml");
|
|
361
|
+
if (existsSync(defaultPath)) {
|
|
362
|
+
return loadConfig(defaultPath, loadOptions);
|
|
363
|
+
}
|
|
364
|
+
return getDefaultConfig();
|
|
365
|
+
}
|
|
730
366
|
|
|
731
367
|
// src/core/sdk-initializer.ts
|
|
732
368
|
var sdkInstance = null;
|
|
@@ -739,7 +375,7 @@ function buildHttpInstrumentationConfig(options, config, _otlpEndpoint) {
|
|
|
739
375
|
...programmaticPatterns.map((p) => typeof p === "string" ? new RegExp(p) : p),
|
|
740
376
|
...yamlPatterns.map((p) => new RegExp(p))
|
|
741
377
|
];
|
|
742
|
-
logger.log(`HTTP filtering: ${allOutgoingPatterns.length} outgoing patterns configured`);
|
|
378
|
+
instrumentCore.logger.log(`HTTP filtering: ${allOutgoingPatterns.length} outgoing patterns configured`);
|
|
743
379
|
if (options.http?.ignoreOutgoingRequestHook) {
|
|
744
380
|
httpConfig.ignoreOutgoingRequestHook = options.http.ignoreOutgoingRequestHook;
|
|
745
381
|
} else if (allOutgoingPatterns.length > 0) {
|
|
@@ -808,9 +444,9 @@ function shouldEnableAutoInstrumentation(explicitValue, hasWebFramework) {
|
|
|
808
444
|
}
|
|
809
445
|
const isEffect = isEffectProject();
|
|
810
446
|
if (isEffect && !hasWebFramework) {
|
|
811
|
-
logger.log("@atrim/instrumentation: Detected Effect-TS without web framework");
|
|
812
|
-
logger.log(" - Auto-instrumentation disabled by default");
|
|
813
|
-
logger.log(" - Effect.withSpan() will create spans");
|
|
447
|
+
instrumentCore.logger.log("@atrim/instrumentation: Detected Effect-TS without web framework");
|
|
448
|
+
instrumentCore.logger.log(" - Auto-instrumentation disabled by default");
|
|
449
|
+
instrumentCore.logger.log(" - Effect.withSpan() will create spans");
|
|
814
450
|
return false;
|
|
815
451
|
}
|
|
816
452
|
return true;
|
|
@@ -848,11 +484,11 @@ function isTracingAlreadyInitialized() {
|
|
|
848
484
|
}
|
|
849
485
|
async function initializeSdk(options = {}) {
|
|
850
486
|
if (sdkInstance) {
|
|
851
|
-
logger.warn("@atrim/instrumentation: SDK already initialized. Returning existing instance.");
|
|
487
|
+
instrumentCore.logger.warn("@atrim/instrumentation: SDK already initialized. Returning existing instance.");
|
|
852
488
|
return sdkInstance;
|
|
853
489
|
}
|
|
854
490
|
if (initializationPromise) {
|
|
855
|
-
logger.log(
|
|
491
|
+
instrumentCore.logger.log(
|
|
856
492
|
"@atrim/instrumentation: SDK already initialized, waiting for initialization to complete..."
|
|
857
493
|
);
|
|
858
494
|
return initializationPromise;
|
|
@@ -866,20 +502,20 @@ async function initializeSdk(options = {}) {
|
|
|
866
502
|
}
|
|
867
503
|
}
|
|
868
504
|
async function performInitialization(options) {
|
|
869
|
-
const config = await
|
|
505
|
+
const config = await loadConfigWithOptions(options);
|
|
870
506
|
const loggingLevel = config.instrumentation.logging || "on";
|
|
871
|
-
logger.setLevel(loggingLevel);
|
|
507
|
+
instrumentCore.logger.setLevel(loggingLevel);
|
|
872
508
|
const alreadyInitialized = isTracingAlreadyInitialized();
|
|
873
509
|
if (alreadyInitialized) {
|
|
874
|
-
logger.log("@atrim/instrumentation: Detected existing OpenTelemetry initialization.");
|
|
875
|
-
logger.log(" - Skipping NodeSDK setup");
|
|
876
|
-
logger.log(" - Setting up pattern-based filtering only");
|
|
877
|
-
logger.log("");
|
|
878
|
-
initializePatternMatcher(config);
|
|
879
|
-
logger.log("@atrim/instrumentation: Pattern filtering initialized");
|
|
880
|
-
logger.log(" \u26A0\uFE0F Note: Pattern filtering will only work with manual spans");
|
|
881
|
-
logger.log(" \u26A0\uFE0F Auto-instrumentation must be configured separately");
|
|
882
|
-
logger.log("");
|
|
510
|
+
instrumentCore.logger.log("@atrim/instrumentation: Detected existing OpenTelemetry initialization.");
|
|
511
|
+
instrumentCore.logger.log(" - Skipping NodeSDK setup");
|
|
512
|
+
instrumentCore.logger.log(" - Setting up pattern-based filtering only");
|
|
513
|
+
instrumentCore.logger.log("");
|
|
514
|
+
instrumentCore.initializePatternMatcher(config);
|
|
515
|
+
instrumentCore.logger.log("@atrim/instrumentation: Pattern filtering initialized");
|
|
516
|
+
instrumentCore.logger.log(" \u26A0\uFE0F Note: Pattern filtering will only work with manual spans");
|
|
517
|
+
instrumentCore.logger.log(" \u26A0\uFE0F Auto-instrumentation must be configured separately");
|
|
518
|
+
instrumentCore.logger.log("");
|
|
883
519
|
return null;
|
|
884
520
|
}
|
|
885
521
|
const serviceInfo = await detectServiceInfoAsync();
|
|
@@ -915,7 +551,7 @@ async function performInitialization(options) {
|
|
|
915
551
|
"@opentelemetry/instrumentation-dns": { enabled: false }
|
|
916
552
|
})
|
|
917
553
|
);
|
|
918
|
-
logger.log(`Auto-instrumentation: ${instrumentations.length} instrumentations enabled`);
|
|
554
|
+
instrumentCore.logger.log(`Auto-instrumentation: ${instrumentations.length} instrumentations enabled`);
|
|
919
555
|
}
|
|
920
556
|
if (options.instrumentations) {
|
|
921
557
|
instrumentations.push(...options.instrumentations);
|
|
@@ -923,14 +559,14 @@ async function performInitialization(options) {
|
|
|
923
559
|
if (!enableAutoInstrumentation && instrumentations.length === 0) {
|
|
924
560
|
const wasExplicit = options.autoInstrument === false;
|
|
925
561
|
const detectionMessage = wasExplicit ? "@atrim/instrumentation: Auto-instrumentation: disabled" : "@atrim/instrumentation: Pure Effect-TS app detected (auto-detected)";
|
|
926
|
-
logger.log(detectionMessage);
|
|
927
|
-
logger.log(" - Skipping NodeSDK setup");
|
|
928
|
-
logger.log(" - Pattern matching configured from instrumentation.yaml");
|
|
562
|
+
instrumentCore.logger.log(detectionMessage);
|
|
563
|
+
instrumentCore.logger.log(" - Skipping NodeSDK setup");
|
|
564
|
+
instrumentCore.logger.log(" - Pattern matching configured from instrumentation.yaml");
|
|
929
565
|
if (!wasExplicit) {
|
|
930
|
-
logger.log(" - Use EffectInstrumentationLive for tracing");
|
|
566
|
+
instrumentCore.logger.log(" - Use EffectInstrumentationLive for tracing");
|
|
931
567
|
}
|
|
932
|
-
logger.log("");
|
|
933
|
-
initializePatternMatcher(config);
|
|
568
|
+
instrumentCore.logger.log("");
|
|
569
|
+
instrumentCore.initializePatternMatcher(config);
|
|
934
570
|
return null;
|
|
935
571
|
}
|
|
936
572
|
const sdkConfig = {
|
|
@@ -966,14 +602,14 @@ function resetSdk() {
|
|
|
966
602
|
}
|
|
967
603
|
function registerShutdownHandlers(sdk) {
|
|
968
604
|
const shutdown = async (signal) => {
|
|
969
|
-
logger.log(`
|
|
605
|
+
instrumentCore.logger.log(`
|
|
970
606
|
@atrim/instrumentation: Received ${signal}, shutting down gracefully...`);
|
|
971
607
|
try {
|
|
972
608
|
await sdk.shutdown();
|
|
973
|
-
logger.log("@atrim/instrumentation: Shutdown complete");
|
|
609
|
+
instrumentCore.logger.log("@atrim/instrumentation: Shutdown complete");
|
|
974
610
|
process.exit(0);
|
|
975
611
|
} catch (error) {
|
|
976
|
-
logger.error(
|
|
612
|
+
instrumentCore.logger.error(
|
|
977
613
|
"@atrim/instrumentation: Error during shutdown:",
|
|
978
614
|
error instanceof Error ? error.message : String(error)
|
|
979
615
|
);
|
|
@@ -983,77 +619,75 @@ function registerShutdownHandlers(sdk) {
|
|
|
983
619
|
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
984
620
|
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
985
621
|
process.on("uncaughtException", async (error) => {
|
|
986
|
-
logger.error("@atrim/instrumentation: Uncaught exception:", error);
|
|
622
|
+
instrumentCore.logger.error("@atrim/instrumentation: Uncaught exception:", error);
|
|
987
623
|
await sdk.shutdown();
|
|
988
624
|
process.exit(1);
|
|
989
625
|
});
|
|
990
626
|
process.on("unhandledRejection", async (reason) => {
|
|
991
|
-
logger.error("@atrim/instrumentation: Unhandled rejection:", reason);
|
|
627
|
+
instrumentCore.logger.error("@atrim/instrumentation: Unhandled rejection:", reason);
|
|
992
628
|
await sdk.shutdown();
|
|
993
629
|
process.exit(1);
|
|
994
630
|
});
|
|
995
631
|
}
|
|
996
632
|
function logInitialization(config, serviceName, serviceVersion, options, autoInstrumentEnabled) {
|
|
997
|
-
logger.minimal("@atrim/instrumentation: SDK initialized successfully");
|
|
998
|
-
logger.log(` - Service: ${serviceName}${serviceVersion ? ` v${serviceVersion}` : ""}`);
|
|
633
|
+
instrumentCore.logger.minimal("@atrim/instrumentation: SDK initialized successfully");
|
|
634
|
+
instrumentCore.logger.log(` - Service: ${serviceName}${serviceVersion ? ` v${serviceVersion}` : ""}`);
|
|
999
635
|
if (config.instrumentation.enabled) {
|
|
1000
636
|
const instrumentCount = config.instrumentation.instrument_patterns.filter(
|
|
1001
637
|
(p) => p.enabled !== false
|
|
1002
638
|
).length;
|
|
1003
639
|
const ignoreCount = config.instrumentation.ignore_patterns.length;
|
|
1004
|
-
logger.log(` - Pattern filtering: enabled`);
|
|
1005
|
-
logger.log(` - Instrument patterns: ${instrumentCount}`);
|
|
1006
|
-
logger.log(` - Ignore patterns: ${ignoreCount}`);
|
|
640
|
+
instrumentCore.logger.log(` - Pattern filtering: enabled`);
|
|
641
|
+
instrumentCore.logger.log(` - Instrument patterns: ${instrumentCount}`);
|
|
642
|
+
instrumentCore.logger.log(` - Ignore patterns: ${ignoreCount}`);
|
|
1007
643
|
} else {
|
|
1008
|
-
logger.log(` - Pattern filtering: disabled`);
|
|
644
|
+
instrumentCore.logger.log(` - Pattern filtering: disabled`);
|
|
1009
645
|
}
|
|
1010
646
|
const autoInstrumentLabel = autoInstrumentEnabled ? "enabled" : "disabled";
|
|
1011
647
|
const autoDetected = options.autoInstrument === void 0 ? " (auto-detected)" : "";
|
|
1012
|
-
logger.log(` - Auto-instrumentation: ${autoInstrumentLabel}${autoDetected}`);
|
|
648
|
+
instrumentCore.logger.log(` - Auto-instrumentation: ${autoInstrumentLabel}${autoDetected}`);
|
|
1013
649
|
if (options.instrumentations && options.instrumentations.length > 0) {
|
|
1014
|
-
logger.log(` - Custom instrumentations: ${options.instrumentations.length}`);
|
|
650
|
+
instrumentCore.logger.log(` - Custom instrumentations: ${options.instrumentations.length}`);
|
|
1015
651
|
}
|
|
1016
652
|
const endpoint = options.otlp?.endpoint || process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT || process.env.OTEL_EXPORTER_OTLP_ENDPOINT || "http://localhost:4318/v1/traces";
|
|
1017
|
-
logger.log(` - OTLP endpoint: ${endpoint}`);
|
|
1018
|
-
logger.log("");
|
|
653
|
+
instrumentCore.logger.log(` - OTLP endpoint: ${endpoint}`);
|
|
654
|
+
instrumentCore.logger.log("");
|
|
1019
655
|
}
|
|
1020
|
-
|
|
1021
|
-
// src/api.ts
|
|
1022
656
|
async function initializeInstrumentation(options = {}) {
|
|
1023
657
|
const sdk = await initializeSdk(options);
|
|
1024
658
|
if (sdk) {
|
|
1025
|
-
const config = await
|
|
1026
|
-
initializePatternMatcher(config);
|
|
659
|
+
const config = await loadConfigWithOptions(options);
|
|
660
|
+
instrumentCore.initializePatternMatcher(config);
|
|
1027
661
|
}
|
|
1028
662
|
return sdk;
|
|
1029
663
|
}
|
|
1030
664
|
async function initializePatternMatchingOnly(options = {}) {
|
|
1031
|
-
const config = await
|
|
1032
|
-
initializePatternMatcher(config);
|
|
1033
|
-
logger.log("@atrim/instrumentation: Pattern matching initialized (legacy mode)");
|
|
1034
|
-
logger.log(
|
|
665
|
+
const config = await loadConfigWithOptions(options);
|
|
666
|
+
instrumentCore.initializePatternMatcher(config);
|
|
667
|
+
instrumentCore.logger.log("@atrim/instrumentation: Pattern matching initialized (legacy mode)");
|
|
668
|
+
instrumentCore.logger.log(
|
|
1035
669
|
" Note: NodeSDK is not initialized. Use initializeInstrumentation() for complete setup."
|
|
1036
670
|
);
|
|
1037
671
|
}
|
|
1038
672
|
var initializeInstrumentationEffect = (options = {}) => effect.Effect.gen(function* () {
|
|
1039
673
|
const sdk = yield* effect.Effect.tryPromise({
|
|
1040
674
|
try: () => initializeSdk(options),
|
|
1041
|
-
catch: (error) => new
|
|
675
|
+
catch: (error) => new InitializationError({
|
|
1042
676
|
reason: "SDK initialization failed",
|
|
1043
677
|
cause: error
|
|
1044
678
|
})
|
|
1045
679
|
});
|
|
1046
680
|
if (sdk) {
|
|
1047
681
|
yield* effect.Effect.tryPromise({
|
|
1048
|
-
try: () =>
|
|
1049
|
-
catch: (error) => new
|
|
682
|
+
try: () => loadConfigWithOptions(options),
|
|
683
|
+
catch: (error) => new ConfigError({
|
|
1050
684
|
reason: "Failed to load config for pattern matcher",
|
|
1051
685
|
cause: error
|
|
1052
686
|
})
|
|
1053
687
|
}).pipe(
|
|
1054
688
|
effect.Effect.tap(
|
|
1055
689
|
(config) => effect.Effect.sync(() => {
|
|
1056
|
-
initializePatternMatcher(config);
|
|
690
|
+
instrumentCore.initializePatternMatcher(config);
|
|
1057
691
|
})
|
|
1058
692
|
)
|
|
1059
693
|
);
|
|
@@ -1062,16 +696,16 @@ var initializeInstrumentationEffect = (options = {}) => effect.Effect.gen(functi
|
|
|
1062
696
|
});
|
|
1063
697
|
var initializePatternMatchingOnlyEffect = (options = {}) => effect.Effect.gen(function* () {
|
|
1064
698
|
const config = yield* effect.Effect.tryPromise({
|
|
1065
|
-
try: () =>
|
|
1066
|
-
catch: (error) => new
|
|
699
|
+
try: () => loadConfigWithOptions(options),
|
|
700
|
+
catch: (error) => new ConfigError({
|
|
1067
701
|
reason: "Failed to load configuration",
|
|
1068
702
|
cause: error
|
|
1069
703
|
})
|
|
1070
704
|
});
|
|
1071
705
|
yield* effect.Effect.sync(() => {
|
|
1072
|
-
initializePatternMatcher(config);
|
|
1073
|
-
logger.log("@atrim/instrumentation: Pattern matching initialized (legacy mode)");
|
|
1074
|
-
logger.log(
|
|
706
|
+
instrumentCore.initializePatternMatcher(config);
|
|
707
|
+
instrumentCore.logger.log("@atrim/instrumentation: Pattern matching initialized (legacy mode)");
|
|
708
|
+
instrumentCore.logger.log(
|
|
1075
709
|
" Note: NodeSDK is not initialized. Use initializeInstrumentation() for complete setup."
|
|
1076
710
|
);
|
|
1077
711
|
});
|
|
@@ -1171,24 +805,35 @@ function suppressShutdownErrors() {
|
|
|
1171
805
|
});
|
|
1172
806
|
}
|
|
1173
807
|
|
|
1174
|
-
exports
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
exports
|
|
1179
|
-
|
|
1180
|
-
|
|
808
|
+
Object.defineProperty(exports, "PatternMatcher", {
|
|
809
|
+
enumerable: true,
|
|
810
|
+
get: function () { return instrumentCore.PatternMatcher; }
|
|
811
|
+
});
|
|
812
|
+
Object.defineProperty(exports, "getPatternMatcher", {
|
|
813
|
+
enumerable: true,
|
|
814
|
+
get: function () { return instrumentCore.getPatternMatcher; }
|
|
815
|
+
});
|
|
816
|
+
Object.defineProperty(exports, "shouldInstrumentSpan", {
|
|
817
|
+
enumerable: true,
|
|
818
|
+
get: function () { return instrumentCore.shouldInstrumentSpan; }
|
|
819
|
+
});
|
|
820
|
+
exports.ConfigError = ConfigError;
|
|
821
|
+
exports.ConfigFileError = ConfigFileError;
|
|
822
|
+
exports.ConfigUrlError = ConfigUrlError;
|
|
823
|
+
exports.ConfigValidationError = ConfigValidationError;
|
|
824
|
+
exports.ExportError = ExportError;
|
|
825
|
+
exports.InitializationError = InitializationError;
|
|
1181
826
|
exports.PatternSpanProcessor = PatternSpanProcessor;
|
|
1182
|
-
exports.ServiceDetectionError =
|
|
1183
|
-
exports.ShutdownError =
|
|
827
|
+
exports.ServiceDetectionError = ServiceDetectionError;
|
|
828
|
+
exports.ShutdownError = ShutdownError;
|
|
1184
829
|
exports.annotateCacheOperation = annotateCacheOperation;
|
|
1185
830
|
exports.annotateDbQuery = annotateDbQuery;
|
|
1186
831
|
exports.annotateHttpRequest = annotateHttpRequest;
|
|
832
|
+
exports.clearConfigCache = _resetConfigLoaderCache;
|
|
1187
833
|
exports.createOtlpExporter = createOtlpExporter;
|
|
1188
834
|
exports.detectServiceInfo = detectServiceInfoAsync;
|
|
1189
835
|
exports.detectServiceInfoEffect = detectServiceInfo;
|
|
1190
836
|
exports.getOtlpEndpoint = getOtlpEndpoint;
|
|
1191
|
-
exports.getPatternMatcher = getPatternMatcher;
|
|
1192
837
|
exports.getSdkInstance = getSdkInstance;
|
|
1193
838
|
exports.getServiceInfoWithFallback = getServiceInfoWithFallback;
|
|
1194
839
|
exports.getServiceName = getServiceNameAsync;
|
|
@@ -1200,12 +845,13 @@ exports.initializeInstrumentationEffect = initializeInstrumentationEffect;
|
|
|
1200
845
|
exports.initializePatternMatchingOnly = initializePatternMatchingOnly;
|
|
1201
846
|
exports.initializePatternMatchingOnlyEffect = initializePatternMatchingOnlyEffect;
|
|
1202
847
|
exports.loadConfig = loadConfig;
|
|
848
|
+
exports.loadConfigFromInline = loadConfigFromInline;
|
|
849
|
+
exports.loadConfigWithOptions = loadConfigWithOptions;
|
|
1203
850
|
exports.markSpanError = markSpanError;
|
|
1204
851
|
exports.markSpanSuccess = markSpanSuccess;
|
|
1205
852
|
exports.recordException = recordException;
|
|
1206
853
|
exports.resetSdk = resetSdk;
|
|
1207
854
|
exports.setSpanAttributes = setSpanAttributes;
|
|
1208
|
-
exports.shouldInstrumentSpan = shouldInstrumentSpan;
|
|
1209
855
|
exports.shutdownSdk = shutdownSdk;
|
|
1210
856
|
exports.suppressShutdownErrors = suppressShutdownErrors;
|
|
1211
857
|
//# sourceMappingURL=index.cjs.map
|