mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-04 00:18:01 +01:00
Implement support for logger provider.
This allows the users of 'unleash-server' to programatically change the logger implemnentation. #175
This commit is contained in:
parent
a70f7f7046
commit
f5e9ca3bbe
@ -37,4 +37,37 @@ Available unleash options includes:
|
||||
|
||||
- databaseUrl
|
||||
- port
|
||||
- logLevel - ('INFO', 'ERROR',)
|
||||
|
||||
## How do I configure the log output?
|
||||
|
||||
By default, `unleash` uses [log4js](https://github.com/nomiddlename/log4js-node) to log important information. It is possible to swap out the logger provider (only when using Unleash programatically). This enables filtering of log levels and easy redirection of output streams.
|
||||
|
||||
### What is a logger provider?
|
||||
|
||||
A logger provider is a function which takes the name of a logger and returns a logger implementation. For instance, the following code snippet shows how a logger provider for the global `console` object could be written:
|
||||
|
||||
```javascript
|
||||
function consoleLoggerProvider (name) {
|
||||
// do something with the name
|
||||
return {
|
||||
debug: console.debug.bind(console),
|
||||
info: console.info.bind(console),
|
||||
warn: console.warn.bind(console),
|
||||
error: console.error.bind(console)
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
The logger interface with its `debug`, `info`, `warn` and `error` methods expects format string support as seen in `debug` or the JavaScript `console` object. Many commonly used logging implementations cover this API, e.g. bunyan, pino or winston.
|
||||
|
||||
### How do I set a logger provider?
|
||||
|
||||
Custom logger providers need to be set *before requiring the `unleash-server` module*. The following example shows how this can be done:
|
||||
|
||||
```javascript
|
||||
// first configure the logger provider
|
||||
const unleashLogger = require('unleash-server/logger');
|
||||
unleashLogger.setLoggerProvider(consoleLoggerProvider);
|
||||
|
||||
// then require unleash-server and continue as normal
|
||||
const unleash = require('unleash-server');
|
13
lib/app.js
13
lib/app.js
@ -6,8 +6,7 @@ const bodyParser = require('body-parser');
|
||||
const cookieParser = require('cookie-parser');
|
||||
const validator = require('express-validator');
|
||||
const responseTime = require('response-time');
|
||||
const log4js = require('log4js');
|
||||
const logger = require('./logger');
|
||||
const logger = require('./logger')('app.js');
|
||||
const routes = require('./routes');
|
||||
const path = require('path');
|
||||
const errorHandler = require('errorhandler');
|
||||
@ -56,12 +55,10 @@ module.exports = function(config) {
|
||||
app.use(bodyParser.json({ strict: false }));
|
||||
|
||||
if (config.enableRequestLogger) {
|
||||
app.use(
|
||||
log4js.connectLogger(logger, {
|
||||
format: ':status :method :url :response-timems',
|
||||
level: 'auto', // 3XX=WARN, 4xx/5xx=ERROR
|
||||
})
|
||||
);
|
||||
app.use((req, res, next) => {
|
||||
next();
|
||||
logger.info(`${res.statusCode} ${req.method} ${req.path}`);
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof config.preRouterHook === 'function') {
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* eslint camelcase: "off" */
|
||||
'use strict';
|
||||
|
||||
const logger = require('../logger');
|
||||
const logger = require('../logger')('client-instance-store.js');
|
||||
const COLUMNS = [
|
||||
'app_name',
|
||||
'instance_id',
|
||||
|
@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const logger = require('../logger');
|
||||
const logger = require('../logger')('client-metrics-db.js');
|
||||
|
||||
const METRICS_COLUMNS = ['id', 'created_at', 'metrics'];
|
||||
const TABLE = 'client_metrics';
|
||||
|
@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const logger = require('../logger');
|
||||
const logger = require('../logger')('client-metrics-store.js');
|
||||
|
||||
const { EventEmitter } = require('events');
|
||||
|
||||
|
@ -6,7 +6,7 @@ const {
|
||||
FEATURE_ARCHIVED,
|
||||
FEATURE_REVIVED,
|
||||
} = require('../event-type');
|
||||
const logger = require('../logger');
|
||||
const logger = require('../logger')('client-toggle-store.js');
|
||||
const NotFoundError = require('../error/notfound-error');
|
||||
const FEATURE_COLUMNS = [
|
||||
'name',
|
||||
|
@ -5,7 +5,7 @@ const {
|
||||
STRATEGY_DELETED,
|
||||
STRATEGY_UPDATED,
|
||||
} = require('../event-type');
|
||||
const logger = require('../logger');
|
||||
const logger = require('../logger')('strategy-store.js');
|
||||
const NotFoundError = require('../error/notfound-error');
|
||||
const STRATEGY_COLUMNS = ['name', 'description', 'parameters', 'built_in'];
|
||||
const TABLE = 'strategies';
|
||||
|
@ -3,11 +3,6 @@
|
||||
const { test } = require('ava');
|
||||
const eventDiffer = require('./event-differ');
|
||||
const { FEATURE_CREATED, FEATURE_UPDATED } = require('./event-type');
|
||||
const logger = require('./logger');
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
test('fails if events include an unknown event type', t => {
|
||||
const events = [
|
||||
|
@ -1,19 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
const log4js = require('log4js');
|
||||
log4js.configure({
|
||||
appenders: [{ type: 'console' }],
|
||||
});
|
||||
|
||||
const logger = log4js.getLogger('unleash');
|
||||
let loggerProvider = getDefaultLogProvider();
|
||||
|
||||
// TODO: make level configurable
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
logger.setLevel(log4js.levels.ERROR);
|
||||
} else if (process.env.NODE_ENV === 'test') {
|
||||
logger.setLevel(log4js.levels.ERROR);
|
||||
} else {
|
||||
logger.setLevel(log4js.levels.DEBUG);
|
||||
module.exports = exports = function getLogger(name) {
|
||||
return loggerProvider(name);
|
||||
};
|
||||
|
||||
exports.setLoggerProvider = function setLoggerProvider(provider) {
|
||||
loggerProvider = provider;
|
||||
};
|
||||
|
||||
function getDefaultLogProvider() {
|
||||
let level;
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
level = log4js.levels.ERROR;
|
||||
} else if (process.env.NODE_ENV === 'test') {
|
||||
level = log4js.levels.FATAL;
|
||||
} else {
|
||||
level = log4js.levels.DEBUG;
|
||||
}
|
||||
|
||||
log4js.configure({
|
||||
appenders: [{ type: 'console' }],
|
||||
levels: {
|
||||
'[all]': level,
|
||||
},
|
||||
});
|
||||
|
||||
return log4js.getLogger;
|
||||
}
|
||||
|
||||
module.exports = logger;
|
||||
|
22
lib/logger.test.js
Normal file
22
lib/logger.test.js
Normal file
@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
const { test } = require('ava');
|
||||
const createLogger = require('./logger');
|
||||
const logger = require('../logger');
|
||||
const sinon = require('sinon');
|
||||
|
||||
test('should expose a setLoggerProvider function', t => {
|
||||
t.true(logger.setLoggerProvider instanceof Function);
|
||||
});
|
||||
|
||||
test('should create logger via custom logger provider', t => {
|
||||
const provider = sinon.stub();
|
||||
const loggerName = 'test';
|
||||
const loggerImpl = {};
|
||||
provider.withArgs(loggerName).returns(loggerImpl);
|
||||
logger.setLoggerProvider(provider);
|
||||
|
||||
const log = createLogger(loggerName);
|
||||
|
||||
t.is(log, loggerImpl);
|
||||
});
|
@ -3,16 +3,11 @@
|
||||
const { test } = require('ava');
|
||||
const store = require('./../../../test/fixtures/store');
|
||||
const supertest = require('supertest');
|
||||
const logger = require('../../logger');
|
||||
const getApp = require('../../app');
|
||||
|
||||
const { EventEmitter } = require('events');
|
||||
const eventBus = new EventEmitter();
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
function getSetup() {
|
||||
const stores = store.createStores();
|
||||
const app = getApp({
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
const { Router } = require('express');
|
||||
|
||||
const logger = require('../../logger');
|
||||
const logger = require('../../logger')('/admin-api/archive.js');
|
||||
const { FEATURE_REVIVED } = require('../../event-type');
|
||||
const ValidationError = require('../../error/validation-error');
|
||||
const validateRequest = require('../../error/validate-request');
|
||||
|
@ -4,7 +4,6 @@ const { test } = require('ava');
|
||||
|
||||
const store = require('./../../../test/fixtures/store');
|
||||
const supertest = require('supertest');
|
||||
const logger = require('../../logger');
|
||||
const getApp = require('../../app');
|
||||
|
||||
const { EventEmitter } = require('events');
|
||||
@ -22,10 +21,6 @@ function getSetup() {
|
||||
return { base, eventStore: stores.eventStore, request: supertest(app) };
|
||||
}
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
test('should get empty events list via admin', t => {
|
||||
t.plan(1);
|
||||
const { request, base } = getSetup();
|
||||
|
@ -3,7 +3,7 @@
|
||||
const { Router } = require('express');
|
||||
const joi = require('joi');
|
||||
|
||||
const logger = require('../../logger');
|
||||
const logger = require('../../logger')('/admin-api/feature.js');
|
||||
const {
|
||||
FEATURE_CREATED,
|
||||
FEATURE_UPDATED,
|
||||
|
@ -3,16 +3,11 @@
|
||||
const { test } = require('ava');
|
||||
const store = require('./../../../test/fixtures/store');
|
||||
const supertest = require('supertest');
|
||||
const logger = require('../../logger');
|
||||
const getApp = require('../../app');
|
||||
|
||||
const { EventEmitter } = require('events');
|
||||
const eventBus = new EventEmitter();
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
function getSetup() {
|
||||
const base = `/random${Math.round(Math.random() * 1000)}`;
|
||||
const stores = store.createStores();
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
const { Router } = require('express');
|
||||
|
||||
const logger = require('../../logger');
|
||||
const logger = require('../../logger')('/admin-api/metrics.js');
|
||||
const ClientMetrics = require('../../client-metrics');
|
||||
const { catchLogAndSendErrorResponse } = require('./route-utils');
|
||||
|
||||
|
@ -3,16 +3,11 @@
|
||||
const { test } = require('ava');
|
||||
const store = require('./../../../test/fixtures/store');
|
||||
const supertest = require('supertest');
|
||||
const logger = require('../../logger');
|
||||
const getApp = require('../../app');
|
||||
|
||||
const { EventEmitter } = require('events');
|
||||
const eventBus = new EventEmitter();
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
function getSetup() {
|
||||
const stores = store.createStores();
|
||||
const app = getApp({
|
||||
|
@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const logger = require('../../logger');
|
||||
const logger = require('../../logger')('route-utils.js');
|
||||
|
||||
const catchLogAndSendErrorResponse = (err, res) => {
|
||||
logger.error(err);
|
||||
|
@ -4,7 +4,7 @@ const { Router } = require('express');
|
||||
const joi = require('joi');
|
||||
|
||||
const eventType = require('../../event-type');
|
||||
const logger = require('../../logger');
|
||||
const logger = require('../../logger')('/admin-api/strategy.js');
|
||||
const NameExistsError = require('../../error/name-exists-error');
|
||||
const extractUser = require('../../extract-user');
|
||||
const strategySchema = require('./strategy-schema');
|
||||
|
@ -4,7 +4,6 @@ const { test } = require('ava');
|
||||
const store = require('./../../../test/fixtures/store');
|
||||
const supertest = require('supertest');
|
||||
const getApp = require('../../app');
|
||||
const logger = require('../../logger');
|
||||
|
||||
const { EventEmitter } = require('events');
|
||||
const eventBus = new EventEmitter();
|
||||
@ -25,10 +24,6 @@ function getSetup() {
|
||||
};
|
||||
}
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
test('add version numbers for /stategies', t => {
|
||||
t.plan(1);
|
||||
const { request, base } = getSetup();
|
||||
|
@ -3,16 +3,11 @@
|
||||
const { test } = require('ava');
|
||||
const store = require('./../../test/fixtures/store');
|
||||
const supertest = require('supertest');
|
||||
const logger = require('../logger');
|
||||
const getApp = require('../app');
|
||||
|
||||
const { EventEmitter } = require('events');
|
||||
const eventBus = new EventEmitter();
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
test('should use enable prometheus', t => {
|
||||
t.plan(0);
|
||||
const stores = store.createStores();
|
||||
|
@ -3,16 +3,11 @@
|
||||
const { test } = require('ava');
|
||||
const store = require('./../../../test/fixtures/store');
|
||||
const supertest = require('supertest');
|
||||
const logger = require('../../logger');
|
||||
const getApp = require('../../app');
|
||||
|
||||
const { EventEmitter } = require('events');
|
||||
const eventBus = new EventEmitter();
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
function getSetup() {
|
||||
const base = `/random${Math.round(Math.random() * 1000)}`;
|
||||
const stores = store.createStores();
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
const { Router } = require('express');
|
||||
const joi = require('joi');
|
||||
const logger = require('../../logger');
|
||||
const logger = require('../../logger')('client-api/metrics.js');
|
||||
|
||||
const { clientMetricsSchema } = require('./metrics-schema');
|
||||
|
||||
|
@ -3,16 +3,11 @@
|
||||
const { test } = require('ava');
|
||||
const store = require('./../../../test/fixtures/store');
|
||||
const supertest = require('supertest');
|
||||
const logger = require('../../logger');
|
||||
const getApp = require('../../app');
|
||||
|
||||
const { EventEmitter } = require('events');
|
||||
const eventBus = new EventEmitter();
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
function getSetup() {
|
||||
const stores = store.createStores();
|
||||
const app = getApp({
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
const { Router } = require('express');
|
||||
const joi = require('joi');
|
||||
const logger = require('../../logger');
|
||||
const logger = require('../../logger')('/client-api/register.js');
|
||||
|
||||
const { clientRegisterSchema } = require('./register-schema');
|
||||
|
||||
|
@ -3,16 +3,11 @@
|
||||
const { test } = require('ava');
|
||||
const store = require('./../../../test/fixtures/store');
|
||||
const supertest = require('supertest');
|
||||
const logger = require('../../logger');
|
||||
const getApp = require('../../app');
|
||||
|
||||
const { EventEmitter } = require('events');
|
||||
const eventBus = new EventEmitter();
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
function getSetup() {
|
||||
const stores = store.createStores();
|
||||
const app = getApp({
|
||||
|
@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const logger = require('../logger');
|
||||
const logger = require('../logger')('health-check.js');
|
||||
const { Router } = require('express');
|
||||
|
||||
exports.router = function(config) {
|
||||
|
@ -3,16 +3,11 @@
|
||||
const { test } = require('ava');
|
||||
const store = require('./../../test/fixtures/store');
|
||||
const supertest = require('supertest');
|
||||
const logger = require('../logger');
|
||||
const getApp = require('../app');
|
||||
|
||||
const { EventEmitter } = require('events');
|
||||
const eventBus = new EventEmitter();
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
function getSetup() {
|
||||
const stores = store.createStores();
|
||||
const db = stores.db;
|
||||
|
@ -3,16 +3,11 @@
|
||||
const { test } = require('ava');
|
||||
const store = require('./../../test/fixtures/store');
|
||||
const supertest = require('supertest');
|
||||
const logger = require('../logger');
|
||||
const getApp = require('../app');
|
||||
|
||||
const { EventEmitter } = require('events');
|
||||
const eventBus = new EventEmitter();
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
function getSetup() {
|
||||
const base = `/random${Math.round(Math.random() * 1000)}`;
|
||||
const stores = store.createStores();
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
const { EventEmitter } = require('events');
|
||||
|
||||
const logger = require('./logger');
|
||||
const logger = require('./logger')('server-impl.js');
|
||||
const migrator = require('../migrator');
|
||||
const getApp = require('./app');
|
||||
|
||||
|
5
logger.js
Normal file
5
logger.js
Normal file
@ -0,0 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const logger = require('./lib/logger');
|
||||
|
||||
exports.setLoggerProvider = logger.setLoggerProvider;
|
@ -39,7 +39,7 @@
|
||||
"db-migrate": "db-migrate",
|
||||
"lint": "eslint .",
|
||||
"pretest": "npm run lint",
|
||||
"test": "PORT=4243 ava lib/*.test.js lib/**/*.test.js lib/**/**/*.test.js lib/**/**/**/*.test.js test",
|
||||
"test": "NODE_ENV=test PORT=4243 ava lib/*.test.js lib/**/*.test.js lib/**/**/*.test.js lib/**/**/**/*.test.js test",
|
||||
"test:docker": "./scripts/docker-postgres.sh",
|
||||
"test:watch": "npm run test -- --watch",
|
||||
"test:pg-virtualenv": "pg_virtualenv npm run test:pg-virtualenv-chai",
|
||||
|
@ -2,11 +2,6 @@
|
||||
|
||||
const { test } = require('ava');
|
||||
const { setupApp } = require('./../../helpers/test-helper');
|
||||
const logger = require('../../../../lib/logger');
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
test.serial('returns events', async t => {
|
||||
t.plan(0);
|
||||
|
@ -2,11 +2,6 @@
|
||||
|
||||
const { test } = require('ava');
|
||||
const { setupApp } = require('./../../helpers/test-helper');
|
||||
const logger = require('../../../../lib/logger');
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
test.serial('returns three archived toggles', async t => {
|
||||
t.plan(1);
|
||||
|
@ -2,11 +2,6 @@
|
||||
|
||||
const { test } = require('ava');
|
||||
const { setupApp } = require('./../../helpers/test-helper');
|
||||
const logger = require('../../../../lib/logger');
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
test.serial('returns three feature toggles', async t => {
|
||||
const { request, destroy } = await setupApp('feature_api_serial');
|
||||
|
@ -2,11 +2,6 @@
|
||||
|
||||
const { test } = require('ava');
|
||||
const { setupApp } = require('./../../helpers/test-helper');
|
||||
const logger = require('../../../../lib/logger');
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
test.serial('should register client', async t => {
|
||||
t.plan(0);
|
||||
|
@ -2,11 +2,6 @@
|
||||
|
||||
const { test } = require('ava');
|
||||
const { setupApp } = require('./../../helpers/test-helper');
|
||||
const logger = require('../../../../lib/logger');
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
test.serial('gets all strategies', async t => {
|
||||
t.plan(1);
|
||||
|
@ -2,11 +2,6 @@
|
||||
|
||||
const { test } = require('ava');
|
||||
const { setupApp } = require('./helpers/test-helper');
|
||||
const logger = require('../../lib/logger');
|
||||
|
||||
test.beforeEach(() => {
|
||||
logger.setLevel('FATAL');
|
||||
});
|
||||
|
||||
test('returns health good', async t => {
|
||||
t.plan(0);
|
||||
|
Loading…
Reference in New Issue
Block a user