unnbound-logger-sdk 3.0.2 → 3.0.4

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 CHANGED
@@ -240,6 +240,22 @@ The Axios middleware:
240
240
  - Creates spans for each HTTP request
241
241
  - Supports request/response filtering through configuration
242
242
 
243
+ ## Manual tracing
244
+
245
+ In case the function doesn't run inside an HTTP handler (for example a cron job), you can assign a trace id manually by using the `withTrace` function:
246
+
247
+ ```typescript
248
+ import { withTrace } from 'unnbound-logger';
249
+
250
+ const operation = async (value: number) => {
251
+ // This will log a { traceId, value }
252
+ logger.info('Processing value', { value });
253
+ return value * 2;
254
+ };
255
+
256
+ setInterval(() => withTrace(() => operation(13)), 1000);
257
+ ```
258
+
243
259
  ## Function Tracing with startSpan
244
260
 
245
261
  The `startSpan` function allows you to wrap any async operation with automatic span tracking and logging. This is particularly useful for maintaining consistent trace IDs across async operations and distributed systems:
@@ -262,6 +278,8 @@ const result = await startSpan('Processing operation', operation, () => ({
262
278
  const result = await startSpan('Processing operation', () => operation(21)); // Returns 42
263
279
  ```
264
280
 
281
+ _Note: In case the `traceId` is missing from the context, `startSpan` will generate one. It is recommended to use a single `traceId` across your handler though, so always consider using `traceMiddleware` and `withTrace` to inject the `traceId` instead of relying on `startSpan` to create one._
282
+
265
283
  ### Async Operations
266
284
 
267
285
  The span context is maintained across async operations:
package/dist/axios.js CHANGED
@@ -46,7 +46,7 @@ const traceAxios = (client, { ignoreTraceRoutes = types_1.defaultIgnoreTraceRout
46
46
  // Check if this request should be ignored
47
47
  if ((0, utils_1.shouldIgnorePath)(url, ignoreTraceRoutes))
48
48
  return originalMethod(config);
49
- const traceId = storage_1.storage.getStore()?.[storage_1.ContextAttribute.TraceId];
49
+ const traceId = storage_1.storage.getStore()?.traceId;
50
50
  config = { ...config, headers: { ...config.headers, [traceHeaderKey]: traceId } };
51
51
  // Execute the request within a span
52
52
  return (0, span_1.startSpan)(`Outgoing HTTP request`, () => originalMethod(config), (options) => {
package/dist/index.d.ts CHANGED
@@ -7,6 +7,7 @@
7
7
  export type { LogLevel, LogType, HttpMethod, Log, LogTransaction, SftpLog, HttpLog, SftpPayload, } from './types';
8
8
  export type { UnnboundLogger } from './logger';
9
9
  export { logger } from './logger';
10
+ export { withTrace, getTraceId } from './trace';
10
11
  export { startSpan } from './span';
11
12
  export { traceAxios } from './axios';
12
13
  export { traceMiddleware } from './middleware';
package/dist/index.js CHANGED
@@ -1,8 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.traceMiddleware = exports.traceAxios = exports.startSpan = exports.logger = void 0;
3
+ exports.traceMiddleware = exports.traceAxios = exports.startSpan = exports.getTraceId = exports.withTrace = exports.logger = void 0;
4
4
  var logger_1 = require("./logger");
5
5
  Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return logger_1.logger; } });
6
+ var trace_1 = require("./trace");
7
+ Object.defineProperty(exports, "withTrace", { enumerable: true, get: function () { return trace_1.withTrace; } });
8
+ Object.defineProperty(exports, "getTraceId", { enumerable: true, get: function () { return trace_1.getTraceId; } });
6
9
  var span_1 = require("./span");
7
10
  Object.defineProperty(exports, "startSpan", { enumerable: true, get: function () { return span_1.startSpan; } });
8
11
  var axios_1 = require("./axios");
@@ -1,11 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.traceMiddleware = void 0;
4
- const uuid_1 = require("uuid");
5
- const storage_1 = require("./storage");
6
4
  const span_1 = require("./span");
7
5
  const types_1 = require("./types");
8
6
  const utils_1 = require("./utils");
7
+ const trace_1 = require("./trace");
9
8
  const getFullUrl = (req) => {
10
9
  const url = req.originalUrl || req.url;
11
10
  if (url?.startsWith('http://') || url?.startsWith('https://'))
@@ -46,9 +45,9 @@ const traceMiddleware = ({ ignoreTraceRoutes = types_1.defaultIgnoreTraceRoutes,
46
45
  }) => async (req, res, next) => {
47
46
  if ((0, utils_1.shouldIgnorePath)(req.path, ignoreTraceRoutes))
48
47
  return next();
49
- const traceId = req.header(traceHeaderKey) || (0, uuid_1.v4)();
48
+ const traceId = req.header(traceHeaderKey) || (0, trace_1.getTraceId)();
50
49
  res.setHeader(traceHeaderKey, traceId);
51
- return await storage_1.storage.run({ [storage_1.ContextAttribute.TraceId]: traceId }, async () => {
50
+ return await (0, trace_1.withTrace)(async () => {
52
51
  return await (0, span_1.startSpan)('Incoming HTTP request', async () => {
53
52
  return new Promise((resolve) => {
54
53
  // Capture response body for logging
@@ -62,9 +61,12 @@ const traceMiddleware = ({ ignoreTraceRoutes = types_1.defaultIgnoreTraceRoutes,
62
61
  });
63
62
  }, (o) => {
64
63
  return buildIncomingHttpPayload(req, o
65
- ? { statusCode: res.statusCode, headers: res.getHeaders() }
64
+ ? {
65
+ statusCode: res.statusCode,
66
+ headers: res.getHeaders(),
67
+ }
66
68
  : undefined, res.locals.body);
67
69
  });
68
- });
70
+ }, { traceId });
69
71
  };
70
72
  exports.traceMiddleware = traceMiddleware;
package/dist/span.js CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.startSpan = void 0;
4
4
  const uuid_1 = require("uuid");
5
5
  const storage_1 = require("./storage");
6
+ const trace_1 = require("./trace");
6
7
  const logger_1 = require("./logger");
7
8
  /**
8
9
  * Starts a span that tracks the duration of a callback
@@ -16,9 +17,8 @@ const startSpan = async (spanName, callback, getter) => {
16
17
  const previous = storage_1.storage.getStore();
17
18
  return storage_1.storage.run({
18
19
  ...previous,
19
- [storage_1.ContextAttribute.SpanId]: previous?.[storage_1.ContextAttribute.SpanId]
20
- ? `${spanId} ${previous?.[storage_1.ContextAttribute.SpanId]}`
21
- : spanId,
20
+ traceId: previous?.traceId ?? (0, trace_1.getTraceId)(),
21
+ spanId: previous?.spanId ? `${spanId} ${previous?.spanId}` : spanId,
22
22
  }, async () => {
23
23
  logger_1.logger.info({ ...getLogPayload(getter) }, `${spanName} started.`);
24
24
  try {
package/dist/storage.d.ts CHANGED
@@ -1,10 +1,6 @@
1
1
  import { AsyncLocalStorage } from 'async_hooks';
2
- export declare enum ContextAttribute {
3
- TraceId = "traceId",
4
- SpanId = "spanId"
5
- }
6
2
  export interface Context {
7
- [ContextAttribute.TraceId]?: string;
8
- [ContextAttribute.SpanId]?: string;
3
+ traceId?: string;
4
+ spanId?: string;
9
5
  }
10
6
  export declare const storage: AsyncLocalStorage<Context>;
package/dist/storage.js CHANGED
@@ -1,10 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.storage = exports.ContextAttribute = void 0;
3
+ exports.storage = void 0;
4
4
  const async_hooks_1 = require("async_hooks");
5
- var ContextAttribute;
6
- (function (ContextAttribute) {
7
- ContextAttribute["TraceId"] = "traceId";
8
- ContextAttribute["SpanId"] = "spanId";
9
- })(ContextAttribute || (exports.ContextAttribute = ContextAttribute = {}));
10
5
  exports.storage = new async_hooks_1.AsyncLocalStorage();
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Generates a trace ID
3
+ * @returns A trace ID
4
+ */
5
+ export declare const getTraceId: () => string;
6
+ /**
7
+ * Runs a callback with a trace ID
8
+ * @param callback - The callback to run
9
+ * @param extra - Extra context to add to the trace
10
+ * @returns The result of the callback
11
+ */
12
+ export declare const withTrace: <T, E extends {
13
+ traceId?: string;
14
+ }>(callback: () => T, extra?: E) => T;
package/dist/trace.js ADDED
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withTrace = exports.getTraceId = void 0;
4
+ const uuid_1 = require("uuid");
5
+ const storage_1 = require("./storage");
6
+ /**
7
+ * Generates a trace ID
8
+ * @returns A trace ID
9
+ */
10
+ const getTraceId = () => (0, uuid_1.v4)();
11
+ exports.getTraceId = getTraceId;
12
+ /**
13
+ * Runs a callback with a trace ID
14
+ * @param callback - The callback to run
15
+ * @param extra - Extra context to add to the trace
16
+ * @returns The result of the callback
17
+ */
18
+ const withTrace = (callback, extra) => {
19
+ return storage_1.storage.run({ ...storage_1.storage.getStore(), ...extra, traceId: extra?.traceId ?? (0, exports.getTraceId)() }, callback);
20
+ };
21
+ exports.withTrace = withTrace;
package/dist/types.d.ts CHANGED
@@ -43,7 +43,7 @@ export interface HttpLog extends LogTransaction<'http'> {
43
43
  };
44
44
  };
45
45
  }
46
- export type SftpOperation = 'connect' | 'upload' | 'download' | 'list' | 'delete' | 'rename' | 'stat' | 'exists' | 'realPath' | 'get' | 'put' | 'cwd' | 'mkdir' | 'rmdir' | 'chmod' | 'append' | 'uploadDir' | 'downloadDir' | 'end';
46
+ export type SftpOperation = 'connect' | 'upload' | 'download' | 'list' | 'delete' | 'rename' | 'stat' | 'exists' | 'realPath' | 'get' | 'put' | 'cwd' | 'mkdir' | 'rmdir' | 'chmod' | 'append' | 'uploadDir' | 'downloadDir' | 'close';
47
47
  export interface SftpPayload {
48
48
  host: string;
49
49
  operation: SftpOperation;
@@ -51,6 +51,8 @@ export interface SftpPayload {
51
51
  bytes?: number;
52
52
  destinationPath?: string;
53
53
  files?: number;
54
+ content?: string;
55
+ exists?: string | false;
54
56
  }
55
57
  export interface SftpLog extends LogTransaction<'sftp'> {
56
58
  sftp: SftpPayload;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "unnbound-logger-sdk",
3
3
  "description": "A structured logging library with TypeScript support using Pino. Provides consistent, well-typed logging with automatic logId, workflowId, traceId, and deploymentId tracking across operational contexts.",
4
- "version": "3.0.2",
4
+ "version": "3.0.4",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "keywords": [
@@ -19,7 +19,7 @@
19
19
  "license": "MIT",
20
20
  "repository": {
21
21
  "type": "git",
22
- "url": "https://github.com/unnbounddev/unnbound-sdks.git"
22
+ "url": "git+https://github.com/unnbounddev/unnbound-sdks.git"
23
23
  },
24
24
  "homepage": "https://github.com/unnbounddev/unnbound-sdks#readme",
25
25
  "bugs": {