pino-seq 3.0.0 → 4.0.0

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
@@ -2,21 +2,69 @@
2
2
 
3
3
  A stream to send [Pino](https://github.com/pinojs/pino) events to [Seq](https://datalust.co/seq). Tested with Node.js versions 18.x and up.
4
4
 
5
+ **Now written in TypeScript** with automatic type definitions and full ES Module support!
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install pino-seq
11
+ ```
12
+
13
+ ## Usage
14
+
5
15
  Use the `createStream()` method to create a Pino stream configuration, passing `serverUrl`, `apiKey` and batching parameters.
6
16
 
7
- ```js
17
+ This example works in both JavaScript and TypeScript projects:
18
+
19
+ ```javascript
8
20
  import pino from 'pino';
9
- import pinoToSeq from 'pino-seq';
21
+ import { createStream } from 'pino-seq';
10
22
 
11
- let stream = pinoToSeq.createStream({ serverUrl: 'http://localhost:5341' });
12
- let logger = pino({ name: 'pino-seq example' }, stream);
23
+ // Create a stream to Seq
24
+ const stream = createStream({
25
+ serverUrl: 'http://localhost:5341',
26
+ apiKey: 'your-api-key' // optional
27
+ });
13
28
 
29
+ // Create a Pino logger
30
+ const logger = pino({ name: 'pino-seq example' }, stream);
31
+
32
+ // Log some messages
14
33
  logger.info('Hello Seq, from Pino');
15
34
 
16
- let frLogger = logger.child({ lang: 'fr' });
35
+ // Child loggers work too
36
+ const frLogger = logger.child({ lang: 'fr' });
17
37
  frLogger.warn('au reviour');
38
+
39
+ // Flush logs before exit
40
+ await stream.flush();
18
41
  ```
19
42
 
20
- ### Acknowledgements
43
+ For TypeScript projects with explicit typing:
44
+
45
+ ```typescript
46
+ import { createStream, PinoSeqStreamConfig } from 'pino-seq';
47
+
48
+ const config: PinoSeqStreamConfig = {
49
+ serverUrl: 'http://localhost:5341',
50
+ // ... see Configuration section below for all options
51
+ };
52
+ const stream = createStream(config);
53
+ ```
54
+
55
+ ## Configuration
56
+
57
+ The `createStream()` function accepts a configuration object with the following properties:
58
+
59
+ - `serverUrl` (string): The URL of your Seq server
60
+ - `apiKey` (string, optional): API key for authentication
61
+ - `logOtherAs` (string, optional): Log level for unstructured messages ('Verbose', 'Debug', 'Information', 'Warning', 'Error', 'Fatal')
62
+ - `additionalProperties` (object, optional): Additional properties to add to all log events
63
+ - `maxBatchingTime` (number, optional): Maximum time in milliseconds to wait before sending a batch
64
+ - `eventSizeLimit` (number, optional): Maximum size of a single event
65
+ - `batchSizeLimit` (number, optional): Maximum size of a batch
66
+ - `onError` (function, optional): Error handler callback
67
+
68
+ ## Acknowledgements
21
69
 
22
70
  Originally by Simi Hartstein and published as `simihartstein/pino-seq`; maintainership transferred to Datalust at version 0.5.
@@ -0,0 +1,7 @@
1
+ import { PinoSeqStream, PinoSeqStreamConfig } from './pinoSeqStream.js';
2
+ export { PinoSeqStream, PinoSeqStreamConfig };
3
+ export declare function createStream(config?: PinoSeqStreamConfig): PinoSeqStream;
4
+ declare const _default: {
5
+ createStream: typeof createStream;
6
+ };
7
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ import { PinoSeqStream } from './pinoSeqStream.js';
2
+ export { PinoSeqStream };
3
+ export function createStream(config) {
4
+ return new PinoSeqStream(config);
5
+ }
6
+ // Default export for backward compatibility
7
+ export default {
8
+ createStream
9
+ };
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAuB,MAAM,oBAAoB,CAAC;AAExE,OAAO,EAAE,aAAa,EAAuB,CAAC;AAE9C,MAAM,UAAU,YAAY,CAAC,MAA4B;IACvD,OAAO,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;AACnC,CAAC;AAED,4CAA4C;AAC5C,eAAe;IACb,YAAY;CACb,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { Writable } from 'stream';
2
+ import { SeqLoggerConfig } from 'seq-logging';
3
+ export interface PinoSeqStreamConfig extends Partial<SeqLoggerConfig> {
4
+ additionalProperties?: Record<string, any>;
5
+ logOtherAs?: 'Verbose' | 'Debug' | 'Information' | 'Warning' | 'Error' | 'Fatal';
6
+ _testLogger?: any;
7
+ }
8
+ export declare class PinoSeqStream extends Writable {
9
+ private _additionalProperties?;
10
+ private _logOtherAs?;
11
+ private _bufferTime;
12
+ private _buffer;
13
+ private _logger;
14
+ private _flushTimer?;
15
+ constructor(config?: PinoSeqStreamConfig);
16
+ _write(message: Buffer | string, enc: string, cb: (error?: Error | null) => void): void;
17
+ private handleUnstructuredMessage;
18
+ private flushBuffer;
19
+ flush(): Promise<boolean>;
20
+ _final(callback: (error?: Error | null) => void): void;
21
+ }
@@ -0,0 +1,125 @@
1
+ import { Writable } from 'stream';
2
+ import { Logger as SeqLogger } from 'seq-logging';
3
+ const LEVEL_NAMES = {
4
+ 10: 'Verbose',
5
+ 20: 'Debug',
6
+ 30: 'Information',
7
+ 40: 'Warning',
8
+ 50: 'Error',
9
+ 60: 'Fatal'
10
+ };
11
+ export class PinoSeqStream extends Writable {
12
+ constructor(config) {
13
+ super();
14
+ const { additionalProperties, logOtherAs, _testLogger, ...loggerConfig } = config || {};
15
+ this._additionalProperties = additionalProperties;
16
+ this._logOtherAs = logOtherAs;
17
+ this._bufferTime = false;
18
+ this._buffer = [];
19
+ // Allow injecting a mock logger for testing
20
+ if (_testLogger) {
21
+ this._logger = _testLogger;
22
+ }
23
+ else {
24
+ const onError = loggerConfig.onError || ((e) => {
25
+ console.error('[PinoSeqStream]', e);
26
+ });
27
+ const configWithDefaults = {
28
+ ...loggerConfig,
29
+ onError
30
+ };
31
+ this._logger = new SeqLogger(configWithDefaults);
32
+ }
33
+ }
34
+ _write(message, enc, cb) {
35
+ if (message) {
36
+ try {
37
+ const eventCopy = JSON.parse(message.toString());
38
+ const { time, level, msg, err, error, stack, ...props } = eventCopy;
39
+ // Get the properties from the error
40
+ const errorObj = err || error;
41
+ const errMessage = errorObj?.message;
42
+ const errStack = errorObj?.stack;
43
+ const { message: _msg, stack: _stack, ...errorProps } = errorObj || {};
44
+ const forSeq = {
45
+ timestamp: new Date(time),
46
+ level: LEVEL_NAMES[level],
47
+ traceId: props.trace_id,
48
+ spanId: props.span_id,
49
+ messageTemplate: msg || errMessage,
50
+ properties: {
51
+ ...this._additionalProperties,
52
+ ...errorProps,
53
+ ...props
54
+ },
55
+ exception: stack || errStack
56
+ };
57
+ // Handle sending to seq separately
58
+ try {
59
+ // If we get a new correctly formatted message, flush the buffer
60
+ if (this._logOtherAs) {
61
+ this.flushBuffer();
62
+ }
63
+ this._logger.emit(forSeq);
64
+ }
65
+ catch (err) {
66
+ console.error(err);
67
+ }
68
+ }
69
+ catch (err) {
70
+ const msg = String(message);
71
+ console.error(msg);
72
+ if (this._logOtherAs) {
73
+ this.handleUnstructuredMessage(msg);
74
+ }
75
+ }
76
+ }
77
+ cb();
78
+ }
79
+ handleUnstructuredMessage(message) {
80
+ this._bufferTime = this._bufferTime || new Date();
81
+ this._buffer.push(message);
82
+ // Flush the message buffer after 1 sec of inactivity
83
+ if (!this._flushTimer) {
84
+ this._flushTimer = setTimeout(() => {
85
+ this.flushBuffer();
86
+ }, 1000);
87
+ }
88
+ }
89
+ flushBuffer() {
90
+ if (this._buffer.length) {
91
+ try {
92
+ // No need to flush again
93
+ if (this._flushTimer) {
94
+ clearTimeout(this._flushTimer);
95
+ this._flushTimer = undefined;
96
+ }
97
+ this._logger.emit({
98
+ timestamp: this._bufferTime || new Date(),
99
+ level: this._logOtherAs,
100
+ messageTemplate: this._buffer.join('\n'),
101
+ properties: { ...this._additionalProperties },
102
+ });
103
+ this._bufferTime = false;
104
+ this._buffer = [];
105
+ }
106
+ catch (err) {
107
+ console.error(err);
108
+ }
109
+ }
110
+ }
111
+ flush() {
112
+ this.flushBuffer();
113
+ return this._logger.flush();
114
+ }
115
+ // Force the underlying logger to flush at the time of the call
116
+ // and wait for pending writes to complete
117
+ _final(callback) {
118
+ this.flushBuffer();
119
+ this._logger
120
+ .close()
121
+ .then(() => callback())
122
+ .catch((err) => callback(err));
123
+ }
124
+ }
125
+ //# sourceMappingURL=pinoSeqStream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pinoSeqStream.js","sourceRoot":"","sources":["../src/pinoSeqStream.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,14 +1,27 @@
1
1
  {
2
2
  "name": "pino-seq",
3
- "version": "3.0.0",
3
+ "version": "4.0.0",
4
4
  "description": "A stream that sends Pino log events to Seq",
5
- "main": "index.js",
6
- "types": "index.d.ts",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
7
  "type": "module",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ }
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
8
19
  "scripts": {
9
- "test": "mocha",
10
- "start": "node ./example/example.js",
11
- "start:ts": "tsx ./example/example.ts"
20
+ "build": "tsc",
21
+ "prepublishOnly": "npm run build",
22
+ "test": "npm run build && mocha --ignore test/integration*.js",
23
+ "test:integration": "npm run build && mocha --include test/integration*.js --timeout 10000",
24
+ "dev": "tsc --watch"
12
25
  },
13
26
  "repository": {
14
27
  "type": "git",
@@ -25,7 +38,9 @@
25
38
  },
26
39
  "homepage": "https://github.com/datalust/pino-seq#readme",
27
40
  "devDependencies": {
41
+ "@types/node": "^25.0.6",
28
42
  "mocha": "^11.7.4",
43
+ "pino": "^10.1.1",
29
44
  "tsx": "^4.20.6",
30
45
  "typescript": "^5.9.3"
31
46
  },
@@ -1,30 +0,0 @@
1
- # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2
- # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3
-
4
- name: Test
5
-
6
- on:
7
- push:
8
- branches: [ dev ]
9
- pull_request:
10
- branches: [ dev ]
11
-
12
- jobs:
13
- build:
14
-
15
- runs-on: ubuntu-latest
16
-
17
- strategy:
18
- matrix:
19
- node-version: [18.x, 20.x, 22.x]
20
- os: [ubuntu-latest, windows-latest, macOS-latest]
21
-
22
- steps:
23
- - uses: actions/checkout@v2
24
- - name: Use Node.js ${{ matrix.node-version }}
25
- uses: actions/setup-node@v1
26
- with:
27
- node-version: ${{ matrix.node-version }}
28
- - run: npm ci
29
- - run: npm run build --if-present
30
- - run: npm test
@@ -1,34 +0,0 @@
1
- # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2
- # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
3
-
4
- name: Publish
5
-
6
- on:
7
- push:
8
- branches:
9
- - main
10
-
11
- jobs:
12
- build:
13
- runs-on: ubuntu-latest
14
- steps:
15
- - uses: actions/checkout@v2
16
- - uses: actions/setup-node@v1
17
- with:
18
- node-version: 20
19
- - run: npm ci
20
- - run: npm test
21
-
22
- publish-npm:
23
- needs: build
24
- runs-on: ubuntu-latest
25
- steps:
26
- - uses: actions/checkout@v2
27
- - uses: actions/setup-node@v1
28
- with:
29
- node-version: 20
30
- registry-url: https://registry.npmjs.org/
31
- - run: npm ci
32
- - run: npm publish
33
- env:
34
- NODE_AUTH_TOKEN: ${{secrets.npm_token}}
package/.prettierrc DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "tabWidth": 2,
3
- "singleQuote": true,
4
- "useTabs": false,
5
- "trailingComma": "none",
6
- "printWidth": 160
7
- }
@@ -1,62 +0,0 @@
1
- {
2
- "version": "0.2.0",
3
- "configurations": [
4
- {
5
- "name": "Current TS File",
6
- "type": "node",
7
- "request": "launch",
8
- "args": [
9
- "${relativeFile}"
10
- ],
11
- "runtimeArgs": [
12
- "--nolazy",
13
- "-r",
14
- "ts-node/register"
15
- ],
16
- "sourceMaps": true,
17
- "cwd": "${workspaceRoot}",
18
- "protocol": "inspector",
19
- },
20
- {
21
- "name": "Launch",
22
- "type": "node",
23
- "request": "launch",
24
- "program": "${workspaceRoot}/example/example.js",
25
- "stopOnEntry": false,
26
- "args": [],
27
- "cwd": "${workspaceRoot}",
28
- "preLaunchTask": null,
29
- "runtimeExecutable": null,
30
- "runtimeArgs": [
31
- "--nolazy"
32
- ],
33
- "env": {
34
- "NODE_ENV": "development"
35
- },
36
- "console": "internalConsole",
37
- "sourceMaps": false,
38
- "outDir": null
39
- },
40
- {
41
- "name": "Attach",
42
- "type": "node",
43
- "request": "attach",
44
- "port": 5858,
45
- "address": "localhost",
46
- "restart": false,
47
- "sourceMaps": false,
48
- "outDir": null,
49
- "localRoot": "${workspaceRoot}",
50
- "remoteRoot": null
51
- },
52
- {
53
- "name": "Attach to Process",
54
- "type": "node",
55
- "request": "attach",
56
- "processId": "${command.PickProcess}",
57
- "port": 5858,
58
- "sourceMaps": false,
59
- "outDir": null
60
- }
61
- ]
62
- }
@@ -1,12 +0,0 @@
1
- "use strict";
2
-
3
- import pino from 'pino';
4
- import pinoToSeq from '../index.js';
5
-
6
- let stream = pinoToSeq.createStream({serverUrl: "http://localhost:5341"});
7
- let logger = pino({name: "pino-seq example"}, stream);
8
-
9
- logger.info("Hello Seq, from Pino");
10
-
11
- let frLogger = logger.child({lang: "fr"});
12
- frLogger.warn("au reviour");
@@ -1,16 +0,0 @@
1
- import Pino from "pino"
2
- import PinoSeq from ".."
3
-
4
- const stream = PinoSeq.createStream({serverUrl: "http://localhost:5341"});
5
-
6
- const options: Pino.LoggerOptions = {
7
- name: "pino-seq example"
8
- }
9
- const logger: Pino.Logger = Pino(options, stream);
10
-
11
- logger.info("Hello Seq, from Pino");
12
-
13
- const frLogger = logger.child({lang: "fr"});
14
- frLogger.warn("au reviour");
15
-
16
- stream.flush().then((_) => console.log('flushed'));
package/index.d.ts DELETED
@@ -1,19 +0,0 @@
1
- import { Writable } from 'stream';
2
-
3
- declare namespace PinoSeq {
4
- interface SeqConfig {
5
- serverUrl?: string;
6
- apiKey?: string;
7
- logOtherAs?: 'Verbose' | 'Debug' | 'Information' | 'Warning' | 'Error' | 'Fatal';
8
- maxBatchingTime?: number;
9
- eventSizeLimit?: number;
10
- batchSizeLimit?: number;
11
- onError?: (e: Error) => void;
12
- }
13
-
14
- function createStream(config: PinoSeq.SeqConfig): Writable & {
15
- flush: () => Promise<boolean>;
16
- };
17
- }
18
-
19
- export = PinoSeq;
package/index.js DELETED
@@ -1,10 +0,0 @@
1
- "use strict";
2
-
3
- import { PinoSeqStream } from './pinoSeqStream.js';
4
-
5
- export default {
6
- createStream: config => {
7
- config = config || {};
8
- return new PinoSeqStream(config);
9
- }
10
- };
package/pinoSeqStream.js DELETED
@@ -1,117 +0,0 @@
1
- "use strict";
2
-
3
- import stream from 'stream';
4
- import { Logger as SeqLogger } from 'seq-logging';
5
-
6
- let LEVEL_NAMES = {
7
- 10: 'Verbose',
8
- 20: 'Debug',
9
- 30: 'Information',
10
- 40: 'Warning',
11
- 50: 'Error',
12
- 60: 'Fatal'
13
- };
14
-
15
- class PinoSeqStream extends stream.Writable {
16
- constructor(config) {
17
- super();
18
-
19
- let { additionalProperties, logOtherAs, ...loggerConfig } = config == null ? {} : { ...config };
20
- loggerConfig.onError = loggerConfig.onError || function (e) { console.error('[PinoSeqStream] Log batch failed\n', e) };
21
- this._additionalProperties = additionalProperties;
22
- this._logOtherAs = logOtherAs;
23
- this._bufferTime = false;
24
- this._buffer = [];
25
- this._logger = new SeqLogger(loggerConfig);
26
- }
27
-
28
- _write(message, enc, cb) {
29
- if (message) {
30
- try {
31
- let eventCopy = JSON.parse(message);
32
-
33
- let { time, level, msg, err, error, stack, ...props } = eventCopy;
34
-
35
- // Get the properties from the error
36
- let { message: errMessage, stack: errStack, ...errorProps } = err || error || {};
37
-
38
- let forSeq = {
39
- timestamp: new Date(time),
40
- level: LEVEL_NAMES[level],
41
- traceId: props.trace_id,
42
- spanId: props.span_id,
43
- messageTemplate: msg ? msg : errMessage,
44
- properties: { ...this._additionalProperties, ...errorProps, ...props },
45
- exception: stack ? stack : errStack
46
- };
47
-
48
- // Handle sending to sql separatly
49
- try {
50
- // If we get a new correctly formatted message, flush the buffer
51
- if (this._logOtherAs) {
52
- this.flushBuffer();
53
- }
54
- this._logger.emit(forSeq);
55
- } catch (err) {
56
- console.error(err);
57
- }
58
- } catch (err) {
59
- const msg = String(message);
60
- console.error(msg);
61
- if (this._logOtherAs) {
62
- this.handleUnstructuredMessage(msg);
63
- }
64
- }
65
- }
66
- cb();
67
- }
68
-
69
- handleUnstructuredMessage(message) {
70
- this._bufferTime = this._bufferTime ? this._bufferTime : new Date();
71
- this._buffer.push(message);
72
- // Flush the message buffer after 1 sec of inacticity
73
- if (!this._flushTimer) {
74
- this._flushTimer = setTimeout(() => {
75
- this.flushBuffer();
76
- }, 1000);
77
- }
78
- }
79
-
80
- flushBuffer() {
81
- if (this._buffer.length) {
82
- try {
83
- // No need to flush again
84
- if (this._flushTimer) {
85
- clearTimeout(this._flushTimer);
86
- }
87
- this._logger.emit({
88
- timestamp: this._bufferTime,
89
- level: this._logOtherAs,
90
- messageTemplate: this._buffer.join('\n'),
91
- properties: { ...this._additionalProperties },
92
- });
93
- this._bufferTime = false;
94
- this._buffer = [];
95
- } catch (err) {
96
- console.error(err);
97
- }
98
- }
99
- }
100
-
101
- flush() {
102
- this.flushBuffer();
103
- return this._logger.flush();
104
- }
105
-
106
- // Force the underlying logger to flush at the time of the call
107
- // and wait for pending writes to complete
108
- _final(callback) {
109
- this.flushBuffer();
110
- this._logger
111
- .close()
112
- .then(() => callback())
113
- .catch((err) => callback(err));
114
- }
115
- }
116
-
117
- export { PinoSeqStream };
@@ -1,11 +0,0 @@
1
- "use strict";
2
-
3
- import { PinoSeqStream } from '../pinoSeqStream.js';
4
-
5
- describe('PinoSeqStream', () => {
6
- describe('constructor', () => {
7
- it('can be constructed', () => {
8
- new PinoSeqStream();
9
- });
10
- });
11
- });