@ryanzeng/nest-observe 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -296,6 +296,71 @@ function bodyValue(message) {
296
296
  return redactText(message.stack ?? `${message.name}: ${message.message}`);
297
297
  return redact(message);
298
298
  }
299
+ function isPlainObject(value) {
300
+ if (value === null || typeof value !== "object") return false;
301
+ const prototype = Object.getPrototypeOf(value);
302
+ if (prototype === null) return true;
303
+ const constructor = Object.prototype.hasOwnProperty.call(prototype, "constructor") ? prototype.constructor : void 0;
304
+ return typeof constructor === "function" && constructor instanceof constructor && Function.prototype.toString.call(constructor) === Function.prototype.toString.call(Object);
305
+ }
306
+ function isStackFormat(value) {
307
+ return typeof value === "string" && /^(.)+\n\s+at .+:\d+:\d+/.test(value);
308
+ }
309
+ function fallbackMessages(logger, values) {
310
+ if (values.length <= 1) return { messages: values, context: logger.context };
311
+ const lastValue = values.at(-1);
312
+ const contextName = typeof lastValue === "string" ? lastValue : logger.context;
313
+ const remaining = typeof lastValue === "string" ? values.slice(0, -1) : values;
314
+ if (logger.options?.structuredParams === false) {
315
+ return { messages: remaining, context: contextName };
316
+ }
317
+ const messages = [remaining[0]];
318
+ const structuredParams = [];
319
+ for (const value of remaining.slice(1)) {
320
+ if (isPlainObject(value)) structuredParams.push(value);
321
+ else messages.push(value);
322
+ }
323
+ const params = structuredParams.length > 0 ? Object.assign({}, ...structuredParams) : void 0;
324
+ return { messages, context: contextName, ...params ? { params } : {} };
325
+ }
326
+ function fallbackError(logger, values) {
327
+ if (values.length === 2) {
328
+ if (isStackFormat(values[1])) {
329
+ return { messages: [values[0]], stack: values[1], context: logger.context };
330
+ }
331
+ return fallbackMessages(logger, values);
332
+ }
333
+ const trailingValue = values.at(-1);
334
+ if (isStackFormat(trailingValue)) {
335
+ return { ...fallbackMessages(logger, values.slice(0, -1)), stack: trailingValue };
336
+ }
337
+ const parsed = fallbackMessages(logger, values);
338
+ if (parsed.messages.length <= 1) return parsed;
339
+ const possibleStack = parsed.messages.at(-1);
340
+ if (typeof possibleStack !== "string" && possibleStack !== void 0) return parsed;
341
+ return {
342
+ ...parsed,
343
+ messages: parsed.messages.slice(0, -1),
344
+ ...possibleStack === void 0 ? {} : { stack: possibleStack }
345
+ };
346
+ }
347
+ function parseLogCall(logger, method, message, args) {
348
+ const values = [message, ...args];
349
+ const nestParser = method === "error" ? logger.getContextAndStackAndMessagesToPrint : logger.getContextAndMessagesToPrint;
350
+ if (typeof nestParser === "function") return nestParser.call(logger, values);
351
+ return method === "error" ? fallbackError(logger, values) : fallbackMessages(logger, values);
352
+ }
353
+ function exceptionAttributes(message, stack) {
354
+ const error = message instanceof Error ? message : void 0;
355
+ const stacktrace = stack ?? error?.stack;
356
+ return {
357
+ ...error ? {
358
+ "exception.type": error.name,
359
+ "exception.message": redactText(error.message)
360
+ } : {},
361
+ ...stacktrace ? { "exception.stacktrace": redactText(stacktrace) } : {}
362
+ };
363
+ }
299
364
  var NestLoggerInstrumentation = class {
300
365
  constructor(emitter, resourceAttributes = {}) {
301
366
  this.emitter = emitter;
@@ -317,18 +382,30 @@ var NestLoggerInstrumentation = class {
317
382
  const resourceAttributes = this.resourceAttributes;
318
383
  prototype[method] = function(message, ...args) {
319
384
  try {
385
+ const gated = this;
386
+ if (typeof gated.isLevelEnabled === "function" && !gated.isLevelEnabled(method)) {
387
+ return original.call(this, message, ...args);
388
+ }
320
389
  const spanContext = trace2.getActiveSpan()?.spanContext();
321
- const contextName = this.context ?? (typeof args.at(-1) === "string" ? String(args.at(-1)) : void 0);
322
- const attributes = { ...resourceAttributes };
323
- if (contextName) attributes["nestjs.context"] = contextName;
324
- if (spanContext?.traceId) attributes.trace_id = spanContext.traceId;
325
- if (spanContext?.spanId) attributes.span_id = spanContext.spanId;
326
- emitter.emit({
327
- body: bodyValue(message),
328
- severityText: SEVERITY[method],
329
- attributes,
330
- timestamp: Date.now()
331
- });
390
+ const parsed = parseLogCall(this, method, message, args);
391
+ const timestamp = Date.now();
392
+ for (const parsedMessage of parsed.messages) {
393
+ const params = parsed.params ? redact(parsed.params) : {};
394
+ const attributes = {
395
+ ...params,
396
+ ...resourceAttributes,
397
+ ...exceptionAttributes(parsedMessage, parsed.stack)
398
+ };
399
+ if (parsed.context) attributes["nestjs.context"] = parsed.context;
400
+ if (spanContext?.traceId) attributes.trace_id = spanContext.traceId;
401
+ if (spanContext?.spanId) attributes.span_id = spanContext.spanId;
402
+ emitter.emit({
403
+ body: bodyValue(parsedMessage),
404
+ severityText: SEVERITY[method],
405
+ attributes,
406
+ timestamp
407
+ });
408
+ }
332
409
  } catch {
333
410
  }
334
411
  return original.call(this, message, ...args);
@@ -654,7 +731,6 @@ import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-proto";
654
731
  import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
655
732
  import { registerInstrumentations } from "@opentelemetry/instrumentation";
656
733
  import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
657
- import { PrismaInstrumentation } from "@prisma/instrumentation";
658
734
  import { BatchLogRecordProcessor, LoggerProvider } from "@opentelemetry/sdk-logs";
659
735
  import { AggregationType, MeterProvider, PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
660
736
  import { AlwaysOffSampler, BatchSpanProcessor, ParentBasedSampler, TraceIdRatioBasedSampler } from "@opentelemetry/sdk-trace-base";
@@ -823,7 +899,7 @@ import { hostname } from "os";
823
899
  // package.json
824
900
  var package_default = {
825
901
  name: "@ryanzeng/nest-observe",
826
- version: "0.1.3",
902
+ version: "0.1.4",
827
903
  description: "Zero-config, vendor-neutral OpenTelemetry observability for NestJS",
828
904
  keywords: [
829
905
  "nestjs",
@@ -908,8 +984,7 @@ var package_default = {
908
984
  "@opentelemetry/sdk-logs": "^0.221.0",
909
985
  "@opentelemetry/sdk-metrics": "^2.10.0",
910
986
  "@opentelemetry/sdk-trace-base": "^2.10.0",
911
- "@opentelemetry/sdk-trace-node": "^2.10.0",
912
- "@prisma/instrumentation": "^7.10.0"
987
+ "@opentelemetry/sdk-trace-node": "^2.10.0"
913
988
  },
914
989
  devDependencies: {
915
990
  "@nestjs/common": "^12.0.1",
@@ -1224,7 +1299,6 @@ function observe(options = {}) {
1224
1299
  providerTracing: config.providerTracing,
1225
1300
  controllerTracing: config.controllerTracing
1226
1301
  }));
1227
- if (config.traces) instrumentations.push(new PrismaInstrumentation());
1228
1302
  registerInstrumentations({
1229
1303
  instrumentations,
1230
1304
  ...tracerProvider ? { tracerProvider } : {},