From 7484437551ba6f3f8b913638942e280eab8ed412 Mon Sep 17 00:00:00 2001 From: Aaron Ransley Date: Wed, 4 Nov 2020 12:39:00 -0700 Subject: [PATCH] Refs #4 - Release 1.2.0 --- CHANGELOG.md | 33 ++++++++-- README.md | 167 ++++++++++++++++++++++++++++++++++++--------------- index.js | 88 ++++++++++++++++----------- package.json | 2 +- 4 files changed, 200 insertions(+), 90 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce5fa29..f49de97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - ... +## [v1.2.0] - 11-4-2020 +### Added +- Added ability to remove default request and error middleware handlers. Use the `skipRequestMiddlewareHandler` and `skipErrorMiddlewareHandler` to skip the registration of these. +- Added ability to avoid filesystem access in non-filesystem based logging setups using `autoCreateLogPath` and `useDefaultLogger` options. See README.md (usage items #3 and #4) for changes. + - Example in your apps `nuxt.config.js`: + ```js + // ... + winstonLog: { + autoCreateLogPath: false, + useDefaultLogger: false, + loggerOptions: { + format: combine( + label({ label: 'Custom Nuxt logging!' }), + timestamp(), + prettyPrint() + ), + transports: [new transports.Console()] + } + } + // ... + ``` + +### Changed +- Updated README w/ information on new features + ## [v1.1.1] - 11-4-2020 ### Changed - Bumped deps @@ -19,12 +44,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Learn more about the `context` object here: https://nuxtjs.org/api/context - Added support for passing options to module via inline module options in `nuxt.config.js` - For example: - ``` - ... + ```js + // ... modules: [ - ['nuxt-winston-log', { logName: 'special-logs.log` }] + ['nuxt-winston-log', { logName: 'special-logs.log' }] ] - ... + // ... ``` ### Changed diff --git a/README.md b/README.md index 7f024a9..65f95c3 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ $ yarn add nuxt-winston-log # or npm i nuxt-winston-log } ``` -3. Change options as needed. See Usage section for details. +3. Change options using the `winstonLog` key as needed. See Usage section for details. # Usage @@ -47,65 +47,134 @@ $ yarn add nuxt-winston-log # or npm i nuxt-winston-log The default values are: -```js -{ - // Path that log files will be created in. - // Change this to keep things neat. - logPath: './logs', - // Name of log file. - // Change this to keep things tidy. - logName: `${process.env.NODE_ENV}.log` -} -``` + ```js + // ... + { + // Path that log files will be created in. + // Change this to keep things neat. + logPath: './logs', + + // Name of log file. + // Change this to keep things tidy. + logName: `${process.env.NODE_ENV}.log`, + + // Setting to determine if filesystem is accessed to auto-create logPath. + // Set this to `false` for non-filesystem based logging setups. + autoCreateLogPath: true, + + // Setting to determine if default logger instance is created for you. + // Set this to `false` and provide `loggerOptions` (usage item #3) to + // completely customize the logger instance (formatting, transports, etc.) + useDefaultLogger: true, + + // Settings to determine if default handlers should be + // registered for requests and errors respectively. + // Set to `true` to skip request logging (level: info). + skipRequestMiddlewareHandler: false, + // Set to `true` to skip error logging (level: error). + skipErrorMiddlewareHandler: false + } + // ... + ``` 2. To customize the [File Transport instance](https://github.com/winstonjs/winston/blob/master/docs/transports.md#file-transport), pass options to the `transportOptions` key: -```js -import path from 'path' -const logfilePath = path.resolve(process.cwd(), './logs', `${process.env.NODE_ENV}.log`) + Example in your apps `~/nuxt.config.js` file: + ```js + import path from 'path' + const logfilePath = path.resolve(process.cwd(), './logs', `${process.env.NODE_ENV}.log`) + + export default { + // Configure nuxt-winston-log module + winstonLog: { + transportOptions: { + filename: logfilePath + } + } + } + ``` + +3. To customize the [Logger instance](https://github.com/winstonjs/winston#creating-your-own-logger), set `useDefaultLogger` option to `false`, and make sure you provide a custom set of `loggerOptions` to be passed to [Winston's `createLogger`](https://github.com/winstonjs/winston#creating-your-own-logger) under the hood: + + Example in your apps `~/nuxt.config.js` file: + ```js + // Note imports from winston core for transports, formatting helpers, etc. + import { format, transports } from 'winston' + const { combine, timestamp, label, prettyPrint } = format + + export default { + // Configure nuxt-winston-log module + winstonLog: { + useDefaultLogger: false, + loggerOptions: { + format: combine( + label({ label: 'Custom Nuxt logging!' }), + timestamp(), + prettyPrint() + ), + transports: [new transports.Console()] + } + } + } + ``` + +4. To disable automatic creation of the `logPath` directory, set `autoCreateLogPath` option to `false`: -export default { - winstonLog: { - transportOptions: { - filename: logfilePath + Example in your apps `~/nuxt.config.js` file: + ```js + // ... + export default { + // Configure nuxt-winston-log module + winstonLog: { + autoCreateLogPath: false + } } - } -} -``` + // ... + ``` -3. To customize the [Logger instance](https://github.com/winstonjs/winston#creating-your-own-logger), pass options to the `loggerOptions` key. Note that you can completely overwrite all defaults this way, and establish your own `format`, `transports`, and so on. +5. To access the winston logger instance from within Nuxt lifecycle areas, use the `$winstonLog` key from the Nuxt `context` object. **Note:** This is only available for server-side executions. For example, because `asyncData` is an isomorphic function in Nuxt, you will need to guard `$winstonLog` access with something like `if (process.server) { ... }` -```js -import { format, transports } from 'winston' -const { combine, timestamp, label, prettyPrint } = format - -export default { - winstonLog: { - loggerOptions: { - format: combine( - label({ label: 'Custom Nuxt logging!' }), - timestamp(), - prettyPrint() - ), - transports: [new transports.Console()] + Example `nuxtServerInit` in your apps `~/store/index.js`: + ```js + // ... + export const actions = { + async nuxtServerInit({ store, commit }, { req, $winstonLog }) { + $winstonLog.info(`x-forwarded-host: ${req.headers['x-forwarded-host']}`) + } } - } -} -``` + // ... + ``` -4. To access the winston logger instance from within Nuxt lifecycle areas, use the `$winstonLog` key from the Nuxt `context` object. + Example `asyncData` in your apps `~/pages/somepage.vue`: + ```js + // ... + asyncData(context) { + if (process.server) { + context.$winstonLog.info('Hello from asyncData on server') + } + } + // ... + ``` -```js -// e.g. inside `~/store/index.js` -// ... -export const actions = { - async nuxtServerInit({ store, commit }, { req, $winstonLog }) { +6. To disable default request and error logging behaviors, the `skipRequestMiddlewareHandler` and `skipErrorMiddlewareHandler` options can be set to `true`. For more information on what these handlers do out of the box, see the source at the [bottom of the `~/index.js` file](https://github.com/aaronransley/nuxt-winston-log/blob/master/index.js). + + Example in your apps `~/nuxt.config.js` file: + ```js // ... - $winstonLog.info(`x-forwarded-host: ${req.headers['x-forwarded-host']}`) + export default { + // Configure nuxt-winston-log module + winstonLog: { + skipRequestMiddlewareHandler: true, + skipErrorMiddlewareHandler: true + } + } // ... - } -} -// ... -``` + ``` + + Adding your own middleware handlers to Nuxt is outside the scope of this documentation, but can be accomplished using [a custom module of your own](https://nuxtjs.org/docs/2.x/directory-structure/modules#write-your-own-module). + + Because modules are executed sequentially, your custom module should be loaded _after the `nuxt-winston-log` module_. You can then access the logger instance via `process.winstonLog` as needed. + + See [the `~/index.js` file](https://github.com/aaronransley/nuxt-winston-log/blob/master/index.js) for some example middleware handlers / hooks. # [Changelog](./CHANGELOG.md) diff --git a/index.js b/index.js index 8393717..abf0bf7 100644 --- a/index.js +++ b/index.js @@ -14,23 +14,35 @@ module.exports = function WinstonLog(moduleOptions = {}) { const winstonOptions = { logPath: './logs', logName: `${process.env.NODE_ENV}.log`, + autoCreateLogPath: true, + useDefaultLogger: true, + skipRequestMiddlewareHandler: false, + skipErrorMiddlewareHandler: false, ...this.options.winstonLog, ...moduleOptions, } - mkdirIfNotExists(resolve(process.cwd(), winstonOptions.logPath)) + if (winstonOptions.autoCreateLogPath) { + mkdirIfNotExists(resolve(process.cwd(), winstonOptions.logPath)) + } - const logger = createLogger({ - exitOnError: false, - format: combine(timestamp(), errors({ stack: true }), json()), - transports: [ - new transports.File({ - filename: resolve(winstonOptions.logPath, winstonOptions.logName), - ...winstonOptions.transportOptions, - }), - ], - ...winstonOptions.loggerOptions, - }) + let logger + + if (winstonOptions.useDefaultLogger) { + logger = createLogger({ + exitOnError: false, + format: combine(timestamp(), errors({ stack: true }), json()), + transports: [ + new transports.File({ + filename: resolve(winstonOptions.logPath, winstonOptions.logName), + ...winstonOptions.transportOptions, + }), + ], + ...winstonOptions.loggerOptions, + }) + } else { + logger = createLogger(winstonOptions.loggerOptions) + } // Persist a reference to Winston logger instance. // This is injected by `~/plugin.server.js` for use via Nuxt context objects @@ -43,33 +55,37 @@ module.exports = function WinstonLog(moduleOptions = {}) { mode: 'server', }) - this.nuxt.hook('render:setupMiddleware', (app) => - app.use((req, res, next) => { - const reqInfo = extractReqInfo(req) - const isHtmlOrJson = - checkHeadersAccepts(reqInfo.headers, ['text/html', 'application/xhtml']) || - checkHeadersContentType(reqInfo.headers, ['application/json']) - const isInternalNuxtRequest = reqInfo.url && reqInfo.url.includes('/_nuxt/') + if (winstonOptions.skipRequestMiddlewareHandler !== true) { + this.nuxt.hook('render:setupMiddleware', (app) => + app.use((req, res, next) => { + const reqInfo = extractReqInfo(req) + const isHtmlOrJson = + checkHeadersAccepts(reqInfo.headers, ['text/html', 'application/xhtml']) || + checkHeadersContentType(reqInfo.headers, ['application/json']) + const isInternalNuxtRequest = reqInfo.url && reqInfo.url.includes('/_nuxt/') - if (isHtmlOrJson && !isInternalNuxtRequest) { - logger.info(`Accessed ${req.url}`, { - ...reqInfo, - }) - } - next() - }) - ) + if (isHtmlOrJson && !isInternalNuxtRequest) { + logger.info(`Accessed ${req.url}`, { + ...reqInfo, + }) + } + next() + }) + ) + } - this.nuxt.hook('render:errorMiddleware', (app) => - app.use((err, req, res, next) => { - const newError = new Error(err) - newError.stack = err.stack - logger.error(newError, { - ...extractReqInfo(req), + if (winstonOptions.skipErrorMiddlewareHandler !== true) { + this.nuxt.hook('render:errorMiddleware', (app) => + app.use((err, req, res, next) => { + const newError = new Error(err) + newError.stack = err.stack + logger.error(newError, { + ...extractReqInfo(req), + }) + next(err) }) - next(err) - }) - ) + ) + } } module.exports.meta = pkg diff --git a/package.json b/package.json index d5b62c0..9c085bf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nuxt-winston-log", - "version": "1.1.1", + "version": "1.2.0", "description": "Enable logging to Winston in your Nuxt application", "main": "index.js", "author": "Aaron Ransley (https://aaronransley.com)",