Skip to content

Commit

Permalink
Refs #4 - Release 1.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronransley committed Nov 4, 2020
1 parent f6c1da2 commit 7484437
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 90 deletions.
33 changes: 29 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
167 changes: 118 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,73 +39,142 @@ $ 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

1. By default, `nuxt-winston-log` exposes some basic options for common needs. Internally, these options are used to create a basic [Logger instance](https://github.com/winstonjs/winston#creating-your-own-logger) and wire up middleware.

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)
88 changes: 52 additions & 36 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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)",
Expand Down

0 comments on commit 7484437

Please sign in to comment.