Skip to content
Snippets Groups Projects
Commit fb6fd755 authored by Jure's avatar Jure
Browse files

Add 'packages/pubsweet-logger/' from commit '195785b7'

git-subtree-dir: packages/pubsweet-logger
git-subtree-mainline: b38985c6
git-subtree-split: 195785b7
parents b38985c6 195785b7
No related branches found
No related tags found
No related merge requests found
Showing
with 3329 additions and 0 deletions
if declare -Ff use_nvm >/dev/null; then
use nvm
fi
{
"extends": ["standard"],
"env": {
"es6": true,
"node": true
},
"parserOptions": {
"ecmaVersion": 2017
}
}
# Created by https://www.gitignore.io/api/osx,node
### OSX ###
*.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Node ###
# Logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# IDEs
.idea
# pubsweet-specific
myapp
testapp
.vscode
.wallaby.js
\ No newline at end of file
image: pubsweet/pubsweet-test-base
cache:
paths:
- node_modules/
before_script:
- yarn
test:lint:
script:
- npm run lint
test:vulnerabilities:
script:
- npm run vuln-test
test:node:
script:
- npm test
coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/
publish:
stage: deploy
only:
- tags
- triggers
script:
- echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}'>.npmrc
- npm publish
\ No newline at end of file
7.9
\ No newline at end of file
Copyright (c) 2015 Adam Hyde
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
[![MIT license](https://img.shields.io/badge/license-MIT-e51879.svg)](https://gitlab.coko.foundation/pubsweet/pubsweet-logger/raw/master/LICENSE)
[![npm](https://img.shields.io/npm/v/pubsweet.svg)](https://npmjs.com/package/@pubsweet/logger)
[![build status](https://gitlab.coko.foundation/yld/pubsweet-logger/badges/master/build.svg)](https://gitlab.coko.foundation/yld/pubsweet-logger/commits/master)
[![coverage report](https://gitlab.coko.foundation/yld/pubsweet-logger/badges/master/coverage.svg)](https://gitlab.coko.foundation/yld/pubsweet-logger/commits/master)
[![code style standard](https://img.shields.io/badge/code%20style-standard-green.svg)](https://standardjs.com/)
[![mattermost chat](https://img.shields.io/badge/mattermost_chat-coko%2Fpubsweet-blue.svg)](https://mattermost.coko.foundation/coko/channels/pubsweet)
# @pubsweet/logger
A module encapsulating standard logging features for pubsweet components and services.
## Usage
Either:
```javascript
const myLogger = require('winston') // or something else
const logger = require('@pubsweet/logger')
logger.configure(mylogger)
```
Or set the logger in config:
```javascript
const myLogger = require('winston') // or something else
{
'pubsweet-server':{
logger: myLogger
}
}
```
The configured logger can then be imported from anywhere:
```javascript
const logger = require('@pubsweet/logger')
logger.info('log')
```
The logger exposes the following methods:
- `info`
- `debug`
- `error`
- `warn`
- `configure`
- `getRawLogger` (returns the logger passed to `configure`)
As well as:
- `stream` (an object for passing to `morgan`)
Note that the logger used to configure the module must implement `error`, `warn`, `info` and `debug` functions.
module.exports = {}
{
"name": "@pubsweet/logger",
"version": "0.0.1",
"description": "A module encapsulating standard logging features for pubsweet components and services.",
"main": "src/index.js",
"scripts": {
"test": "jest",
"lint": "eslint src test",
"vuln-test": "nsp check --output checkstyle"
},
"repository": {
"type": "git",
"url": "git@gitlab.coko.foundation:pubsweet/pubsweet-logger.git"
},
"keywords": [
"logger",
"pubsweet"
],
"engines": {
"node": ">=7.9.0",
"npm": ">=3.0.0"
},
"author": "Antony Denyer",
"license": "MIT",
"devDependencies": {
"bunyan": "^1.8.12",
"eslint": "^4.5.0",
"eslint-config-standard": "^10.2.1",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-node": "^5.2.0",
"eslint-plugin-promise": "^3.5.0",
"eslint-plugin-standard": "^3.0.1",
"jest": "^20.0.4",
"nsp": "^2.7.0",
"winston": "^2.3.1"
},
"jest": {
"testMatch": [
"**/test/**/*.js"
],
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*.js"
],
"modulePaths": [
"<rootDir>/node_modules"
],
"testEnvironment": "node",
"verbose": true
},
"dependencies": {
"config": "^1.26.2",
"joi": "^10.6.0",
"lodash": "^4.17.4"
}
}
process.env.SUPPRESS_NO_CONFIG_WARNING = true
const config = require('config')
const validations = require('./validations')
const { get } = require('lodash/fp')
const loggerFromConfig = get('pubsweet-server.logger', config)
config.util.setModuleDefaults('pubsweet-server.logger', loggerFromConfig)
let logger = validations.validateConfig(loggerFromConfig)
let configured = Boolean(logger)
if (!configured) {
global.console.debug = (...args) => global.console.log(args)
logger = global.console
}
module.exports = {
error: (...args) => logger.error(...args),
warn: (...args) => logger.warn(...args),
info: (...args) => logger.info(...args),
debug: (...args) => logger.debug(...args),
stream: {
write: function (message, encoding) {
logger.info(message)
}
},
configure: (theirLogger) => {
if (configured) {
throw new Error('Logger has already been configured')
}
validations.validateConfig(theirLogger)
logger = theirLogger
configured = true
},
getRawLogger: () => logger
}
'use strict'
const Joi = require('joi')
const schema = Joi.object({
error: Joi.func().required(),
warn: Joi.func().required(),
debug: Joi.func().required(),
info: Joi.func().required()
}).optional()
module.exports = {
validateConfig: function validateConfig (config) {
const result = Joi.validate(config, schema, { allowUnknown: true })
if (result.error) throw result.error
return result.value
}
}
{
"env": {
"jest": true
}
}
\ No newline at end of file
'use strict'
process.env.ALLOW_CONFIG_MUTATIONS = true
let config = require('config')
config['pubsweet-server'] = { }
describe('Logging manager', () => {
describe('when no logger is specifed', () => {
it('logs errors to console', () => {
jest.spyOn(global.console, 'error').mockImplementation()
const logger = require('../src/')
logger.error('an error message')
expect(console.error).toHaveBeenCalled()
console.error.mockRestore()
})
it('logs warn to console', () => {
jest.spyOn(global.console, 'warn').mockImplementation()
const logger = require('../src/')
logger.warn('a warn message')
expect(console.warn).toHaveBeenCalled()
console.warn.mockRestore()
})
it('logs info to console', () => {
jest.spyOn(global.console, 'info').mockImplementation()
const logger = require('../src/')
logger.info('an info message')
expect(console.info).toHaveBeenCalled()
console.info.mockRestore()
})
it('logs debug to console', () => {
jest.spyOn(global.console, 'log').mockImplementation()
const logger = require('../src/')
logger.debug('a debug message')
expect(console.log).toHaveBeenCalled()
console.log.mockRestore()
})
it('can stream logs to console', () => {
jest.spyOn(global.console, 'info').mockImplementation()
const logger = require('../src')
logger.stream.write('a stream message')
expect(console.info).toHaveBeenCalled()
console.info.mockRestore()
})
})
describe('when configure method is passed another logger', () => {
it('throws an error if a required method is not implemented', () => {
const logger = require('../src/')
expect.hasAssertions()
// https://github.com/facebook/jest/issues/2124
try {
logger.configure({})
} catch (e) {
expect(e.name).toBe('ValidationError')
}
})
it('works with winston', () => {
const logger = require('../src/')
const winston = require('winston')
jest.spyOn(winston, 'debug').mockImplementation()
jest.spyOn(winston, 'info').mockImplementation()
jest.spyOn(winston, 'warn').mockImplementation()
jest.spyOn(winston, 'error').mockImplementation()
logger.configure(winston)
logger.debug('debug')
expect(winston.debug).toHaveBeenLastCalledWith('debug')
logger.info('info')
expect(winston.info).toHaveBeenLastCalledWith('info')
logger.warn('warn')
expect(winston.warn).toHaveBeenLastCalledWith('warn')
logger.error('error')
expect(winston.error).toHaveBeenLastCalledWith('error')
})
it('works with bunyan', () => {
jest.resetModules()
config = require('config')
const logger = require('../src/')
const bunyan = require('bunyan').createLogger({name: 'test'})
jest.spyOn(bunyan, 'debug').mockImplementation()
jest.spyOn(bunyan, 'info').mockImplementation()
jest.spyOn(bunyan, 'warn').mockImplementation()
jest.spyOn(bunyan, 'error').mockImplementation()
logger.configure(bunyan)
logger.debug('debug')
expect(bunyan.debug).toHaveBeenLastCalledWith('debug')
logger.info('info')
expect(bunyan.info).toHaveBeenLastCalledWith('info')
logger.warn('warn')
expect(bunyan.warn).toHaveBeenLastCalledWith('warn')
logger.error('error')
expect(bunyan.error).toHaveBeenLastCalledWith('error')
})
it('prevents configuration again', () => {
jest.resetModules()
config = require('config')
const logger = require('../src/')
const winston = require('winston')
logger.configure(winston)
expect(() => logger.configure(winston)).toThrow(/already been configured/)
})
})
describe('has getRawLogger method', () => {
it('which returns raw logger', () => {
jest.resetModules()
const logger = require('../src/')
const bunyan = require('bunyan').createLogger({name: 'test'})
logger.configure(bunyan)
const rawLogger = logger.getRawLogger()
expect(rawLogger.fields.name).toBe('test')
})
})
describe('when a logger is passed by config', () => {
it('sets logger to "bunyan" if specified', () => {
jest.resetModules()
config = require('config')
const bunyan = require('bunyan').createLogger({name: 'test'})
config['pubsweet-server'] = { logger: bunyan }
const logger = require('../src/')
const rawLogger = logger.getRawLogger()
expect(rawLogger.fields.name).toBe('test')
})
it('sets logger to "winston" if specified', () => {
jest.resetModules()
config = require('config')
const winston = require('winston')
config['pubsweet-server'] = { logger: winston }
const logger = require('../src/')
const rawLogger = logger.getRawLogger()
expect(rawLogger).toEqual(require('winston'))
})
it('defaults to console', () => {
jest.resetModules()
config = require('config')
config['pubsweet-server'] = {}
const logger = require('../src/')
const rawLogger = logger.getRawLogger()
expect(rawLogger).toEqual(global.console)
})
it('logger passed must be an object', () => {
jest.resetModules()
config = require('config')
config['pubsweet-server'] = { logger: 'wiiiiiiiiinston' }
expect.hasAssertions()
try {
require('../src/')
} catch (e) {
expect(e.name).toBe('ValidationError')
}
})
it('prevents configuration again', () => {
jest.resetModules()
config = require('config')
const winston = require('winston')
config['pubsweet-server'] = { logger: winston }
const logger = require('../src/')
expect(() => logger.configure(winston)).toThrow(/already been configured/)
})
})
})
This diff is collapsed.
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment