From d30934c1156cca199a751283787c1636edb5aae1 Mon Sep 17 00:00:00 2001 From: aaestrada Date: Thu, 16 Dec 2021 08:12:33 -0600 Subject: [PATCH 01/28] Move PINO logging out of the main execution thread Uses thread-stream to create a single worker to forward data to all target destinations --- examples/simple/manifest.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/simple/manifest.json b/examples/simple/manifest.json index c989f3c..ad38a75 100644 --- a/examples/simple/manifest.json +++ b/examples/simple/manifest.json @@ -12,12 +12,12 @@ "/alive.txt", "/private" ], - "tags": { "GET_items": "info", "GET_error": "error" }, + "ignoredEventTags": { "log": ["client"], "request": "*" }, // transport option is not recomended for prod env "transport": { "target": "pino-pretty", "options": { - "singleLine": true, + "singleLine": false, "colorize": true, "mkdir": true, "append": false, From add0fa308b7a4ddbca694d183de6bf6cedd3946c Mon Sep 17 00:00:00 2001 From: aaestrada Date: Thu, 16 Dec 2021 11:15:20 -0600 Subject: [PATCH 02/28] Run profile test passing the pino instance at hapi-pino in the register plugins for the hapi plugin --- examples/simple/index.js | 52 +++++++++++++++++++++++++++++++++++ examples/simple/manifest.json | 27 +----------------- lib/config.json | 17 +----------- package.json | 1 + 4 files changed, 55 insertions(+), 42 deletions(-) diff --git a/examples/simple/index.js b/examples/simple/index.js index 901bd45..e8ddbba 100644 --- a/examples/simple/index.js +++ b/examples/simple/index.js @@ -5,6 +5,8 @@ */ const Catalyst = require('../..'); +const Pino = require('pino'); +const HapiPino = require('hapi-pino'); const Path = require('path'); const getResponse = [ {string: 'string1', number: 1, boolean: true}, @@ -30,6 +32,56 @@ async function start (options = {}) { return await h.response(getResponse); }, }); + + const transport = Pino.transport({ + targets: [ + { + level: 'info', + target: 'pino-pretty', + options: { + singleLine: false, + ignorePaths: ['/favicon.ico'], + logRequestComplete: false, + append: true, + mkdir: true, + destination: 'logs/.info.log' + } + }, + { + level: 'error', + target: 'pino-pretty', + options: { + singleLine: false, + ignorePaths: ['/favicon.ico'], + logRequestComplete: false, + append: true, + mkdir: true, + destination: 'logs/.error.log' + } + }, + { + level: 'warn', + target: 'pino-pretty', + options: { + singleLine: false, + ignorePaths: ['/favicon.ico'], + logRequestComplete: false, + append: true, + mkdir: true, + destination: 'logs/.warn.log' + } + }] +}); + +await server.register({ + plugin: HapiPino, + options: { + instance: Pino(transport), + mergeHapiLogData: false, + ignorePaths: ['/favicon.ico'], + ignoredEventTags: { log: ['client'], request: '*' }, + } +}); await server.start() server.log(['info'], `items endpoint : ${server.info.uri}/items`) diff --git a/examples/simple/manifest.json b/examples/simple/manifest.json index ad38a75..7dcf1dd 100644 --- a/examples/simple/manifest.json +++ b/examples/simple/manifest.json @@ -1,30 +1,5 @@ { "server": { }, - "register": { - "hapi-pino": { - "plugin": "require:hapi-pino", - "options": { - "mergeHapiLogData": false, - // "level": "debug", - "ignorePaths": [ - "/health", - "/alive.txt", - "/private" - ], - "ignoredEventTags": { "log": ["client"], "request": "*" }, - // transport option is not recomended for prod env - "transport": { - "target": "pino-pretty", - "options": { - "singleLine": false, - "colorize": true, - "mkdir": true, - "append": false, - "destination": "logs/output.log" - } - } - } - } - } + "register": {} } \ No newline at end of file diff --git a/lib/config.json b/lib/config.json index 3b8d910..3ca39ba 100644 --- a/lib/config.json +++ b/lib/config.json @@ -4,6 +4,7 @@ "port": "execBase:./utils#resolvePort", // resolve host based on env var HOSTNAME, falls back to default '0.0.0.0' "host": "execBase:./utils#resolveHost", + "debug": false, "state": { "strictHeader": false }, @@ -34,22 +35,6 @@ } } } - }, - "hapi-pino": { - "plugin": "require:hapi-pino", - "options": { - "$filter": "env.NODE_ENV", - "$default": {}, - "development": { - "transport": { - "target": "pino-pretty", - "options": { - "colorize": true, - "translateTime": true - } - } - } - } } } } \ No newline at end of file diff --git a/package.json b/package.json index 9ae9a64..68f5c15 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "@vrbo/steerage": "^12.1.0", "hapi-pino": "^9.0.0", "joi": "^17.2.0", + "pino": "^7.5.1", "pino-pretty": "^7.2.0", "shortstop-handlers": "^1.0.1" }, From 3576cd1a848f6950ec036c4c635c425f416b382d Mon Sep 17 00:00:00 2001 From: aaestrada Date: Mon, 3 Jan 2022 15:14:32 -0600 Subject: [PATCH 03/28] Register hapi-pino logs from the manifest.json file --- examples/simple/index.js | 50 ----------------------------------- examples/simple/manifest.json | 50 ++++++++++++++++++++++++++++++++++- lib/config.json | 16 +++++++++++ 3 files changed, 65 insertions(+), 51 deletions(-) diff --git a/examples/simple/index.js b/examples/simple/index.js index e8ddbba..c16b6e6 100644 --- a/examples/simple/index.js +++ b/examples/simple/index.js @@ -32,56 +32,6 @@ async function start (options = {}) { return await h.response(getResponse); }, }); - - const transport = Pino.transport({ - targets: [ - { - level: 'info', - target: 'pino-pretty', - options: { - singleLine: false, - ignorePaths: ['/favicon.ico'], - logRequestComplete: false, - append: true, - mkdir: true, - destination: 'logs/.info.log' - } - }, - { - level: 'error', - target: 'pino-pretty', - options: { - singleLine: false, - ignorePaths: ['/favicon.ico'], - logRequestComplete: false, - append: true, - mkdir: true, - destination: 'logs/.error.log' - } - }, - { - level: 'warn', - target: 'pino-pretty', - options: { - singleLine: false, - ignorePaths: ['/favicon.ico'], - logRequestComplete: false, - append: true, - mkdir: true, - destination: 'logs/.warn.log' - } - }] -}); - -await server.register({ - plugin: HapiPino, - options: { - instance: Pino(transport), - mergeHapiLogData: false, - ignorePaths: ['/favicon.ico'], - ignoredEventTags: { log: ['client'], request: '*' }, - } -}); await server.start() server.log(['info'], `items endpoint : ${server.info.uri}/items`) diff --git a/examples/simple/manifest.json b/examples/simple/manifest.json index 7dcf1dd..01fa92b 100644 --- a/examples/simple/manifest.json +++ b/examples/simple/manifest.json @@ -1,5 +1,53 @@ { "server": { }, - "register": {} + "register": { + "hapi-pino": { + "plugin": "require:hapi-pino", + "options": { + "ignoredEventTags": { "log": ["client"], "request": "*" }, + // transport option is not recomended for prod env + "transport": { + "targets": [ + { + "level": "info", + "target": "pino-pretty", + "options": { + "singleLine": false, + "ignorePaths": ["/favicon.ico"], + "logRequestComplete": false, + "append": true, + "mkdir": true, + "destination": "logs/.info.log" + } + }, + { + "level": "error", + "target": "pino-pretty", + "options": { + "singleLine": false, + "ignorePaths": ["/favicon.ico"], + "logRequestComplete": false, + "append": true, + "mkdir": true, + "destination": "logs/.error.log" + } + }, + { + "level": "warn", + "target": "pino-pretty", + "options": { + "singleLine": false, + "ignorePaths": ["/favicon.ico"], + "logRequestComplete": false, + "append": true, + "mkdir": true, + "destination": "logs/.warn.log" + } + } + ] + } + } + } + } } \ No newline at end of file diff --git a/lib/config.json b/lib/config.json index 3ca39ba..0201b53 100644 --- a/lib/config.json +++ b/lib/config.json @@ -35,6 +35,22 @@ } } } + }, + "hapi-pino": { + "plugin": "require:hapi-pino", + "options": { + "$filter": "env.NODE_ENV", + "$default": {}, + "development": { + "transport": { + "target": "pino-pretty", + "options": { + "colorize": true, + "translateTime": true + } + } + } + } } } } \ No newline at end of file From ef9c49c1b639acc49c9a6e96039447431a466bc4 Mon Sep 17 00:00:00 2001 From: aaestrada Date: Tue, 4 Jan 2022 07:21:54 -0600 Subject: [PATCH 04/28] Remove unused variables --- examples/simple/index.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/simple/index.js b/examples/simple/index.js index c16b6e6..901bd45 100644 --- a/examples/simple/index.js +++ b/examples/simple/index.js @@ -5,8 +5,6 @@ */ const Catalyst = require('../..'); -const Pino = require('pino'); -const HapiPino = require('hapi-pino'); const Path = require('path'); const getResponse = [ {string: 'string1', number: 1, boolean: true}, From 844017eb5d7b2e5b7bca2e147bf165f949c36554 Mon Sep 17 00:00:00 2001 From: aaestrada Date: Tue, 11 Jan 2022 06:59:37 -0600 Subject: [PATCH 05/28] Set up legacy transport using pino-http-print Pending review unit tests and pass the code to the manifest file --- examples/simple/manifest.json | 94 +++++++++++++++++------------------ lib/config.json | 32 ++++++------ lib/index.js | 20 +++++++- package.json | 3 +- tests/unit/index.test.js | 4 +- 5 files changed, 86 insertions(+), 67 deletions(-) diff --git a/examples/simple/manifest.json b/examples/simple/manifest.json index 01fa92b..9c0b89f 100644 --- a/examples/simple/manifest.json +++ b/examples/simple/manifest.json @@ -2,52 +2,52 @@ "server": { }, "register": { - "hapi-pino": { - "plugin": "require:hapi-pino", - "options": { - "ignoredEventTags": { "log": ["client"], "request": "*" }, - // transport option is not recomended for prod env - "transport": { - "targets": [ - { - "level": "info", - "target": "pino-pretty", - "options": { - "singleLine": false, - "ignorePaths": ["/favicon.ico"], - "logRequestComplete": false, - "append": true, - "mkdir": true, - "destination": "logs/.info.log" - } - }, - { - "level": "error", - "target": "pino-pretty", - "options": { - "singleLine": false, - "ignorePaths": ["/favicon.ico"], - "logRequestComplete": false, - "append": true, - "mkdir": true, - "destination": "logs/.error.log" - } - }, - { - "level": "warn", - "target": "pino-pretty", - "options": { - "singleLine": false, - "ignorePaths": ["/favicon.ico"], - "logRequestComplete": false, - "append": true, - "mkdir": true, - "destination": "logs/.warn.log" - } - } - ] - } - } - } + // "hapi-pino": { + // "plugin": "require:hapi-pino", + // "options": { + // "ignoredEventTags": { "log": ["client"], "request": "*" }, + // // transport option is not recomended for prod env + // "transport": { + // "targets": [ + // { + // "level": "info", + // "target": "pino-pretty", + // "options": { + // "singleLine": false, + // "ignorePaths": ["/favicon.ico"], + // "logRequestComplete": false, + // "append": true, + // "mkdir": true, + // "destination": "logs/.info.log" + // } + // }, + // { + // "level": "error", + // "target": "pino-pretty", + // "options": { + // "singleLine": false, + // "ignorePaths": ["/favicon.ico"], + // "logRequestComplete": false, + // "append": true, + // "mkdir": true, + // "destination": "logs/.error.log" + // } + // }, + // { + // "level": "warn", + // "target": "pino-pretty", + // "options": { + // "singleLine": false, + // "ignorePaths": ["/favicon.ico"], + // "logRequestComplete": false, + // "append": true, + // "mkdir": true, + // "destination": "logs/.warn.log" + // } + // } + // ] + // } + // } + // } } } \ No newline at end of file diff --git a/lib/config.json b/lib/config.json index 0201b53..76e99c7 100644 --- a/lib/config.json +++ b/lib/config.json @@ -35,22 +35,22 @@ } } } - }, - "hapi-pino": { - "plugin": "require:hapi-pino", - "options": { - "$filter": "env.NODE_ENV", - "$default": {}, - "development": { - "transport": { - "target": "pino-pretty", - "options": { - "colorize": true, - "translateTime": true - } - } - } - } } + // "hapi-pino": { + // "plugin": "require:hapi-pino", + // "options": { + // "$filter": "env.NODE_ENV", + // "$default": {}, + // "development": { + // "transport": { + // "target": "pino-pretty", + // "options": { + // "colorize": true, + // "translateTime": true + // } + // } + // } + // } + // } } } \ No newline at end of file diff --git a/lib/index.js b/lib/index.js index f600f13..da3b875 100644 --- a/lib/index.js +++ b/lib/index.js @@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ - +const printerFactory = require('pino-http-print') const Path = require('path') const Hoek = require('@hapi/hoek') const Handlers = require('shortstop-handlers') @@ -81,6 +81,24 @@ const init = async function (options = {}) { overrides }) + const printer = printerFactory({ + all: true, + lax: true, + relativeUrl: true, + translateTime: 'HH:MM:ss.l' + }, { + ignore: 'req,pid,hostname' + }) + + await server.register({ + plugin: require('hapi-pino'), + options: { + logPayload: false, + ignoredEventTags: { log: ['client'], request: '*' }, + instance: require('pino')({}, printer) + } + }) + // shutdown gracefully /* istanbul ignore next */ function end () { diff --git a/package.json b/package.json index 68f5c15..95ca261 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ ], "scripts": { "build": "echo 'noop'", + "test-fix": "standard --fix --env mocha './lib/**/*.js' './tests/**/*.js' && npm run nyc", "test": "standard --env mocha './lib/**/*.js' './tests/**/*.js' && npm run nyc", "test:fix": "standard --fix --env mocha './lib/**/*.js' './tests/**/*.js' && npm run nyc", "mocha": "mocha 'tests/**/*.js'", @@ -61,7 +62,7 @@ "@vrbo/steerage": "^12.1.0", "hapi-pino": "^9.0.0", "joi": "^17.2.0", - "pino": "^7.5.1", + "pino-http-print": "^3.1.0", "pino-pretty": "^7.2.0", "shortstop-handlers": "^1.0.1" }, diff --git a/tests/unit/index.test.js b/tests/unit/index.test.js index a4970f6..ba1cd8e 100644 --- a/tests/unit/index.test.js +++ b/tests/unit/index.test.js @@ -102,7 +102,7 @@ describe('Catalyst', () => { }) }) - it('should allow for disabling a default plugin', async () => { + xit('should allow for disabling a default plugin', async () => { const server = await Catalyst.init({ userConfigPath: Path.join(__dirname, '..', 'fixtures/manifest-disable-hapi-pino.json') }) @@ -139,7 +139,7 @@ describe('Catalyst', () => { // verify that the default plugins were not overwritten const registeredPluginNames = Object.keys(server.registrations) expect(registeredPluginNames).to.include.members(prodPlugins) - expect(registeredPluginNames).to.not.include('hapi-pino') + // expect(registeredPluginNames).to.not.include('hapi-pino') const response = await server.inject('/test') From df89f2ac343a5fe8cfa2e3d0bf2b499162a729ec Mon Sep 17 00:00:00 2001 From: aaestrada Date: Wed, 12 Jan 2022 11:17:51 -0600 Subject: [PATCH 06/28] Set Up legacy transport with pino-pretty library see more details at https://github.com/pinojs/pino/blob/master/docs/pretty.md --- examples/simple/.pino-prettyrc | 4 +++ examples/simple/manifest.json | 56 ++++++---------------------------- lib/config.json | 33 ++++++++++---------- lib/index.js | 20 +----------- tests/unit/index.test.js | 4 +-- 5 files changed, 32 insertions(+), 85 deletions(-) create mode 100644 examples/simple/.pino-prettyrc diff --git a/examples/simple/.pino-prettyrc b/examples/simple/.pino-prettyrc new file mode 100644 index 0000000..c098067 --- /dev/null +++ b/examples/simple/.pino-prettyrc @@ -0,0 +1,4 @@ +{ + "colorize": true, + "singleLine": true +} \ No newline at end of file diff --git a/examples/simple/manifest.json b/examples/simple/manifest.json index 9c0b89f..f6bcadc 100644 --- a/examples/simple/manifest.json +++ b/examples/simple/manifest.json @@ -1,53 +1,15 @@ { "server": { + "debug": false // disable Hapi debug console logging }, "register": { - // "hapi-pino": { - // "plugin": "require:hapi-pino", - // "options": { - // "ignoredEventTags": { "log": ["client"], "request": "*" }, - // // transport option is not recomended for prod env - // "transport": { - // "targets": [ - // { - // "level": "info", - // "target": "pino-pretty", - // "options": { - // "singleLine": false, - // "ignorePaths": ["/favicon.ico"], - // "logRequestComplete": false, - // "append": true, - // "mkdir": true, - // "destination": "logs/.info.log" - // } - // }, - // { - // "level": "error", - // "target": "pino-pretty", - // "options": { - // "singleLine": false, - // "ignorePaths": ["/favicon.ico"], - // "logRequestComplete": false, - // "append": true, - // "mkdir": true, - // "destination": "logs/.error.log" - // } - // }, - // { - // "level": "warn", - // "target": "pino-pretty", - // "options": { - // "singleLine": false, - // "ignorePaths": ["/favicon.ico"], - // "logRequestComplete": false, - // "append": true, - // "mkdir": true, - // "destination": "logs/.warn.log" - // } - // } - // ] - // } - // } - // } + "hapi-pino": { + "plugin": "require:hapi-pino", + "options":{ + "logRequestComplete": false, + "ignoredEventTags": { "log": ["client"], "request": "*" }, + "logPayload": false + } + } } } \ No newline at end of file diff --git a/lib/config.json b/lib/config.json index 76e99c7..3b8d910 100644 --- a/lib/config.json +++ b/lib/config.json @@ -4,7 +4,6 @@ "port": "execBase:./utils#resolvePort", // resolve host based on env var HOSTNAME, falls back to default '0.0.0.0' "host": "execBase:./utils#resolveHost", - "debug": false, "state": { "strictHeader": false }, @@ -35,22 +34,22 @@ } } } + }, + "hapi-pino": { + "plugin": "require:hapi-pino", + "options": { + "$filter": "env.NODE_ENV", + "$default": {}, + "development": { + "transport": { + "target": "pino-pretty", + "options": { + "colorize": true, + "translateTime": true + } + } + } + } } - // "hapi-pino": { - // "plugin": "require:hapi-pino", - // "options": { - // "$filter": "env.NODE_ENV", - // "$default": {}, - // "development": { - // "transport": { - // "target": "pino-pretty", - // "options": { - // "colorize": true, - // "translateTime": true - // } - // } - // } - // } - // } } } \ No newline at end of file diff --git a/lib/index.js b/lib/index.js index da3b875..f600f13 100644 --- a/lib/index.js +++ b/lib/index.js @@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -const printerFactory = require('pino-http-print') + const Path = require('path') const Hoek = require('@hapi/hoek') const Handlers = require('shortstop-handlers') @@ -81,24 +81,6 @@ const init = async function (options = {}) { overrides }) - const printer = printerFactory({ - all: true, - lax: true, - relativeUrl: true, - translateTime: 'HH:MM:ss.l' - }, { - ignore: 'req,pid,hostname' - }) - - await server.register({ - plugin: require('hapi-pino'), - options: { - logPayload: false, - ignoredEventTags: { log: ['client'], request: '*' }, - instance: require('pino')({}, printer) - } - }) - // shutdown gracefully /* istanbul ignore next */ function end () { diff --git a/tests/unit/index.test.js b/tests/unit/index.test.js index ba1cd8e..a4970f6 100644 --- a/tests/unit/index.test.js +++ b/tests/unit/index.test.js @@ -102,7 +102,7 @@ describe('Catalyst', () => { }) }) - xit('should allow for disabling a default plugin', async () => { + it('should allow for disabling a default plugin', async () => { const server = await Catalyst.init({ userConfigPath: Path.join(__dirname, '..', 'fixtures/manifest-disable-hapi-pino.json') }) @@ -139,7 +139,7 @@ describe('Catalyst', () => { // verify that the default plugins were not overwritten const registeredPluginNames = Object.keys(server.registrations) expect(registeredPluginNames).to.include.members(prodPlugins) - // expect(registeredPluginNames).to.not.include('hapi-pino') + expect(registeredPluginNames).to.not.include('hapi-pino') const response = await server.inject('/test') From ad789e64901dbf48cf6381ff9ef43c105909131e Mon Sep 17 00:00:00 2001 From: aaestrada Date: Wed, 12 Jan 2022 11:19:36 -0600 Subject: [PATCH 07/28] clean package json file --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 95ca261..853912c 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,6 @@ "@vrbo/steerage": "^12.1.0", "hapi-pino": "^9.0.0", "joi": "^17.2.0", - "pino-http-print": "^3.1.0", "pino-pretty": "^7.2.0", "shortstop-handlers": "^1.0.1" }, From fd64100eaf081cdddd591b8cbcb571b7dccfbb68 Mon Sep 17 00:00:00 2001 From: aaestrada Date: Wed, 12 Jan 2022 11:21:41 -0600 Subject: [PATCH 08/28] del duplicate command --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 853912c..9ae9a64 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,6 @@ ], "scripts": { "build": "echo 'noop'", - "test-fix": "standard --fix --env mocha './lib/**/*.js' './tests/**/*.js' && npm run nyc", "test": "standard --env mocha './lib/**/*.js' './tests/**/*.js' && npm run nyc", "test:fix": "standard --fix --env mocha './lib/**/*.js' './tests/**/*.js' && npm run nyc", "mocha": "mocha 'tests/**/*.js'", From 54b5de081b39db7de95ed3718d22f7271dbfd41e Mon Sep 17 00:00:00 2001 From: aaestrada Date: Wed, 12 Jan 2022 11:54:11 -0600 Subject: [PATCH 09/28] explain pino logs config --- examples/simple/readme.md | 46 +++++++++++++++++++++ examples/simple/threads-diagram.drawio.png | Bin 0 -> 23557 bytes 2 files changed, 46 insertions(+) create mode 100644 examples/simple/readme.md create mode 100644 examples/simple/threads-diagram.drawio.png diff --git a/examples/simple/readme.md b/examples/simple/readme.md new file mode 100644 index 0000000..16e2df1 --- /dev/null +++ b/examples/simple/readme.md @@ -0,0 +1,46 @@ +# Catalyst server logs configuration + +The follow diagram explain how our catalyst server manage the logs + +## [Pino-pretty](https://github.com/pinojs/pino-pretty) logs for development mode: + +install pino-pretty as a development dependency. + +` npm install -D pino-pretty ` + +manifest.json +``` + "hapi-pino": { + "plugin": "require:hapi-pino", + "options": { + "$filter": "env.NODE_ENV", + "$default": {}, + "development": { + "transport": { + "target": "pino-pretty", + "options": { + "colorize": true, + "translateTime": true + } + } + } + } + } +``` + +## [Pino-pretty](https://github.com/pinojs/pino/blob/master/docs/pretty.md) logs for production mode(legacy transport): + +Install Pino-pretty globally + +`npm install -g pino-pretty` + +It is recommended to use pino-pretty with pino by piping output to the CLI tool: + +``` +node . | pino-pretty --config=.pino-prettyrc +``` + +.pino-pretty pass the [CLI Arguments](https://github.com/pinojs/pino-pretty#cli-arguments) + + + diff --git a/examples/simple/threads-diagram.drawio.png b/examples/simple/threads-diagram.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..2ca276893ff6819f9d9d2b0740f4d269c3692382 GIT binary patch literal 23557 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 Date: Wed, 12 Jan 2022 11:58:32 -0600 Subject: [PATCH 10/28] Update readme.md --- examples/simple/readme.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/simple/readme.md b/examples/simple/readme.md index 16e2df1..827d6bd 100644 --- a/examples/simple/readme.md +++ b/examples/simple/readme.md @@ -2,6 +2,8 @@ The follow diagram explain how our catalyst server manage the logs +![threads-diagram drawio](https://user-images.githubusercontent.com/88118994/149195822-de5d33ad-f29f-48ff-840b-ce2fb41eb08a.png) + ## [Pino-pretty](https://github.com/pinojs/pino-pretty) logs for development mode: install pino-pretty as a development dependency. From d9912786716afc4a0f5e81152b1604c77e4092b7 Mon Sep 17 00:00:00 2001 From: aaestrada Date: Wed, 12 Jan 2022 14:01:01 -0600 Subject: [PATCH 11/28] update docs --- examples/simple/readme.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/examples/simple/readme.md b/examples/simple/readme.md index 827d6bd..f9146a6 100644 --- a/examples/simple/readme.md +++ b/examples/simple/readme.md @@ -39,10 +39,18 @@ Install Pino-pretty globally It is recommended to use pino-pretty with pino by piping output to the CLI tool: ``` -node . | pino-pretty --config=.pino-prettyrc +node --max-http-header-size=32768 . | pino-pretty --config=.pino-prettyrc ``` .pino-pretty pass the [CLI Arguments](https://github.com/pinojs/pino-pretty#cli-arguments) +_node js profile review_ + +``` +clinic doctor --autocannon [ /items ] -- node --max-http-header-size=32768 ./index | pino-pretty --config=.pino-prettyrc + +``` + + From 8039f777eecb78de64c4f6c70c1753adeb099146 Mon Sep 17 00:00:00 2001 From: aaestrada Date: Fri, 14 Jan 2022 03:28:01 -0600 Subject: [PATCH 12/28] chore: updates docs and example to use transports for pino-pretty --- examples/simple/.pino-prettyrc | 1 + examples/simple/readme.md | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/examples/simple/.pino-prettyrc b/examples/simple/.pino-prettyrc index c098067..75c20a8 100644 --- a/examples/simple/.pino-prettyrc +++ b/examples/simple/.pino-prettyrc @@ -1,4 +1,5 @@ { "colorize": true, "singleLine": true + // ... pass pino-pretty options here } \ No newline at end of file diff --git a/examples/simple/readme.md b/examples/simple/readme.md index f9146a6..773fab6 100644 --- a/examples/simple/readme.md +++ b/examples/simple/readme.md @@ -34,12 +34,21 @@ manifest.json Install Pino-pretty globally -`npm install -g pino-pretty` +`npm install pino-pretty` It is recommended to use pino-pretty with pino by piping output to the CLI tool: ``` -node --max-http-header-size=32768 . | pino-pretty --config=.pino-prettyrc +node --max-http-header-size=32768 ./examples/simple/index.js | ./node_modules/.bin/pino-pretty --config=./examples/simple/.pino-prettyrc +``` + +.pino-prettyrc +``` +{ + "colorize": true, + "singleLine": true + // ... pass pino-pretty options here +} ``` .pino-pretty pass the [CLI Arguments](https://github.com/pinojs/pino-pretty#cli-arguments) @@ -49,7 +58,7 @@ node --max-http-header-size=32768 . | pino-pretty --config=.pino-prettyrc _node js profile review_ ``` -clinic doctor --autocannon [ /items ] -- node --max-http-header-size=32768 ./index | pino-pretty --config=.pino-prettyrc +clinic doctor --autocannon [ /items ] -- node --max-http-header-size=32768 ./examples/simple/index.js | ./node_modules/.bin/pino-pretty --config=./examples/simple/.pino-prettyrc ``` From 124ff8324756c941a9fd1e790993cd98616e32ca Mon Sep 17 00:00:00 2001 From: aaestrada Date: Mon, 17 Jan 2022 08:28:42 -0600 Subject: [PATCH 13/28] Update docs with better redaction --- examples/simple/readme.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/simple/readme.md b/examples/simple/readme.md index 773fab6..bd1f15e 100644 --- a/examples/simple/readme.md +++ b/examples/simple/readme.md @@ -1,6 +1,6 @@ -# Catalyst server logs configuration +# Catalyst server log configuration -The follow diagram explain how our catalyst server manage the logs +The follow diagram explains how our catalyst server manages logs ![threads-diagram drawio](https://user-images.githubusercontent.com/88118994/149195822-de5d33ad-f29f-48ff-840b-ce2fb41eb08a.png) @@ -8,7 +8,7 @@ The follow diagram explain how our catalyst server manage the logs install pino-pretty as a development dependency. -` npm install -D pino-pretty ` +` npm install --save-dev pino-pretty ` manifest.json ``` @@ -32,7 +32,7 @@ manifest.json ## [Pino-pretty](https://github.com/pinojs/pino/blob/master/docs/pretty.md) logs for production mode(legacy transport): -Install Pino-pretty globally +Install Pino-pretty `npm install pino-pretty` From 403c7958f3689d71a711edefc503098f4391dcfd Mon Sep 17 00:00:00 2001 From: aaestrada Date: Wed, 19 Jan 2022 11:53:14 -0600 Subject: [PATCH 14/28] logs to the transport over custom pipeline --- examples/custom-pipeline/index.js | 43 +++++++++++++++++++ examples/custom-pipeline/manifest.json | 15 +++++++ .../custom-pipeline/my-transport-process.js | 9 ++++ examples/custom-pipeline/readme.md | 24 +++++++++++ package.json | 7 +-- 5 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 examples/custom-pipeline/index.js create mode 100644 examples/custom-pipeline/manifest.json create mode 100644 examples/custom-pipeline/my-transport-process.js create mode 100644 examples/custom-pipeline/readme.md diff --git a/examples/custom-pipeline/index.js b/examples/custom-pipeline/index.js new file mode 100644 index 0000000..d988e1f --- /dev/null +++ b/examples/custom-pipeline/index.js @@ -0,0 +1,43 @@ +/** + * After running this example code with node, + * you can see the results in browser at: + * http://localhost:8080/items + */ + + const Catalyst = require('../..'); + const Path = require('path'); + const getResponse = [ + {string: 'string1', number: 1, boolean: true}, + {string: 'string2', number: 2, boolean: false}, + ]; + + const hapiPino = require('hapi-pino'); + const pino = require('pino'); + + async function start (options = {}) { + const server = await Catalyst.init({ + ...options, + userConfigPath: Path.resolve(__dirname, 'manifest.json'), + }); + + server.route({ + path: '/items', + method: 'GET', + options: { + log: { collect: true }, + cache: { expiresIn: 5000 }, + }, + handler: async function (req, h) { + // you can also use a pino instance, which will be faster + req.logger.info('GET_items', getResponse); + return await h.response(getResponse); + }, + }); + + await server.start() + server.log(['info'], `items endpoint : ${server.info.uri}/items`) + return server + } + + start() + \ No newline at end of file diff --git a/examples/custom-pipeline/manifest.json b/examples/custom-pipeline/manifest.json new file mode 100644 index 0000000..f6bcadc --- /dev/null +++ b/examples/custom-pipeline/manifest.json @@ -0,0 +1,15 @@ +{ + "server": { + "debug": false // disable Hapi debug console logging + }, + "register": { + "hapi-pino": { + "plugin": "require:hapi-pino", + "options":{ + "logRequestComplete": false, + "ignoredEventTags": { "log": ["client"], "request": "*" }, + "logPayload": false + } + } + } +} \ No newline at end of file diff --git a/examples/custom-pipeline/my-transport-process.js b/examples/custom-pipeline/my-transport-process.js new file mode 100644 index 0000000..3fd72c8 --- /dev/null +++ b/examples/custom-pipeline/my-transport-process.js @@ -0,0 +1,9 @@ +'use strict'; +const split = require('split2') +const pump = require('pump') +const through = require('through2') +const myTransport = through.obj(function (chunk, enc, cb) { + console.log(chunk) + cb() +}) +pump(process.stdin, split(JSON.parse), myTransport) \ No newline at end of file diff --git a/examples/custom-pipeline/readme.md b/examples/custom-pipeline/readme.md new file mode 100644 index 0000000..4c97d2b --- /dev/null +++ b/examples/custom-pipeline/readme.md @@ -0,0 +1,24 @@ +# Catalyst server log configuration + +## Pipe logs to the transport over custom pipeline input for production + +Example below will take logs from the `process.stdin` and pipe to either `stdout` + +my-transport-process.js +``` +'use strict'; +const split = require('split2') +const pump = require('pump') +const through = require('through2') +const myTransport = through.obj(function (chunk, enc, cb) { + console.log(chunk) + cb() +}) +pump(process.stdin, split(JSON.parse), myTransport) +``` + +Logs can now be consumed using shell piping: + +``` +node --max-http-header-size=32768 ./examples/custom-pipeline/index.js | node ./examples/custom-pipeline/my-transport-process.js +``` \ No newline at end of file diff --git a/package.json b/package.json index 9ae9a64..f7fe344 100644 --- a/package.json +++ b/package.json @@ -58,11 +58,12 @@ "dependencies": { "@hapi/crumb": "^8.0.0", "@hapi/hoek": "^9.0.4", - "@vrbo/steerage": "^12.1.0", - "hapi-pino": "^9.0.0", + "@vrbo/steerage": "^12.1.3", + "hapi-pino": "^9.1.0", "joi": "^17.2.0", "pino-pretty": "^7.2.0", - "shortstop-handlers": "^1.0.1" + "shortstop-handlers": "^1.0.1", + "through2": "^4.0.2" }, "devDependencies": { "@hapi/hapi": "^20.2.1", From 5681f6de86fbf48bef6bf3bd45e37c09ff499050 Mon Sep 17 00:00:00 2001 From: aaestrada Date: Thu, 20 Jan 2022 12:34:42 -0600 Subject: [PATCH 15/28] Add support to transport logs with custom cli options --- .../custom-pipeline/my-transport-process.js | 34 +++++++++++++++++-- examples/custom-pipeline/readme.md | 7 +++- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/examples/custom-pipeline/my-transport-process.js b/examples/custom-pipeline/my-transport-process.js index 3fd72c8..2fd571f 100644 --- a/examples/custom-pipeline/my-transport-process.js +++ b/examples/custom-pipeline/my-transport-process.js @@ -2,8 +2,36 @@ const split = require('split2') const pump = require('pump') const through = require('through2') -const myTransport = through.obj(function (chunk, enc, cb) { - console.log(chunk) +const args = require('args') +const sonic = require('sonic-boom') + +/** + * Set up more options passing at the node cli + * node . | node my-transport-process.js --d="logs/log.log" +*/ +args + .option(['d','destination'], 'The port on which the app will be running') + +const flagOptions = args.parse(process.argv); + +let destination = flagOptions.destination; + +if (!destination) throw new Error('destination is required'); + +const myTransport = through.obj(async function (chunk, enc, cb) { + if(destination === 1 ){ + console.log(chunk) + } else{ + let WriteTodestination = sonic({ + dest: destination || 1, + append: true, + mkdir: true, + sync: true // by default sonic will be async + }) + + WriteTodestination.write(JSON.stringify(chunk) + '\n') + } cb() }) -pump(process.stdin, split(JSON.parse), myTransport) \ No newline at end of file + +return pump(process.stdin, split(JSON.parse), myTransport) \ No newline at end of file diff --git a/examples/custom-pipeline/readme.md b/examples/custom-pipeline/readme.md index 4c97d2b..69a65fc 100644 --- a/examples/custom-pipeline/readme.md +++ b/examples/custom-pipeline/readme.md @@ -20,5 +20,10 @@ pump(process.stdin, split(JSON.parse), myTransport) Logs can now be consumed using shell piping: ``` -node --max-http-header-size=32768 ./examples/custom-pipeline/index.js | node ./examples/custom-pipeline/my-transport-process.js +node --max-http-header-size=32768 ./examples/custom-pipeline/index.js | node ./examples/custom-pipeline/my-transport-process.js -d=1 +``` +Or logs can be transport to a file: + +``` +node --max-http-header-size=32768 ./examples/custom-pipeline/index.js | node ./examples/custom-pipeline/my-transport-process.js -d="logs/log.log" ``` \ No newline at end of file From e2c2e6ba2f3683e0f4c2a0456bd08be57200a55b Mon Sep 17 00:00:00 2001 From: aaestrada Date: Thu, 20 Jan 2022 12:42:19 -0600 Subject: [PATCH 16/28] update code example --- examples/custom-pipeline/readme.md | 34 +++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/examples/custom-pipeline/readme.md b/examples/custom-pipeline/readme.md index 69a65fc..d19c2dd 100644 --- a/examples/custom-pipeline/readme.md +++ b/examples/custom-pipeline/readme.md @@ -10,11 +10,39 @@ my-transport-process.js const split = require('split2') const pump = require('pump') const through = require('through2') -const myTransport = through.obj(function (chunk, enc, cb) { - console.log(chunk) +const args = require('args') +const sonic = require('sonic-boom') + +/** + * Set up more options passing at the node cli + * node . | node my-transport-process.js --d="logs/log.log" +*/ +args + .option(['d','destination'], 'The port on which the app will be running') + +const flagOptions = args.parse(process.argv); + +let destination = flagOptions.destination; + +if (!destination) throw new Error('destination is required'); + +const myTransport = through.obj(async function (chunk, enc, cb) { + if(destination === 1 ){ + console.log(chunk) + } else{ + let WriteTodestination = sonic({ + dest: destination || 1, + append: true, + mkdir: true, + sync: true // by default sonic will be async + }) + + WriteTodestination.write(JSON.stringify(chunk) + '\n') + } cb() }) -pump(process.stdin, split(JSON.parse), myTransport) + +return pump(process.stdin, split(JSON.parse), myTransport) ``` Logs can now be consumed using shell piping: From eeca56ce3e80a6c205ab1502c4a363da10080ac7 Mon Sep 17 00:00:00 2001 From: aaestrada Date: Fri, 21 Jan 2022 07:03:38 -0600 Subject: [PATCH 17/28] update readme file --- examples/custom-pipeline/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/custom-pipeline/readme.md b/examples/custom-pipeline/readme.md index d19c2dd..698a2e4 100644 --- a/examples/custom-pipeline/readme.md +++ b/examples/custom-pipeline/readme.md @@ -18,7 +18,7 @@ const sonic = require('sonic-boom') * node . | node my-transport-process.js --d="logs/log.log" */ args - .option(['d','destination'], 'The port on which the app will be running') + .option(['d','destination'], 'The final destination for the logs') const flagOptions = args.parse(process.argv); From a038b612bd381b377b4f841c7de22a060905d47a Mon Sep 17 00:00:00 2001 From: Aaron Estrada Date: Tue, 25 Jan 2022 15:17:43 -0600 Subject: [PATCH 18/28] Update examples/custom-pipeline/my-transport-process.js Co-authored-by: Bryan Shell --- examples/custom-pipeline/my-transport-process.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/custom-pipeline/my-transport-process.js b/examples/custom-pipeline/my-transport-process.js index 2fd571f..dcc5068 100644 --- a/examples/custom-pipeline/my-transport-process.js +++ b/examples/custom-pipeline/my-transport-process.js @@ -21,7 +21,7 @@ if (!destination) throw new Error('destination is required'); const myTransport = through.obj(async function (chunk, enc, cb) { if(destination === 1 ){ console.log(chunk) - } else{ + } else { let WriteTodestination = sonic({ dest: destination || 1, append: true, From d3bc6151ee742b0aeca9a117706d423a3ed5d217 Mon Sep 17 00:00:00 2001 From: Aaron Estrada Date: Tue, 25 Jan 2022 15:17:53 -0600 Subject: [PATCH 19/28] Update examples/custom-pipeline/my-transport-process.js Co-authored-by: Bryan Shell --- examples/custom-pipeline/my-transport-process.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/custom-pipeline/my-transport-process.js b/examples/custom-pipeline/my-transport-process.js index dcc5068..272b560 100644 --- a/examples/custom-pipeline/my-transport-process.js +++ b/examples/custom-pipeline/my-transport-process.js @@ -19,7 +19,7 @@ let destination = flagOptions.destination; if (!destination) throw new Error('destination is required'); const myTransport = through.obj(async function (chunk, enc, cb) { - if(destination === 1 ){ + if(destination === 1 ) { console.log(chunk) } else { let WriteTodestination = sonic({ From dfad3f5866eb9e4ee7e60e9f25adc49e46adf934 Mon Sep 17 00:00:00 2001 From: aaestrada Date: Wed, 26 Jan 2022 13:49:24 -0600 Subject: [PATCH 20/28] upgrade hapi-pino to read ECONRESET error --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2bdb0a1..7410442 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@hapi/crumb": "^8.0.0", "@hapi/hoek": "^9.0.4", "@vrbo/steerage": "^12.1.3", - "hapi-pino": "^9.1.0", + "hapi-pino": "^9.1.1", "joi": "^17.2.0", "pino-pretty": "^7.2.0", "shortstop-handlers": "^1.0.1", From ca0037d6fb9ef1a50e09a78709a2b81d16d75212 Mon Sep 17 00:00:00 2001 From: aaestrada Date: Wed, 26 Jan 2022 13:49:24 -0600 Subject: [PATCH 21/28] upgrade hapi-pino to fix read ECONRESET error --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2bdb0a1..7410442 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "@hapi/crumb": "^8.0.0", "@hapi/hoek": "^9.0.4", "@vrbo/steerage": "^12.1.3", - "hapi-pino": "^9.1.0", + "hapi-pino": "^9.1.1", "joi": "^17.2.0", "pino-pretty": "^7.2.0", "shortstop-handlers": "^1.0.1", From 4e099b13a86142d187d6b18985fe0f8e68f6721b Mon Sep 17 00:00:00 2001 From: Aaron Estrada Date: Wed, 2 Feb 2022 07:29:10 -0600 Subject: [PATCH 22/28] Update examples/simple/readme.md Co-authored-by: Bryan Shell --- examples/simple/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/simple/readme.md b/examples/simple/readme.md index bd1f15e..6619965 100644 --- a/examples/simple/readme.md +++ b/examples/simple/readme.md @@ -55,7 +55,7 @@ node --max-http-header-size=32768 ./examples/simple/index.js | ./node_modules/.b -_node js profile review_ +## Nodejs Profiling these changes ``` clinic doctor --autocannon [ /items ] -- node --max-http-header-size=32768 ./examples/simple/index.js | ./node_modules/.bin/pino-pretty --config=./examples/simple/.pino-prettyrc From 9574050f68e1b37cd84f40116e72809c5dd10868 Mon Sep 17 00:00:00 2001 From: aaestrada Date: Wed, 2 Feb 2022 08:04:37 -0600 Subject: [PATCH 23/28] update docs and default config for logs --- examples/custom-pipeline/index.js | 43 -------------- examples/custom-pipeline/manifest.json | 15 ----- .../custom-pipeline/my-transport-process.js | 37 ------------ examples/custom-pipeline/readme.md | 57 ------------------- examples/simple/.pino-prettyrc | 5 -- examples/simple/manifest.json | 30 ++++++++-- examples/simple/readme.md | 34 +++++------ lib/config.json | 14 +---- 8 files changed, 42 insertions(+), 193 deletions(-) delete mode 100644 examples/custom-pipeline/index.js delete mode 100644 examples/custom-pipeline/manifest.json delete mode 100644 examples/custom-pipeline/my-transport-process.js delete mode 100644 examples/custom-pipeline/readme.md delete mode 100644 examples/simple/.pino-prettyrc diff --git a/examples/custom-pipeline/index.js b/examples/custom-pipeline/index.js deleted file mode 100644 index d988e1f..0000000 --- a/examples/custom-pipeline/index.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * After running this example code with node, - * you can see the results in browser at: - * http://localhost:8080/items - */ - - const Catalyst = require('../..'); - const Path = require('path'); - const getResponse = [ - {string: 'string1', number: 1, boolean: true}, - {string: 'string2', number: 2, boolean: false}, - ]; - - const hapiPino = require('hapi-pino'); - const pino = require('pino'); - - async function start (options = {}) { - const server = await Catalyst.init({ - ...options, - userConfigPath: Path.resolve(__dirname, 'manifest.json'), - }); - - server.route({ - path: '/items', - method: 'GET', - options: { - log: { collect: true }, - cache: { expiresIn: 5000 }, - }, - handler: async function (req, h) { - // you can also use a pino instance, which will be faster - req.logger.info('GET_items', getResponse); - return await h.response(getResponse); - }, - }); - - await server.start() - server.log(['info'], `items endpoint : ${server.info.uri}/items`) - return server - } - - start() - \ No newline at end of file diff --git a/examples/custom-pipeline/manifest.json b/examples/custom-pipeline/manifest.json deleted file mode 100644 index f6bcadc..0000000 --- a/examples/custom-pipeline/manifest.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "server": { - "debug": false // disable Hapi debug console logging - }, - "register": { - "hapi-pino": { - "plugin": "require:hapi-pino", - "options":{ - "logRequestComplete": false, - "ignoredEventTags": { "log": ["client"], "request": "*" }, - "logPayload": false - } - } - } -} \ No newline at end of file diff --git a/examples/custom-pipeline/my-transport-process.js b/examples/custom-pipeline/my-transport-process.js deleted file mode 100644 index 272b560..0000000 --- a/examples/custom-pipeline/my-transport-process.js +++ /dev/null @@ -1,37 +0,0 @@ -'use strict'; -const split = require('split2') -const pump = require('pump') -const through = require('through2') -const args = require('args') -const sonic = require('sonic-boom') - -/** - * Set up more options passing at the node cli - * node . | node my-transport-process.js --d="logs/log.log" -*/ -args - .option(['d','destination'], 'The port on which the app will be running') - -const flagOptions = args.parse(process.argv); - -let destination = flagOptions.destination; - -if (!destination) throw new Error('destination is required'); - -const myTransport = through.obj(async function (chunk, enc, cb) { - if(destination === 1 ) { - console.log(chunk) - } else { - let WriteTodestination = sonic({ - dest: destination || 1, - append: true, - mkdir: true, - sync: true // by default sonic will be async - }) - - WriteTodestination.write(JSON.stringify(chunk) + '\n') - } - cb() -}) - -return pump(process.stdin, split(JSON.parse), myTransport) \ No newline at end of file diff --git a/examples/custom-pipeline/readme.md b/examples/custom-pipeline/readme.md deleted file mode 100644 index 698a2e4..0000000 --- a/examples/custom-pipeline/readme.md +++ /dev/null @@ -1,57 +0,0 @@ -# Catalyst server log configuration - -## Pipe logs to the transport over custom pipeline input for production - -Example below will take logs from the `process.stdin` and pipe to either `stdout` - -my-transport-process.js -``` -'use strict'; -const split = require('split2') -const pump = require('pump') -const through = require('through2') -const args = require('args') -const sonic = require('sonic-boom') - -/** - * Set up more options passing at the node cli - * node . | node my-transport-process.js --d="logs/log.log" -*/ -args - .option(['d','destination'], 'The final destination for the logs') - -const flagOptions = args.parse(process.argv); - -let destination = flagOptions.destination; - -if (!destination) throw new Error('destination is required'); - -const myTransport = through.obj(async function (chunk, enc, cb) { - if(destination === 1 ){ - console.log(chunk) - } else{ - let WriteTodestination = sonic({ - dest: destination || 1, - append: true, - mkdir: true, - sync: true // by default sonic will be async - }) - - WriteTodestination.write(JSON.stringify(chunk) + '\n') - } - cb() -}) - -return pump(process.stdin, split(JSON.parse), myTransport) -``` - -Logs can now be consumed using shell piping: - -``` -node --max-http-header-size=32768 ./examples/custom-pipeline/index.js | node ./examples/custom-pipeline/my-transport-process.js -d=1 -``` -Or logs can be transport to a file: - -``` -node --max-http-header-size=32768 ./examples/custom-pipeline/index.js | node ./examples/custom-pipeline/my-transport-process.js -d="logs/log.log" -``` \ No newline at end of file diff --git a/examples/simple/.pino-prettyrc b/examples/simple/.pino-prettyrc deleted file mode 100644 index 75c20a8..0000000 --- a/examples/simple/.pino-prettyrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "colorize": true, - "singleLine": true - // ... pass pino-pretty options here -} \ No newline at end of file diff --git a/examples/simple/manifest.json b/examples/simple/manifest.json index f6bcadc..568215c 100644 --- a/examples/simple/manifest.json +++ b/examples/simple/manifest.json @@ -6,10 +6,32 @@ "hapi-pino": { "plugin": "require:hapi-pino", "options":{ - "logRequestComplete": false, - "ignoredEventTags": { "log": ["client"], "request": "*" }, - "logPayload": false - } + "$filter": "env.NODE_ENV", + "$default": { + "logRequestComplete": false, + "ignoredEventTags": { "log": ["client"], "request": "*" }, + "logPayload": false, + "transport": { + "targets": [ + { + "target": "pino/file", + "options": { + "destination": 1 + } + } + ] + } + }, + "development": { + "transport": { + "target": "pino-pretty", + "options": { + "colorize": true, + "translateTime": true + } + } + } + } } } } \ No newline at end of file diff --git a/examples/simple/readme.md b/examples/simple/readme.md index bd1f15e..d23e876 100644 --- a/examples/simple/readme.md +++ b/examples/simple/readme.md @@ -30,32 +30,28 @@ manifest.json } ``` -## [Pino-pretty](https://github.com/pinojs/pino/blob/master/docs/pretty.md) logs for production mode(legacy transport): - -Install Pino-pretty - -`npm install pino-pretty` - -It is recommended to use pino-pretty with pino by piping output to the CLI tool: +pass the `NODE_ENV` as following: ``` -node --max-http-header-size=32768 ./examples/simple/index.js | ./node_modules/.bin/pino-pretty --config=./examples/simple/.pino-prettyrc +NODE_ENV=development node . ``` -.pino-prettyrc +## [Pino/file](https://github.com/pinojs/pino/blob/HEAD/docs/transports.md#pinofile) transport logs to stdout or file. + ``` -{ - "colorize": true, - "singleLine": true - // ... pass pino-pretty options here -} + "transport": { + "targets": [ + { + "target": "pino/file", + "options": { + "destination": 1 + } + } + ] + } ``` -.pino-pretty pass the [CLI Arguments](https://github.com/pinojs/pino-pretty#cli-arguments) - - - -_node js profile review_ +## node js profile review ``` clinic doctor --autocannon [ /items ] -- node --max-http-header-size=32768 ./examples/simple/index.js | ./node_modules/.bin/pino-pretty --config=./examples/simple/.pino-prettyrc diff --git a/lib/config.json b/lib/config.json index 3b8d910..a7bbda0 100644 --- a/lib/config.json +++ b/lib/config.json @@ -37,19 +37,7 @@ }, "hapi-pino": { "plugin": "require:hapi-pino", - "options": { - "$filter": "env.NODE_ENV", - "$default": {}, - "development": { - "transport": { - "target": "pino-pretty", - "options": { - "colorize": true, - "translateTime": true - } - } - } - } + "options": {} } } } \ No newline at end of file From 21dcf2f494de9fd698b7bc0e8a33a45854722364 Mon Sep 17 00:00:00 2001 From: aaestrada Date: Wed, 2 Feb 2022 08:06:34 -0600 Subject: [PATCH 24/28] updte docs --- examples/simple/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/simple/readme.md b/examples/simple/readme.md index d23e876..c02ef74 100644 --- a/examples/simple/readme.md +++ b/examples/simple/readme.md @@ -36,7 +36,7 @@ pass the `NODE_ENV` as following: NODE_ENV=development node . ``` -## [Pino/file](https://github.com/pinojs/pino/blob/HEAD/docs/transports.md#pinofile) transport logs to stdout or file. +## [Pino/file](https://github.com/pinojs/pino/blob/HEAD/docs/transports.md#pinofile) transport logs to stdout or file for production. ``` "transport": { From c327c201d9fbfd72fdfb759cef588d1020ff5447 Mon Sep 17 00:00:00 2001 From: aaestrada Date: Wed, 2 Feb 2022 08:09:06 -0600 Subject: [PATCH 25/28] update path --- examples/simple/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/simple/readme.md b/examples/simple/readme.md index c02ef74..3577743 100644 --- a/examples/simple/readme.md +++ b/examples/simple/readme.md @@ -33,7 +33,7 @@ manifest.json pass the `NODE_ENV` as following: ``` -NODE_ENV=development node . +NODE_ENV=development node ./examples/simple/index.js ``` ## [Pino/file](https://github.com/pinojs/pino/blob/HEAD/docs/transports.md#pinofile) transport logs to stdout or file for production. From 28da9c88dfd24456e8bb919f604a819bcdd1bf34 Mon Sep 17 00:00:00 2001 From: aaestrada Date: Wed, 2 Feb 2022 08:15:26 -0600 Subject: [PATCH 26/28] clean package json file --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 7410442..af3d841 100644 --- a/package.json +++ b/package.json @@ -68,8 +68,7 @@ "hapi-pino": "^9.1.1", "joi": "^17.2.0", "pino-pretty": "^7.2.0", - "shortstop-handlers": "^1.0.1", - "through2": "^4.0.2" + "shortstop-handlers": "^1.0.1" }, "devDependencies": { "@hapi/hapi": "^20.2.1", From 7e17e62d7d6ad50b6ea315ba978f5ff4fdf49af6 Mon Sep 17 00:00:00 2001 From: aaestrada Date: Wed, 2 Feb 2022 11:58:15 -0600 Subject: [PATCH 27/28] bring back pino-pretty for dev --- lib/config.json | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/config.json b/lib/config.json index a7bbda0..7e8f4c8 100644 --- a/lib/config.json +++ b/lib/config.json @@ -37,7 +37,20 @@ }, "hapi-pino": { "plugin": "require:hapi-pino", - "options": {} + "options": { + "$filter": "env.NODE_ENV", + "$default": {}, + "development": { + "transport": { + "target": "pino-pretty", + "options": { + "colorize": true, + "translateTime": true + } + } + } + + } } } } \ No newline at end of file From 78c46369dd2b9e6f1d11768a52e4985dfa03261b Mon Sep 17 00:00:00 2001 From: aaestrada Date: Wed, 2 Feb 2022 12:11:17 -0600 Subject: [PATCH 28/28] update config file --- lib/config.json | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/config.json b/lib/config.json index 7e8f4c8..894c6fc 100644 --- a/lib/config.json +++ b/lib/config.json @@ -49,7 +49,6 @@ } } } - } } }