Skip to content

Commit

Permalink
Merge branch 'master' into obscure_authm_header
Browse files Browse the repository at this point in the history
  • Loading branch information
kldavis4 authored Oct 15, 2018
2 parents 798938a + a91ba91 commit 774c43a
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 38 deletions.
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ jobs:
- run:
name: Publish to npm
command: npm publish

workflows:
version: 2
test_deploy:
Expand Down
23 changes: 16 additions & 7 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,18 @@ function getMiddlewareConfig (config, logger) {
logName: 'requestId',
obscureHeaders: alwaysObscureHeaders.concat(config.obscureHeaders || []),
excludeHeaders: config.excludeHeaders || [],
additionalRequestFinishData: req => {
const extraFields = {
event: 'REQUEST',
tenant: req.headers['x-kuali-tenant'],
lane: req.headers['x-kuali-lane']
}
filter: config.middlewareFilter,
additionalRequestFinishData: (req, res) => {
const extraFields = Object.assign(
{
event: 'REQUEST',
tenant: req.headers['x-kuali-tenant'],
lane: req.headers['x-kuali-lane']
},
config.additionalRequestFinishData
? config.additionalRequestFinishData(req, res)
: {}
)
return extraFields
}
}
Expand All @@ -72,7 +78,10 @@ function getLoggerConfig (config) {
product: config.product,
environment: config.environment,
level: config.level || 'info',
serializers: { err: bunyan.stdSerializers.err },
serializers: Object.assign(
{ err: bunyan.stdSerializers.err },
config.serializers || {}
),
streams: [
{
level: config.level || 'info',
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "kuali-logger",
"version": "0.1.2",
"version": "0.1.5",
"description": "Standardized logger for Kuali apps",
"main": "lib/index.js",
"scripts": {
Expand Down
72 changes: 57 additions & 15 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
[![bitHound Overall Score](https://www.bithound.io/projects/badges/2258aae0-8f63-11e7-b68c-bd8234fdabb6/score.svg)](https://www.bithound.io/github/KualiCo/kuali-logger)
[![bitHound Dependencies](https://www.bithound.io/projects/badges/2258aae0-8f63-11e7-b68c-bd8234fdabb6/dependencies.svg)](https://www.bithound.io/github/KualiCo/kuali-logger/master/dependencies/npm)
[![CircleCI](https://circleci.com/gh/KualiCo/kuali-logger/tree/master.svg?style=shield&circle-token=b8b3696e50f3bce018f444658e7bd9c738d41751)](https://circleci.com/gh/KualiCo/kuali-logger/tree/master)
[![codecov](https://codecov.io/gh/KualiCo/kuali-logger/branch/master/graph/badge.svg)](https://codecov.io/gh/KualiCo/kuali-logger)

Expand Down Expand Up @@ -43,18 +41,20 @@ const log = require('kuali-logger')(config.get('log'))

These are the supported configuration options:

| Option | Type | Valid values or examples | Default | Required |
| --- | :---: | --- | :---: | :---: |
| `name` | string | res-coi-production | | X |
| `team` | string | res | | X |
| `product` | string | coi | | X |
| `environment` | string | production | | X |
| `level` | string | `trace`, `debug`, `info`, `warn`, `error`, `fatal` | `info` ||
| `format` | string | `short`, `long`, `simple`, `json`, `bunyan`, `pretty` | `json` ||
| `obscureHeaders` | array of strings | `['x-newrelic-id', 'ip']` | `['authorization', 'cookie']` ||
| `excludeHeaders` | array of strings | `['x-real-ip','x-newrelic-transaction']` | `[]` ||
| `stream` | object | ```{ name: 'myStream', stream: process.stdout, level: 'debug', outputFormat: 'json' }``` | bunyan-format stream ||
| `src` | boolean | false, true *(Slows output, don't use in production)* | false ||
| Option | Type | Valid values or examples | Default | Required |
| ------------------ | :------------------------------------------------------------------------: | ---------------------------------------------------------------------------------------- | :---------------------------: | :------: |
| `name` | string | res-coi-production | | X |
| `team` | string | res | | X |
| `product` | string | coi | | X |
| `environment` | string | production | | X |
| `level` | string | `trace`, `debug`, `info`, `warn`, `error`, `fatal` | `info` |
| `format` | string | `short`, `long`, `simple`, `json`, `bunyan`, `pretty` | `json` |
| `obscureHeaders` | array of strings | `['x-newrelic-id', 'ip']` | `['authorization', 'cookie']` |
| `excludeHeaders` | array of strings | `['x-real-ip','x-newrelic-transaction']` | `[]` |
| `stream` | object | ```{ name: 'myStream', stream: process.stdout, level: 'debug', outputFormat: 'json' }``` | bunyan-format stream |
| `src` | boolean | false, true *(Slows output, don't use in production)* | false |
| `serializers` | [object with functions](https://github.com/trentm/node-bunyan#serializers) | valid javascript serializer functions | |
| `middlewareFilter` | function | | valid javascript function | |

### Log Example

Expand Down Expand Up @@ -93,7 +93,14 @@ Adding the logger middleware will automatically log all request and response eve

```js
const express = require('express')
const log = require('kuali-logger')(config.get('log'))
const log = require('kuali-logger')({
...config.get('log'),
additionalRequestFinishData: (req, res) => ({
userId: req.userInfo.id,
userName: req.userInfo.userName
},
filter: (req, res) => req.url.includes('/api/v1/health')
)

const app = express()
app.use(log.middleware)
Expand Down Expand Up @@ -191,6 +198,21 @@ if(err) {
}
```
## Filter log output
You can filter log output by creating a function that modifies the `req` and `res` objects and applying it to the log configuration.
```js
function myMiddlewareFilter (req, res) {
const pattern = /(\/readyz$|\/healthz$|\/metrics$|\/health$)/
return req.headers['x-synthetic'] || pattern.test(req.url)
}

module.exports = {
log: {
middlewareFilter: myMiddlewareFilter
}
}
```
## Configure a custom stream
You can override the default stream configuration with your own [stream configuration](https://github.com/trentm/node-bunyan#streams).
Expand All @@ -215,6 +237,26 @@ const logConfig = {
const log = require('kuali-logger')(logConfig)
```
## Replace a standard serializer
You can replace the built-in serializers (`req` and `res`) with your own functions.
```js
function myResSerializer(res) {
return {
statusCode: res.statusCode,
header: res._header
}
}

module.exports = {
log: {
serializers: {
res: myResSerializer
}
}
}
```
## Add a custom serializer
You can use the standard bunyan method to [add a custom serializer](https://github.com/trentm/node-bunyan#serializers).
Expand Down
64 changes: 49 additions & 15 deletions test/middleware.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,26 @@ const stream = {
const obscureHeaders = ['obscure']
const excludeHeaders = ['exclude']

const log = require('../lib')({
name: 'testLogger',
team: 'testTeam',
product: 'testProduct',
environment: 'testEnvironment',
stream,
obscureHeaders,
excludeHeaders
})
function createApp (customConfig) {
const log = require('../lib')(Object.assign({
name: 'testLogger',
team: 'testTeam',
product: 'testProduct',
environment: 'testEnvironment',
stream,
obscureHeaders,
excludeHeaders
}, customConfig))

const app = express()
app.use(log.middleware)
app.get('/', (req, res) => {
req.log.info()
res.send('ok')
})
const app = express()
app.use(log.middleware)
app.get('/', (req, res) => {
req.appSpecificReq = 'test'
req.log.info()
res.send('ok')
})
return app
}

beforeEach(() => {
catcher.clear()
Expand All @@ -38,6 +42,7 @@ beforeEach(() => {
describe('middleware', () => {
describe('requestId', () => {
test('sets requestId correctly if no existing requestId', done => {
const app = createApp()
request(app).get('/').end((err, res) => {
if (err) throw err
expect(res.headers.hasOwnProperty('x-request-id')).toBe(true)
Expand All @@ -47,6 +52,7 @@ describe('middleware', () => {
})

test('leaves existing requestId unchanged', done => {
const app = createApp()
request(app).get('/').set('X-Request-Id', 'test').end((err, res) => {
if (err) throw err
expect(res.headers['x-request-id']).toBe('test')
Expand All @@ -57,6 +63,7 @@ describe('middleware', () => {
})

describe('additional fields', () => {
const app = createApp()
test('adds additional fields to log output', done => {
request(app)
.get('/')
Expand All @@ -70,10 +77,24 @@ describe('middleware', () => {
done()
})
})
test('adds app specific fields', done => {
const app = createApp({additionalRequestFinishData: req => ({appSpecificReq: req.appSpecificReq})})
request(app)
.get('/')
.set('x-kuali-tenant', 'tenant')
.set('x-kuali-lane', 'lane')
.end((err, res) => {
if (err) throw err
expect(catcher.last.event).toBe('REQUEST')
expect(catcher.last.appSpecificReq).toBe('test')
done()
})
})
})

describe('obscureHeaders and excludeHeaders', () => {
test('obscures and excludes configured headers', done => {
const app = createApp()
request(app)
.get('/')
.set('obscure', 'test')
Expand All @@ -90,4 +111,17 @@ describe('middleware', () => {
})
})
})

describe('filters requests', () => {
test('filters requests based on filter function', done => {
const app = createApp({middlewareFilter: req => req.url.includes('filtered')})
request(app)
.get('/filtered')
.end((err, res) => {
if (err) throw err
expect(catcher.last).toBeFalsy()
done()
})
})
})
})

0 comments on commit 774c43a

Please sign in to comment.