@ontrails/pino 1.0.0-beta.39 → 1.0.0-beta.43

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/CHANGELOG.md CHANGED
@@ -1,122 +1,15 @@
1
- # @ontrails/pino
1
+ # Changelog
2
2
 
3
- ## 1.0.0-beta.39
4
-
5
- ## 1.0.0-beta.38
6
-
7
- ## 1.0.0-beta.37
8
-
9
- ## 1.0.0-beta.36
10
-
11
- ## 1.0.0-beta.35
12
-
13
- ## 1.0.0-beta.34
14
-
15
- ## 1.0.0-beta.33
16
-
17
- ## 1.0.0-beta.32
18
-
19
- ### Patch Changes
20
-
21
- - @ontrails/observe@1.0.0-beta.32
22
-
23
- ## 1.0.0-beta.31
24
-
25
- ### Patch Changes
26
-
27
- - @ontrails/observe@1.0.0-beta.31
28
-
29
- ## 1.0.0-beta.30
30
-
31
- ### Patch Changes
32
-
33
- - @ontrails/observe@1.0.0-beta.30
34
-
35
- ## 1.0.0-beta.29
36
-
37
- ### Patch Changes
38
-
39
- - @ontrails/observe@1.0.0-beta.29
40
-
41
- ## 1.0.0-beta.28
42
-
43
- ### Patch Changes
44
-
45
- - @ontrails/observe@1.0.0-beta.28
46
-
47
- ## 1.0.0-beta.27
48
-
49
- ### Patch Changes
50
-
51
- - @ontrails/observe@1.0.0-beta.27
52
-
53
- ## 1.0.0-beta.26
54
-
55
- ### Patch Changes
56
-
57
- - @ontrails/observe@1.0.0-beta.26
58
-
59
- ## 1.0.0-beta.25
60
-
61
- ### Patch Changes
62
-
63
- - @ontrails/observe@1.0.0-beta.25
64
-
65
- ## 1.0.0-beta.24
66
-
67
- ### Patch Changes
68
-
69
- - @ontrails/observe@1.0.0-beta.24
70
-
71
- ## 1.0.0-beta.23
72
-
73
- ### Patch Changes
74
-
75
- - @ontrails/observe@1.0.0-beta.23
76
-
77
- ## 1.0.0-beta.22
78
-
79
- ### Patch Changes
80
-
81
- - @ontrails/observe@1.0.0-beta.22
82
-
83
- ## 1.0.0-beta.21
84
-
85
- ### Patch Changes
86
-
87
- - @ontrails/observe@1.0.0-beta.21
88
-
89
- ## 1.0.0-beta.20
90
-
91
- ### Patch Changes
92
-
93
- - @ontrails/observe@1.0.0-beta.20
94
-
95
- ## 1.0.0-beta.19
96
-
97
- ### Patch Changes
98
-
99
- - ed5926b: Add missing TSDoc for public adapter and sink boundary types.
100
- - Updated dependencies [1eb5bdc]
101
- - @ontrails/observe@1.0.0-beta.19
102
-
103
- ## 1.0.0-beta.18
3
+ ## 1.0.0-beta.43
104
4
 
105
5
  ### Minor Changes
106
6
 
107
- - e504e67: Add the publishable `@ontrails/pino` package scaffold.
108
- - 1a65022: Implement the structural Pino log sink.
109
-
110
- ### Patch Changes
7
+ - [`50e2779`](https://github.com/outfitter-dev/trails/commit/50e27796d074851bccd57d7df009db749757b457): Extract the real `@ontrails/logtape` and `@ontrails/pino` adapters from the
8
+ temporary observability subpaths. The new packages own their namesake foreign
9
+ dependencies and preserve Trails record metadata, levels, redaction boundaries,
10
+ and lifecycle behavior; the old subpaths are removed in the pre-v1 hard cut.
111
11
 
112
- - bf44972: Document Pino sink usage and publish-readiness checks.
113
- - Updated dependencies [bf44972]
114
- - Updated dependencies [e0ae995]
115
- - @ontrails/observe@1.0.0-beta.18
116
-
117
- ## 1.0.0-beta.17
118
-
119
- ### Minor Changes
12
+ Add governed Regrade transitions for both exact import replacements and expose
13
+ the observability adapter target through the shared adapter readiness check.
120
14
 
121
- - Initial publishable package scaffold.
122
- - Add structural Pino log sink.
15
+ All notable changes to this package are documented through the Trails release process.
package/README.md CHANGED
@@ -1,65 +1,35 @@
1
1
  # @ontrails/pino
2
2
 
3
- Pino adapter package for `@ontrails/observe`.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- bun add @ontrails/observe @ontrails/pino pino
9
- ```
10
-
11
- `pino` is supplied by your application. `@ontrails/pino` has no hard runtime dependency on it.
3
+ Real Pino adapter for Trails observability. This extracted package owns the Pino dependency boundary, keeping `@ontrails/observability` limited to Trails-native records, sink contracts, redaction, formatters, and built-ins.
12
4
 
13
5
  ## Usage
14
6
 
15
- Use `createPinoSink(...)` when you already have a Pino-shaped logger and want Trails log records to flow into it:
16
-
17
7
  ```typescript
18
8
  import pino from 'pino';
19
9
  import { createPinoSink } from '@ontrails/pino';
20
10
 
21
- const sink = createPinoSink(pino());
22
- ```
23
-
24
- The package does not depend on `pino`; it accepts any object shaped like a Pino logger through `PinoLoggerLike`. Records are forwarded in Pino's object-first style as `logger.info(payload, message)`, preserving the metadata already redacted by Trails.
25
-
26
- ```typescript
27
- import pino from 'pino';
28
- import { topo } from '@ontrails/core';
29
- import { createPinoSink } from '@ontrails/pino';
11
+ const logger = pino({ level: 'info' });
12
+ const sink = createPinoSink({ logger });
30
13
 
31
- const logger = pino();
32
- // trails is your application's array of Trail definitions.
33
- const graph = topo('app', trails, {
34
- observe: {
35
- log: createPinoSink(logger),
36
- },
14
+ sink.write({
15
+ category: 'app.http',
16
+ level: 'info',
17
+ message: 'request received',
18
+ metadata: { requestId: 'req_123' },
19
+ timestamp: new Date(),
37
20
  });
38
- ```
39
-
40
- ## Structural Logger Shape
41
-
42
- `PinoLoggerLike` requires `trace`, `debug`, `info`, `warn`, `error`, and `fatal` methods that accept `(payload, message)`. The sink forwards:
43
-
44
- - `record.message` as the Pino message argument.
45
- - `record.category`, `record.timestamp`, and `record.metadata` in the payload.
46
- - `silent` records as no-ops.
47
21
 
48
- If a required method is missing at runtime, the sink throws instead of silently dropping the record.
22
+ await sink.flush();
23
+ ```
49
24
 
50
- ## Publishing
25
+ Pass `pinoOptions` and an optional Pino destination when the adapter should construct the logger. For an asynchronously buffered destination, await `sink.flush()` before shutdown so accepted records reach Pino's destination. Trails records arrive after Trails-owned redaction, retain their category and timestamp as structured fields, and map `trace` through `fatal` directly to Pino levels. `silent` records do not reach Pino.
51
26
 
52
- `@ontrails/pino` participates in the standard Trails package publish checks:
27
+ ## Installation
53
28
 
54
29
  ```bash
55
- bun run publish:check
56
- bun run publish:registry-check
30
+ bun add @ontrails/observability@beta @ontrails/pino@beta
57
31
  ```
58
32
 
59
- `publish:registry-check` is read-only. Before the first registry publication it may report `@ontrails/pino` as a first-time package candidate. Actual package publication still goes through the repo script:
60
-
61
- ```bash
62
- bun run publish:packages
63
- ```
33
+ ## Migration
64
34
 
65
- Do not publish this package with `npm publish` or `changeset publish`.
35
+ This package is the final Pino adapter in the pre-v1 hard cut. No compatibility subpath remains; see the logging migration guide for the explicit historical import map.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ontrails/pino",
3
- "version": "1.0.0-beta.39",
3
+ "version": "1.0.0-beta.43",
4
4
  "files": [
5
5
  "src/**/*.ts",
6
6
  "!src/**/__tests__/**",
@@ -21,7 +21,16 @@
21
21
  "lint": "oxlint ./src",
22
22
  "clean": "rm -rf dist *.tsbuildinfo"
23
23
  },
24
+ "dependencies": {
25
+ "pino": "^10.3.1"
26
+ },
24
27
  "peerDependencies": {
25
- "@ontrails/observe": "^1.0.0-beta.39"
28
+ "@ontrails/observability": "^1.0.0-beta.43",
29
+ "zod": "^4.3.5"
30
+ },
31
+ "trails": {
32
+ "adapter": {
33
+ "target": "observability"
34
+ }
26
35
  }
27
36
  }
package/src/index.ts CHANGED
@@ -1,35 +1,24 @@
1
- import type { LogLevel, LogRecord, LogSink } from '@ontrails/observe';
1
+ import pino from 'pino';
2
+ import type { DestinationStream, Logger, LoggerOptions } from 'pino';
2
3
 
3
- /**
4
- * Package identifier for the publishable Pino adapter package.
5
- */
6
- export const pinoPackageName = '@ontrails/pino';
7
-
8
- /**
9
- * Signature for a Pino-compatible logger method used when forwarding Trails records.
10
- */
11
- export type PinoLogMethod = (
12
- payload: Record<string, unknown>,
13
- message?: string
14
- ) => void;
15
-
16
- /**
17
- * Structural subset of a Pino logger.
18
- */
19
- export interface PinoLoggerLike {
20
- debug: PinoLogMethod;
21
- error: PinoLogMethod;
22
- fatal: PinoLogMethod;
23
- info: PinoLogMethod;
24
- trace: PinoLogMethod;
25
- warn: PinoLogMethod;
26
- }
4
+ import type { LogLevel, LogRecord, LogSink } from '@ontrails/observability';
27
5
 
28
6
  export interface PinoSinkOptions {
7
+ /** Destination used only when this adapter constructs the Pino logger itself. */
8
+ readonly destination?: DestinationStream | undefined;
9
+ /** Existing configured Pino logger to receive Trails records. */
10
+ readonly logger?: Logger | undefined;
11
+ /** Options used only when this adapter constructs the Pino logger itself. */
12
+ readonly pinoOptions?: LoggerOptions | undefined;
29
13
  /** Sink name exposed to Trails observe configuration. Defaults to `pino`. */
30
14
  readonly name?: string | undefined;
31
15
  }
32
16
 
17
+ export interface PinoLogSink extends LogSink {
18
+ /** Flush an asynchronously buffered Pino destination, when one is present. */
19
+ flush(): Promise<void>;
20
+ }
21
+
33
22
  type ForwardMethod = Exclude<LogLevel, 'silent'>;
34
23
 
35
24
  const LEVEL_MAP: Record<LogLevel, ForwardMethod | undefined> = {
@@ -48,46 +37,46 @@ const buildPayload = (record: LogRecord): Record<string, unknown> => ({
48
37
  timestamp: record.timestamp.toISOString(),
49
38
  });
50
39
 
51
- const resolveLoggerMethod = (
52
- logger: PinoLoggerLike,
53
- method: ForwardMethod
54
- ): PinoLogMethod => {
55
- const loggerMethod = logger[method];
56
- if (typeof loggerMethod !== 'function') {
57
- throw new TypeError(`Pino logger is missing "${method}" method`);
40
+ /* oxlint-disable eslint-plugin-promise/avoid-new, eslint-plugin-promise/prefer-await-to-callbacks -- Pino exposes callback-only flush completion; the Trails sink contract is promise-based. */
41
+ const flush = (logger: Logger): Promise<void> =>
42
+ new Promise((resolve, reject) => {
43
+ logger.flush((error) => {
44
+ if (error === undefined) {
45
+ resolve();
46
+ return;
47
+ }
48
+ reject(error);
49
+ });
50
+ });
51
+ /* oxlint-enable eslint-plugin-promise/avoid-new, eslint-plugin-promise/prefer-await-to-callbacks */
52
+
53
+ const resolveLogger = (options: PinoSinkOptions): Logger => {
54
+ if (options.logger !== undefined) {
55
+ return options.logger;
58
56
  }
59
- return loggerMethod.bind(logger);
57
+ if (options.destination !== undefined) {
58
+ return pino(options.pinoOptions ?? {}, options.destination);
59
+ }
60
+ return options.pinoOptions === undefined ? pino() : pino(options.pinoOptions);
60
61
  };
61
62
 
62
- const resolveLoggerMethods = (
63
- logger: PinoLoggerLike
64
- ): Record<ForwardMethod, PinoLogMethod> => ({
65
- debug: resolveLoggerMethod(logger, 'debug'),
66
- error: resolveLoggerMethod(logger, 'error'),
67
- fatal: resolveLoggerMethod(logger, 'fatal'),
68
- info: resolveLoggerMethod(logger, 'info'),
69
- trace: resolveLoggerMethod(logger, 'trace'),
70
- warn: resolveLoggerMethod(logger, 'warn'),
71
- });
72
-
73
63
  /**
74
- * Create a Trails log sink that forwards records to a structural Pino logger.
64
+ * Create a Trails sink backed by a real Pino logger. If no logger is supplied,
65
+ * the adapter constructs one from `pinoOptions`; applications remain free to
66
+ * own destinations, transports, and richer Pino configuration directly.
75
67
  */
76
- export const createPinoSink = (
77
- logger: PinoLoggerLike,
78
- options: PinoSinkOptions = {}
79
- ): LogSink => {
80
- const methods = resolveLoggerMethods(logger);
68
+ export const createPinoSink = (options: PinoSinkOptions = {}): PinoLogSink => {
69
+ const logger = resolveLogger(options);
81
70
 
82
71
  return {
72
+ flush: async (): Promise<void> => await flush(logger),
83
73
  name: options.name ?? 'pino',
84
74
  write(record: LogRecord): void {
85
75
  const method = LEVEL_MAP[record.level];
86
76
  if (method === undefined) {
87
77
  return;
88
78
  }
89
-
90
- methods[method](buildPayload(record), record.message);
79
+ logger[method](buildPayload(record), record.message);
91
80
  },
92
81
  };
93
82
  };