1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-04-19 01:17:18 +02:00

fix: LogProvider as option injected to unleash.

Instead of instructing users to do static calls
in to Unleash, she should instead be allwed to
specify the log provider as an option to Unleash.

This commit introduces the "getLogger" option,
a function responsible for creating a logger.
This commit is contained in:
ivaosthu 2019-04-30 21:14:23 +02:00 committed by Ivar Conradi Østhus
parent 4410d5389b
commit de16a7854d
46 changed files with 167 additions and 138 deletions

View File

@ -58,6 +58,7 @@ Available unleash options include:
- `unsecure` - (default) will use simple cookie based authentication. UI will require the user to specify an email in order to use unleash. - `unsecure` - (default) will use simple cookie based authentication. UI will require the user to specify an email in order to use unleash.
- `custom` - use this when you implement your own custom authentication logic. - `custom` - use this when you implement your own custom authentication logic.
- **ui** (object) - Set of UI specific overrides. You may set the following keys: `headerBackground`, `environment`, `slogan`. - **ui** (object) - Set of UI specific overrides. You may set the following keys: `headerBackground`, `environment`, `slogan`.
- **getLogger** (function) - Used to register a [custom log provider](#How do I configure the log output).
### 3. Docker ### 3. Docker
@ -69,14 +70,10 @@ docker run -d -e DATABASE_URL=postgres://user:pass@10.200.221.11:5432/unleash un
## How do I configure the log output? ## 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 programmatically). This enables filtering of log levels and easy redirection of output streams. 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 programmatically). You do this by providing an implementation of the **getLogger** function as 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 ```javascript
function consoleLoggerProvider(name) { function getLogger(name) {
// do something with the name // do something with the name
return { return {
debug: console.log, debug: console.log,
@ -88,16 +85,3 @@ function consoleLoggerProvider(name) {
``` ```
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. 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/lib/logger');
unleashLogger.setLoggerProvider(consoleLoggerProvider);
// then require unleash-server and continue as normal
const unleash = require('unleash-server');
```

View File

@ -3,6 +3,7 @@
const test = require('ava'); const test = require('ava');
const express = require('express'); const express = require('express');
const proxyquire = require('proxyquire'); const proxyquire = require('proxyquire');
const getLogger = require('../test/fixtures/no-logger');
const getApp = proxyquire('./app', { const getApp = proxyquire('./app', {
'./routes': class Index { './routes': class Index {
router() { router() {
@ -12,13 +13,14 @@ const getApp = proxyquire('./app', {
}); });
test('should not throw when valid config', t => { test('should not throw when valid config', t => {
const app = getApp({}); const app = getApp({ getLogger });
t.true(typeof app.listen === 'function'); t.true(typeof app.listen === 'function');
}); });
test('should call preHook', t => { test('should call preHook', t => {
let called = 0; let called = 0;
getApp({ getApp({
getLogger,
preHook: () => { preHook: () => {
called++; called++;
}, },
@ -29,6 +31,7 @@ test('should call preHook', t => {
test('should call preRouterHook', t => { test('should call preRouterHook', t => {
let called = 0; let called = 0;
getApp({ getApp({
getLogger,
preRouterHook: () => { preRouterHook: () => {
called++; called++;
}, },

View File

@ -1,7 +1,6 @@
/* eslint camelcase: "off" */ /* eslint camelcase: "off" */
'use strict'; 'use strict';
const logger = require('../logger')('client-instance-store.js');
const COLUMNS = [ const COLUMNS = [
'app_name', 'app_name',
'instance_id', 'instance_id',
@ -24,8 +23,9 @@ const mapRow = row => ({
}); });
class ClientInstanceStore { class ClientInstanceStore {
constructor(db) { constructor(db, getLogger) {
this.db = db; this.db = db;
this.logger = getLogger('client-instance-store.js');
const clearer = () => this._removeInstancesOlderThanTwoDays(); const clearer = () => this._removeInstancesOlderThanTwoDays();
setTimeout(clearer, 10).unref(); setTimeout(clearer, 10).unref();
setInterval(clearer, ONE_DAY).unref(); setInterval(clearer, ONE_DAY).unref();
@ -35,7 +35,9 @@ class ClientInstanceStore {
this.db(TABLE) this.db(TABLE)
.whereRaw("created_at < now() - interval '2 days'") .whereRaw("created_at < now() - interval '2 days'")
.del() .del()
.then(res => res > 0 && logger.info(`Deleted ${res} instances`)); .then(
res => res > 0 && this.logger.info(`Deleted ${res} instances`)
);
} }
updateRow(details) { updateRow(details) {

View File

@ -1,7 +1,5 @@
'use strict'; 'use strict';
const logger = require('../logger')('client-metrics-db.js');
const METRICS_COLUMNS = ['id', 'created_at', 'metrics']; const METRICS_COLUMNS = ['id', 'created_at', 'metrics'];
const TABLE = 'client_metrics'; const TABLE = 'client_metrics';
@ -14,8 +12,9 @@ const mapRow = row => ({
}); });
class ClientMetricsDb { class ClientMetricsDb {
constructor(db) { constructor(db, getLogger) {
this.db = db; this.db = db;
this.logger = getLogger('client-metrics-db.js');
// Clear old metrics regulary // Clear old metrics regulary
const clearer = () => this.removeMetricsOlderThanOneHour(); const clearer = () => this.removeMetricsOlderThanOneHour();
@ -27,7 +26,7 @@ class ClientMetricsDb {
this.db(TABLE) this.db(TABLE)
.whereRaw("created_at < now() - interval '1 hour'") .whereRaw("created_at < now() - interval '1 hour'")
.del() .del()
.then(res => res > 0 && logger.info(`Deleted ${res} metrics`)); .then(res => res > 0 && this.logger.info(`Deleted ${res} metrics`));
} }
// Insert new client metrics // Insert new client metrics

View File

@ -1,14 +1,13 @@
'use strict'; 'use strict';
const logger = require('../logger')('client-metrics-store.js');
const { EventEmitter } = require('events'); const { EventEmitter } = require('events');
const TEN_SECONDS = 10 * 1000; const TEN_SECONDS = 10 * 1000;
class ClientMetricsStore extends EventEmitter { class ClientMetricsStore extends EventEmitter {
constructor(metricsDb, pollInterval = TEN_SECONDS) { constructor(metricsDb, getLogger, pollInterval = TEN_SECONDS) {
super(); super();
this.logger = getLogger('client-metrics-store.js');
this.metricsDb = metricsDb; this.metricsDb = metricsDb;
this.highestIdSeen = 0; this.highestIdSeen = 0;
@ -20,7 +19,7 @@ class ClientMetricsStore extends EventEmitter {
const metrics = await this.metricsDb.getMetricsLastHour(); const metrics = await this.metricsDb.getMetricsLastHour();
this._emitMetrics(metrics); this._emitMetrics(metrics);
} catch (err) { } catch (err) {
logger.error('Error fetching metrics last hour', err); this.logger.error('Error fetching metrics last hour', err);
} }
this._startPoller(pollInterval); this._startPoller(pollInterval);
this.emit('ready'); this.emit('ready');

View File

@ -3,6 +3,7 @@
const test = require('ava'); const test = require('ava');
const ClientMetricStore = require('./client-metrics-store'); const ClientMetricStore = require('./client-metrics-store');
const lolex = require('lolex'); const lolex = require('lolex');
const getLogger = require('../../test/fixtures/no-logger');
function getMockDb() { function getMockDb() {
const list = [ const list = [
@ -24,7 +25,7 @@ function getMockDb() {
test.cb('should call database on startup', t => { test.cb('should call database on startup', t => {
const mock = getMockDb(); const mock = getMockDb();
const store = new ClientMetricStore(mock); const store = new ClientMetricStore(mock, getLogger);
t.plan(2); t.plan(2);
@ -42,7 +43,7 @@ test.cb('should start poller even if inital database fetch fails', t => {
const mock = getMockDb(); const mock = getMockDb();
mock.getMetricsLastHour = () => Promise.reject('oops'); mock.getMetricsLastHour = () => Promise.reject('oops');
const store = new ClientMetricStore(mock, 100); const store = new ClientMetricStore(mock, getLogger, 100);
const metrics = []; const metrics = [];
store.on('metrics', m => metrics.push(m)); store.on('metrics', m => metrics.push(m));
@ -63,7 +64,7 @@ test.cb('should poll for updates', t => {
const clock = lolex.install(); const clock = lolex.install();
const mock = getMockDb(); const mock = getMockDb();
const store = new ClientMetricStore(mock, 100); const store = new ClientMetricStore(mock, getLogger, 100);
const metrics = []; const metrics = [];
store.on('metrics', m => metrics.push(m)); store.on('metrics', m => metrics.push(m));

View File

@ -8,7 +8,6 @@ const {
FEATURE_IMPORT, FEATURE_IMPORT,
DROP_FEATURES, DROP_FEATURES,
} = require('../event-type'); } = require('../event-type');
const logger = require('../logger')('client-toggle-store.js');
const NotFoundError = require('../error/notfound-error'); const NotFoundError = require('../error/notfound-error');
const FEATURE_COLUMNS = [ const FEATURE_COLUMNS = [
'name', 'name',
@ -21,8 +20,9 @@ const FEATURE_COLUMNS = [
const TABLE = 'features'; const TABLE = 'features';
class FeatureToggleStore { class FeatureToggleStore {
constructor(db, eventStore) { constructor(db, eventStore, getLogger) {
this.db = db; this.db = db;
this.getLogger = getLogger('client-toggle-store.js');
eventStore.on(FEATURE_CREATED, event => eventStore.on(FEATURE_CREATED, event =>
this._createFeature(event.data) this._createFeature(event.data)
); );
@ -111,7 +111,7 @@ class FeatureToggleStore {
return this.db(TABLE) return this.db(TABLE)
.insert(this.eventDataToRow(data)) .insert(this.eventDataToRow(data))
.catch(err => .catch(err =>
logger.error('Could not insert feature, error was: ', err) this.logger.error('Could not insert feature, error: ', err)
); );
} }
@ -120,7 +120,7 @@ class FeatureToggleStore {
.where({ name: data.name }) .where({ name: data.name })
.update(this.eventDataToRow(data)) .update(this.eventDataToRow(data))
.catch(err => .catch(err =>
logger.error('Could not update feature, error was: ', err) this.logger.error('Could not update feature, error: ', err)
); );
} }
@ -129,7 +129,7 @@ class FeatureToggleStore {
.where({ name }) .where({ name })
.update({ archived: 1, enabled: 0 }) .update({ archived: 1, enabled: 0 })
.catch(err => { .catch(err => {
logger.error('Could not archive feature, error was: ', err); this.logger.error('Could not archive feature, error: ', err);
}); });
} }
@ -138,7 +138,7 @@ class FeatureToggleStore {
.where({ name }) .where({ name })
.update({ archived: 0, enabled: 0 }) .update({ archived: 0, enabled: 0 })
.catch(err => .catch(err =>
logger.error('Could not archive feature, error was: ', err) this.logger.error('Could not archive feature, error: ', err)
); );
} }
@ -151,7 +151,7 @@ class FeatureToggleStore {
result === 0 ? this.db(TABLE).insert(rowData) : result result === 0 ? this.db(TABLE).insert(rowData) : result
) )
.catch(err => .catch(err =>
logger.error('Could not import feature, error was: ', err) this.logger.error('Could not import feature, error: ', err)
); );
} }
@ -159,7 +159,7 @@ class FeatureToggleStore {
return this.db(TABLE) return this.db(TABLE)
.delete() .delete()
.catch(err => .catch(err =>
logger.error('Could not drop features, error was: ', err) this.logger.error('Could not drop features, error: ', err)
); );
} }
} }

View File

@ -10,17 +10,18 @@ const ClientMetricsStore = require('./client-metrics-store');
const ClientApplicationsStore = require('./client-applications-store'); const ClientApplicationsStore = require('./client-applications-store');
module.exports.createStores = config => { module.exports.createStores = config => {
const getLogger = config.getLogger;
const db = createDb(config); const db = createDb(config);
const eventStore = new EventStore(db); const eventStore = new EventStore(db, getLogger);
const clientMetricsDb = new ClientMetricsDb(db); const clientMetricsDb = new ClientMetricsDb(db, getLogger);
return { return {
db, db,
eventStore, eventStore,
featureToggleStore: new FeatureToggleStore(db, eventStore), featureToggleStore: new FeatureToggleStore(db, eventStore, getLogger),
strategyStore: new StrategyStore(db, eventStore), strategyStore: new StrategyStore(db, eventStore, getLogger),
clientApplicationsStore: new ClientApplicationsStore(db), clientApplicationsStore: new ClientApplicationsStore(db, getLogger),
clientInstanceStore: new ClientInstanceStore(db), clientInstanceStore: new ClientInstanceStore(db, getLogger),
clientMetricsStore: new ClientMetricsStore(clientMetricsDb), clientMetricsStore: new ClientMetricsStore(clientMetricsDb, getLogger),
}; };
}; };

View File

@ -7,14 +7,14 @@ const {
STRATEGY_IMPORT, STRATEGY_IMPORT,
DROP_STRATEGIES, DROP_STRATEGIES,
} = require('../event-type'); } = require('../event-type');
const logger = require('../logger')('strategy-store.js');
const NotFoundError = require('../error/notfound-error'); const NotFoundError = require('../error/notfound-error');
const STRATEGY_COLUMNS = ['name', 'description', 'parameters', 'built_in']; const STRATEGY_COLUMNS = ['name', 'description', 'parameters', 'built_in'];
const TABLE = 'strategies'; const TABLE = 'strategies';
class StrategyStore { class StrategyStore {
constructor(db, eventStore) { constructor(db, eventStore, getLogger) {
this.db = db; this.db = db;
this.logger = getLogger('strategy-store.js');
eventStore.on(STRATEGY_CREATED, event => eventStore.on(STRATEGY_CREATED, event =>
this._createStrategy(event.data) this._createStrategy(event.data)
); );
@ -90,7 +90,7 @@ class StrategyStore {
this.db(TABLE) this.db(TABLE)
.insert(this.eventDataToRow(data)) .insert(this.eventDataToRow(data))
.catch(err => .catch(err =>
logger.error('Could not insert strategy, error was: ', err) this.logger.error('Could not insert strategy, error: ', err)
); );
} }
@ -99,7 +99,7 @@ class StrategyStore {
.where({ name: data.name }) .where({ name: data.name })
.update(this.eventDataToRow(data)) .update(this.eventDataToRow(data))
.catch(err => .catch(err =>
logger.error('Could not update strategy, error was: ', err) this.logger.error('Could not update strategy, error: ', err)
); );
} }
@ -108,7 +108,7 @@ class StrategyStore {
.where({ name }) .where({ name })
.del() .del()
.catch(err => { .catch(err => {
logger.error('Could not delete strategy, error was: ', err); this.logger.error('Could not delete strategy, error: ', err);
}); });
} }
@ -121,7 +121,7 @@ class StrategyStore {
result === 0 ? this.db(TABLE).insert(rowData) : result result === 0 ? this.db(TABLE).insert(rowData) : result
) )
.catch(err => .catch(err =>
logger.error('Could not import strategy, error was: ', err) this.logger.error('Could not import strategy, error: ', err)
); );
} }
@ -130,7 +130,7 @@ class StrategyStore {
.where({ built_in: 0 }) // eslint-disable-line .where({ built_in: 0 }) // eslint-disable-line
.delete() .delete()
.catch(err => .catch(err =>
logger.error('Could not drop strategies, error was: ', err) this.logger.error('Could not drop strategies, error: ', err)
); );
} }
} }

View File

@ -4,22 +4,27 @@ const log4js = require('log4js');
let loggerProvider = getDefaultLogProvider(); let loggerProvider = getDefaultLogProvider();
module.exports = exports = function getLogger(name) { module.exports.defaultLogProvider = loggerProvider;
return loggerProvider(name);
};
exports.setLoggerProvider = function setLoggerProvider(provider) { function validateLogProvider(provider) {
validate(typeof provider == 'function', 'Provider needs to be a function'); validate(typeof provider == 'function', 'Provider needs to be a function');
const logger = provider('unleash:logger'); const logger = provider('unleash:logger');
validate(typeof logger.debug == 'function', 'Logger must implement debug'); validate(typeof logger.debug == 'function', 'Logger must implement debug');
validate(typeof logger.info == 'function', 'Logger must implement info'); validate(typeof logger.info == 'function', 'Logger must implement info');
validate(typeof logger.warn == 'function', 'Logger must implement warn'); validate(typeof logger.warn == 'function', 'Logger must implement warn');
validate(typeof logger.error == 'function', 'Logger must implement error'); validate(typeof logger.error == 'function', 'Logger must implement error');
}
exports.validateLogProvider = validateLogProvider;
// Deprecated
exports.setLoggerProvider = function setLoggerProvider(provider) {
validateLogProvider(provider);
loggerProvider = provider; loggerProvider = provider;
logger.info('Custom Logger Provider initalized.'); const logger = provider('unleash:logger');
logger.info(`Your way of configuring a logProvider is depreacted.
See https://unleash.github.io/docs/getting_started for details`);
}; };
function getDefaultLogProvider() { function getDefaultLogProvider() {

View File

@ -1,29 +1,12 @@
'use strict'; 'use strict';
const test = require('ava'); const test = require('ava');
const createLogger = require('./logger'); const logger = require('./logger');
const logger = require('../logger');
test('should expose a setLoggerProvider function', t => { test('should expose a setLoggerProvider function', t => {
t.true(logger.setLoggerProvider instanceof Function); t.true(logger.setLoggerProvider instanceof Function);
}); });
test('should create logger via custom logger provider', t => {
const loggerName = 'test';
const loggerImpl = {
debug: () => {},
info: () => {},
warn: () => {},
error: () => {},
};
const provider = () => loggerImpl;
logger.setLoggerProvider(provider);
const log = createLogger(loggerName);
t.is(log, loggerImpl);
});
test('should require custom logger to implement info', t => { test('should require custom logger to implement info', t => {
const loggerImpl = { const loggerImpl = {
debug: () => {}, debug: () => {},

View File

@ -5,6 +5,7 @@ const store = require('../../test/fixtures/store');
const checkPermission = require('./permission-checker'); const checkPermission = require('./permission-checker');
const supertest = require('supertest'); const supertest = require('supertest');
const getApp = require('../app'); const getApp = require('../app');
const getLogger = require('../../test/fixtures/no-logger');
const { EventEmitter } = require('events'); const { EventEmitter } = require('events');
const eventBus = new EventEmitter(); const eventBus = new EventEmitter();
@ -16,6 +17,7 @@ function getSetup(preRouterHook) {
baseUriPath: base, baseUriPath: base,
stores, stores,
eventBus, eventBus,
getLogger,
preRouterHook(_app) { preRouterHook(_app) {
preRouterHook(_app); preRouterHook(_app);

View File

@ -1,9 +1,9 @@
'use strict'; 'use strict';
const url = require('url'); const url = require('url');
const logger = require('../logger')('HTTP');
module.exports = function(config) { module.exports = function(config) {
const logger = config.getLogger('HTTP');
return (req, res, next) => { return (req, res, next) => {
next(); next();
if (config.enableRequestLogger) { if (config.enableRequestLogger) {

View File

@ -1,6 +1,7 @@
'use strict'; 'use strict';
const { publicFolder } = require('unleash-frontend'); const { publicFolder } = require('unleash-frontend');
const { defaultLogProvider, validateLogProvider } = require('./logger');
const isDev = () => process.env.NODE_ENV === 'development'; const isDev = () => process.env.NODE_ENV === 'development';
const THIRTY_DAYS = 30 * 24 * 60 * 60 * 1000; const THIRTY_DAYS = 30 * 24 * 60 * 60 * 1000;
@ -23,6 +24,7 @@ const DEFAULT_OPTIONS = {
ui: {}, ui: {},
importFile: undefined, importFile: undefined,
dropBeforeImport: false, dropBeforeImport: false,
getLogger: defaultLogProvider,
}; };
module.exports = { module.exports = {
@ -45,6 +47,8 @@ module.exports = {
? { path: options.pipe } ? { path: options.pipe }
: { port: options.port, host: options.host }; : { port: options.port, host: options.host };
validateLogProvider(options.getLogger);
return options; return options;
}, },
}; };

View File

@ -2,7 +2,6 @@
const Controller = require('../controller'); const Controller = require('../controller');
const logger = require('../../logger')('/admin-api/archive.js');
const { FEATURE_REVIVED } = require('../../event-type'); const { FEATURE_REVIVED } = require('../../event-type');
const extractUser = require('../../extract-user'); const extractUser = require('../../extract-user');
const { UPDATE_FEATURE } = require('../../permissions'); const { UPDATE_FEATURE } = require('../../permissions');
@ -10,6 +9,7 @@ const { UPDATE_FEATURE } = require('../../permissions');
class ArchiveController extends Controller { class ArchiveController extends Controller {
constructor(config) { constructor(config) {
super(config); super(config);
this.logger = config.getLogger('/admin-api/archive.js');
this.featureToggleStore = config.stores.featureToggleStore; this.featureToggleStore = config.stores.featureToggleStore;
this.eventStore = config.stores.eventStore; this.eventStore = config.stores.eventStore;
@ -33,7 +33,7 @@ class ArchiveController extends Controller {
}); });
res.status(200).end(); res.status(200).end();
} catch (error) { } catch (error) {
logger.error('Server failed executing request', error); this.logger.error('Server failed executing request', error);
return res.status(500).end(); return res.status(500).end();
} }
} }

View File

@ -3,6 +3,7 @@
const test = require('ava'); const test = require('ava');
const store = require('./../../../test/fixtures/store'); const store = require('./../../../test/fixtures/store');
const permissions = require('../../../test/fixtures/permissions'); const permissions = require('../../../test/fixtures/permissions');
const getLogger = require('../../../test/fixtures/no-logger');
const supertest = require('supertest'); const supertest = require('supertest');
const getApp = require('../../app'); const getApp = require('../../app');
const { UPDATE_FEATURE } = require('../../permissions'); const { UPDATE_FEATURE } = require('../../permissions');
@ -20,6 +21,7 @@ function getSetup() {
eventBus, eventBus,
extendedPermissions: true, extendedPermissions: true,
preRouterHook: perms.hook, preRouterHook: perms.hook,
getLogger,
}); });
return { return {

View File

@ -2,6 +2,7 @@
const test = require('ava'); const test = require('ava');
const store = require('./../../../test/fixtures/store'); const store = require('./../../../test/fixtures/store');
const getLogger = require('../../../test/fixtures/no-logger');
const supertest = require('supertest'); const supertest = require('supertest');
const getApp = require('../../app'); const getApp = require('../../app');
@ -22,6 +23,7 @@ function getSetup() {
eventBus, eventBus,
extendedPermissions: false, extendedPermissions: false,
ui: uiConfig, ui: uiConfig,
getLogger,
}); });
return { return {

View File

@ -3,6 +3,8 @@
const test = require('ava'); const test = require('ava');
const store = require('./../../../test/fixtures/store'); const store = require('./../../../test/fixtures/store');
const getLogger = require('../../../test/fixtures/no-logger');
const supertest = require('supertest'); const supertest = require('supertest');
const getApp = require('../../app'); const getApp = require('../../app');
@ -16,6 +18,7 @@ function getSetup() {
baseUriPath: base, baseUriPath: base,
stores, stores,
eventBus, eventBus,
getLogger,
}); });
return { base, eventStore: stores.eventStore, request: supertest(app) }; return { base, eventStore: stores.eventStore, request: supertest(app) };

View File

@ -24,6 +24,7 @@ class FeatureController extends Controller {
super(config); super(config);
this.featureToggleStore = config.stores.featureToggleStore; this.featureToggleStore = config.stores.featureToggleStore;
this.eventStore = config.stores.eventStore; this.eventStore = config.stores.eventStore;
this.logger = config.getLogger('/admin-api/feature.js');
this.get('/', this.getAllToggles); this.get('/', this.getAllToggles);
this.post('/', this.createToggle, CREATE_FEATURE); this.post('/', this.createToggle, CREATE_FEATURE);
@ -59,7 +60,7 @@ class FeatureController extends Controller {
await this.validateUniqueName(name); await this.validateUniqueName(name);
res.status(201).end(); res.status(201).end();
} catch (error) { } catch (error) {
handleErrors(res, error); handleErrors(res, this.logger, error);
} }
} }
@ -94,7 +95,7 @@ class FeatureController extends Controller {
}); });
res.status(201).end(); res.status(201).end();
} catch (error) { } catch (error) {
handleErrors(res, error); handleErrors(res, this.logger, error);
} }
} }
@ -115,7 +116,7 @@ class FeatureController extends Controller {
}); });
res.status(200).end(); res.status(200).end();
} catch (error) { } catch (error) {
handleErrors(res, error); handleErrors(res, this.logger, error);
} }
} }
@ -127,7 +128,7 @@ class FeatureController extends Controller {
const enabled = !feature.enabled; const enabled = !feature.enabled;
this._toggle(enabled, req, res); this._toggle(enabled, req, res);
} catch (error) { } catch (error) {
handleErrors(res, error); handleErrors(res, this.logger, error);
} }
} }
@ -156,7 +157,7 @@ class FeatureController extends Controller {
}); });
res.json(feature).end(); res.json(feature).end();
} catch (error) { } catch (error) {
handleErrors(res, error); handleErrors(res, this.logger, error);
} }
} }
@ -175,7 +176,7 @@ class FeatureController extends Controller {
}); });
res.status(200).end(); res.status(200).end();
} catch (error) { } catch (error) {
handleErrors(res, error); handleErrors(res, this.logger, error);
} }
} }
} }

View File

@ -3,6 +3,7 @@
const test = require('ava'); const test = require('ava');
const store = require('./../../../test/fixtures/store'); const store = require('./../../../test/fixtures/store');
const permissions = require('../../../test/fixtures/permissions'); const permissions = require('../../../test/fixtures/permissions');
const getLogger = require('../../../test/fixtures/no-logger');
const supertest = require('supertest'); const supertest = require('supertest');
const getApp = require('../../app'); const getApp = require('../../app');
const { UPDATE_FEATURE, CREATE_FEATURE } = require('../../permissions'); const { UPDATE_FEATURE, CREATE_FEATURE } = require('../../permissions');
@ -20,6 +21,7 @@ function getSetup() {
eventBus, eventBus,
extendedPermissions: true, extendedPermissions: true,
preRouterHook: perms.hook, preRouterHook: perms.hook,
getLogger,
}); });
return { return {

View File

@ -2,7 +2,6 @@
const joi = require('joi'); const joi = require('joi');
const Controller = require('../controller'); const Controller = require('../controller');
const logger = require('../../logger')('/admin-api/metrics.js');
const ClientMetrics = require('../../client-metrics'); const ClientMetrics = require('../../client-metrics');
const schema = require('./metrics-schema'); const schema = require('./metrics-schema');
const { UPDATE_APPLICATION } = require('../../permissions'); const { UPDATE_APPLICATION } = require('../../permissions');
@ -10,6 +9,7 @@ const { UPDATE_APPLICATION } = require('../../permissions');
class MetricsController extends Controller { class MetricsController extends Controller {
constructor(config) { constructor(config) {
super(config); super(config);
this.logger = config.getLogger('/admin-api/metrics.js');
const { const {
clientMetricsStore, clientMetricsStore,
clientInstanceStore, clientInstanceStore,
@ -83,7 +83,7 @@ class MetricsController extends Controller {
const { value: applicationData, error } = joi.validate(input, schema); const { value: applicationData, error } = joi.validate(input, schema);
if (error) { if (error) {
logger.warn('Invalid application data posted', error); this.logger.warn('Invalid application data posted', error);
return res.status(400).json(error); return res.status(400).json(error);
} }
@ -91,7 +91,7 @@ class MetricsController extends Controller {
await this.clientApplicationsStore.upsert(applicationData); await this.clientApplicationsStore.upsert(applicationData);
res.status(202).end(); res.status(202).end();
} catch (err) { } catch (err) {
logger.error(err); this.logger.error(err);
res.status(500).end(); res.status(500).end();
} }
} }
@ -103,7 +103,7 @@ class MetricsController extends Controller {
); );
res.json({ applications }); res.json({ applications });
} catch (err) { } catch (err) {
logger.error(err); this.logger.error(err);
res.status(500).end(); res.status(500).end();
} }
} }
@ -147,7 +147,7 @@ class MetricsController extends Controller {
}; };
res.json(appDetails); res.json(appDetails);
} catch (err) { } catch (err) {
logger.error(err); this.logger.error(err);
res.status(500).end(); res.status(500).end();
} }
} }

View File

@ -3,6 +3,7 @@
const test = require('ava'); const test = require('ava');
const store = require('./../../../test/fixtures/store'); const store = require('./../../../test/fixtures/store');
const permissions = require('../../../test/fixtures/permissions'); const permissions = require('../../../test/fixtures/permissions');
const getLogger = require('../../../test/fixtures/no-logger');
const supertest = require('supertest'); const supertest = require('supertest');
const getApp = require('../../app'); const getApp = require('../../app');
const { UPDATE_APPLICATION } = require('../../permissions'); const { UPDATE_APPLICATION } = require('../../permissions');
@ -19,6 +20,7 @@ function getSetup() {
eventBus, eventBus,
extendedPermissions: true, extendedPermissions: true,
preRouterHook: perms.hook, preRouterHook: perms.hook,
getLogger,
}); });
return { return {

View File

@ -13,6 +13,7 @@ const upload = multer({ limits: { fileSize: 5242880 } });
class StateController extends Controller { class StateController extends Controller {
constructor(config) { constructor(config) {
super(config); super(config);
this.logger = config.getLogger('/admin-api/state.js');
this.fileupload('/import', upload.single('file'), this.import, ADMIN); this.fileupload('/import', upload.single('file'), this.import, ADMIN);
this.get('/export', this.export, ADMIN); this.get('/export', this.export, ADMIN);
} }
@ -40,7 +41,7 @@ class StateController extends Controller {
}); });
res.sendStatus(202); res.sendStatus(202);
} catch (err) { } catch (err) {
handleErrors(res, err); handleErrors(res, this.logger, err);
} }
} }
@ -75,7 +76,7 @@ class StateController extends Controller {
res.json(data); res.json(data);
} }
} catch (err) { } catch (err) {
handleErrors(res, err); handleErrors(res, this.logger, err);
} }
} }
} }

View File

@ -18,6 +18,7 @@ const version = 1;
class StrategyController extends Controller { class StrategyController extends Controller {
constructor(config) { constructor(config) {
super(config); super(config);
this.logger = config.getLogger('/admin-api/strategy.js');
this.strategyStore = config.stores.strategyStore; this.strategyStore = config.stores.strategyStore;
this.eventStore = config.stores.eventStore; this.eventStore = config.stores.eventStore;
@ -58,7 +59,7 @@ class StrategyController extends Controller {
}); });
res.status(200).end(); res.status(200).end();
} catch (error) { } catch (error) {
handleErrors(res, error); handleErrors(res, this.logger, error);
} }
} }
@ -73,7 +74,7 @@ class StrategyController extends Controller {
}); });
res.status(201).end(); res.status(201).end();
} catch (error) { } catch (error) {
handleErrors(res, error); handleErrors(res, this.logger, error);
} }
} }
@ -92,7 +93,7 @@ class StrategyController extends Controller {
}); });
res.status(200).end(); res.status(200).end();
} catch (error) { } catch (error) {
handleErrors(res, error); handleErrors(res, this.logger, error);
} }
} }

View File

@ -3,6 +3,7 @@
const test = require('ava'); const test = require('ava');
const store = require('./../../../test/fixtures/store'); const store = require('./../../../test/fixtures/store');
const permissions = require('../../../test/fixtures/permissions'); const permissions = require('../../../test/fixtures/permissions');
const getLogger = require('../../../test/fixtures/no-logger');
const supertest = require('supertest'); const supertest = require('supertest');
const getApp = require('../../app'); const getApp = require('../../app');
const { const {
@ -22,6 +23,7 @@ function getSetup() {
baseUriPath: base, baseUriPath: base,
stores, stores,
eventBus, eventBus,
getLogger,
extendedPermissions: true, extendedPermissions: true,
preRouterHook: perms.hook, preRouterHook: perms.hook,
}); });

View File

@ -2,6 +2,7 @@
const test = require('ava'); const test = require('ava');
const store = require('./../../../test/fixtures/store'); const store = require('./../../../test/fixtures/store');
const getLogger = require('../../../test/fixtures/no-logger');
const supertest = require('supertest'); const supertest = require('supertest');
const getApp = require('../../app'); const getApp = require('../../app');
const User = require('../../user'); const User = require('../../user');
@ -18,6 +19,7 @@ function getSetup() {
baseUriPath: base, baseUriPath: base,
stores, stores,
eventBus, eventBus,
getLogger,
preHook: a => { preHook: a => {
a.use((req, res, next) => { a.use((req, res, next) => {
req.user = currentUser; req.user = currentUser;

View File

@ -1,7 +1,5 @@
'use strict'; 'use strict';
const logger = require('../../logger')('/admin-api/util.js');
const joi = require('joi'); const joi = require('joi');
const customJoi = joi.extend(j => ({ const customJoi = joi.extend(j => ({
@ -36,7 +34,7 @@ const nameType = customJoi
.max(100) .max(100)
.required(); .required();
const handleErrors = (res, error) => { const handleErrors = (res, logger, error) => {
logger.warn(error.message); logger.warn(error.message);
switch (error.name) { switch (error.name) {
case 'NotFoundError': case 'NotFoundError':

View File

@ -2,6 +2,7 @@
const test = require('ava'); const test = require('ava');
const store = require('./../../test/fixtures/store'); const store = require('./../../test/fixtures/store');
const getLogger = require('../../test/fixtures/no-logger');
const supertest = require('supertest'); const supertest = require('supertest');
const getApp = require('../app'); const getApp = require('../app');
@ -16,6 +17,7 @@ test('should use enable prometheus', t => {
serverMetrics: true, serverMetrics: true,
stores, stores,
eventBus, eventBus,
getLogger,
}); });
const request = supertest(app); const request = supertest(app);

View File

@ -2,6 +2,7 @@
const test = require('ava'); const test = require('ava');
const store = require('./../../../test/fixtures/store'); const store = require('./../../../test/fixtures/store');
const getLogger = require('../../../test/fixtures/no-logger');
const supertest = require('supertest'); const supertest = require('supertest');
const getApp = require('../../app'); const getApp = require('../../app');
@ -15,6 +16,7 @@ function getSetup() {
baseUriPath: base, baseUriPath: base,
stores, stores,
eventBus, eventBus,
getLogger,
}); });
return { return {

View File

@ -11,11 +11,12 @@ class ClientApi extends Controller {
super(); super();
const stores = config.stores; const stores = config.stores;
const getLogger = config.getLogger;
this.get('/', this.index); this.get('/', this.index);
this.use('/features', new FeatureController(stores).router); this.use('/features', new FeatureController(stores, getLogger).router);
this.use('/metrics', new MetricsController(stores).router); this.use('/metrics', new MetricsController(stores, getLogger).router);
this.use('/register', new RegisterController(stores).router); this.use('/register', new RegisterController(stores, getLogger).router);
} }
index(req, res) { index(req, res) {

View File

@ -1,14 +1,14 @@
'use strict'; 'use strict';
const joi = require('joi'); const joi = require('joi');
const logger = require('../../logger')('client-api/metrics.js');
const Controller = require('../controller'); const Controller = require('../controller');
const { clientMetricsSchema } = require('./metrics-schema'); const { clientMetricsSchema } = require('./metrics-schema');
class ClientMetricsController extends Controller { class ClientMetricsController extends Controller {
constructor({ clientMetricsStore, clientInstanceStore }) { constructor({ clientMetricsStore, clientInstanceStore }, getLogger) {
super(); super();
this.logger = getLogger('/api/client/metrics');
this.clientMetricsStore = clientMetricsStore; this.clientMetricsStore = clientMetricsStore;
this.clientInstanceStore = clientInstanceStore; this.clientInstanceStore = clientInstanceStore;
@ -22,7 +22,7 @@ class ClientMetricsController extends Controller {
const { error, value } = joi.validate(data, clientMetricsSchema); const { error, value } = joi.validate(data, clientMetricsSchema);
if (error) { if (error) {
logger.warn('Invalid metrics posted', error); this.logger.warn('Invalid metrics posted', error);
return res.status(400).json(error); return res.status(400).json(error);
} }
@ -35,7 +35,7 @@ class ClientMetricsController extends Controller {
}); });
res.status(202).end(); res.status(202).end();
} catch (e) { } catch (e) {
logger.error('failed to store metrics', e); this.logger.error('failed to store metrics', e);
res.status(500).end(); res.status(500).end();
} }
} }

View File

@ -2,6 +2,7 @@
const test = require('ava'); const test = require('ava');
const store = require('./../../../test/fixtures/store'); const store = require('./../../../test/fixtures/store');
const getLogger = require('../../../test/fixtures/no-logger');
const supertest = require('supertest'); const supertest = require('supertest');
const getApp = require('../../app'); const getApp = require('../../app');
@ -14,6 +15,7 @@ function getSetup() {
baseUriPath: '', baseUriPath: '',
stores, stores,
eventBus, eventBus,
getLogger,
}); });
return { return {

View File

@ -1,14 +1,14 @@
'use strict'; 'use strict';
const joi = require('joi'); const joi = require('joi');
const logger = require('../../logger')('/client-api/register.js');
const Controller = require('../controller'); const Controller = require('../controller');
const { clientRegisterSchema: schema } = require('./register-schema'); const { clientRegisterSchema: schema } = require('./register-schema');
class RegisterController extends Controller { class RegisterController extends Controller {
constructor({ clientInstanceStore, clientApplicationsStore }) { constructor({ clientInstanceStore, clientApplicationsStore }, getLogger) {
super(); super();
this.logger = getLogger('/api/client/register');
this.clientInstanceStore = clientInstanceStore; this.clientInstanceStore = clientInstanceStore;
this.clientApplicationsStore = clientApplicationsStore; this.clientApplicationsStore = clientApplicationsStore;
@ -20,7 +20,7 @@ class RegisterController extends Controller {
const { value: clientRegistration, error } = joi.validate(data, schema); const { value: clientRegistration, error } = joi.validate(data, schema);
if (error) { if (error) {
logger.warn('Invalid client data posted', error); this.logger.warn('Invalid client data posted', error);
return res.status(400).json(error); return res.status(400).json(error);
} }
@ -29,14 +29,14 @@ class RegisterController extends Controller {
try { try {
await this.clientApplicationsStore.upsert(clientRegistration); await this.clientApplicationsStore.upsert(clientRegistration);
await this.clientInstanceStore.insert(clientRegistration); await this.clientInstanceStore.insert(clientRegistration);
logger.info( this.logger.info(
`New client registered with appName=${ `New client registered with appName=${
clientRegistration.appName clientRegistration.appName
} and instanceId=${clientRegistration.instanceId}` } and instanceId=${clientRegistration.instanceId}`
); );
return res.status(202).end(); return res.status(202).end();
} catch (err) { } catch (err) {
logger.error('failed to register client', err); this.logger.error('failed to register client', err);
return res.status(500).end(); return res.status(500).end();
} }
} }

View File

@ -2,6 +2,7 @@
const test = require('ava'); const test = require('ava');
const store = require('./../../../test/fixtures/store'); const store = require('./../../../test/fixtures/store');
const getLogger = require('../../../test/fixtures/no-logger');
const supertest = require('supertest'); const supertest = require('supertest');
const getApp = require('../../app'); const getApp = require('../../app');
@ -14,6 +15,7 @@ function getSetup() {
baseUriPath: '', baseUriPath: '',
stores, stores,
eventBus, eventBus,
getLogger,
}); });
return { return {
@ -89,6 +91,7 @@ test('should fail if store fails', t => {
baseUriPath: '', baseUriPath: '',
stores, stores,
eventBus, eventBus,
getLogger,
}); });
// --- end custom config // --- end custom config

View File

@ -1,12 +1,12 @@
'use strict'; 'use strict';
const logger = require('../logger')('health-check.js');
const Controller = require('./controller'); const Controller = require('./controller');
class HealthCheckController extends Controller { class HealthCheckController extends Controller {
constructor(config) { constructor(config) {
super(); super();
this.db = config.stores.db; this.db = config.stores.db;
this.logger = config.getLogger('health-check.js');
this.get('/', (req, res) => this.index(req, res)); this.get('/', (req, res) => this.index(req, res));
} }
@ -16,7 +16,7 @@ class HealthCheckController extends Controller {
await this.db.select(1).from('features'); await this.db.select(1).from('features');
res.json({ health: 'GOOD' }); res.json({ health: 'GOOD' });
} catch (e) { } catch (e) {
logger.error('Could not select from features, error was: ', e); this.logger.error('Could not select from features, error was: ', e);
res.status(500).json({ health: 'BAD' }); res.status(500).json({ health: 'BAD' });
} }
} }

View File

@ -2,6 +2,7 @@
const test = require('ava'); const test = require('ava');
const store = require('./../../test/fixtures/store'); const store = require('./../../test/fixtures/store');
const getLogger = require('../../test/fixtures/no-logger');
const supertest = require('supertest'); const supertest = require('supertest');
const getApp = require('../app'); const getApp = require('../app');
@ -15,6 +16,7 @@ function getSetup() {
baseUriPath: '', baseUriPath: '',
stores, stores,
eventBus, eventBus,
getLogger,
}); });
return { return {

View File

@ -2,6 +2,7 @@
const test = require('ava'); const test = require('ava');
const store = require('./../../test/fixtures/store'); const store = require('./../../test/fixtures/store');
const getLogger = require('../../test/fixtures/no-logger');
const supertest = require('supertest'); const supertest = require('supertest');
const getApp = require('../app'); const getApp = require('../app');
@ -16,6 +17,7 @@ function getSetup() {
stores, stores,
eventBus, eventBus,
enableLegacyRoutes: true, enableLegacyRoutes: true,
getLogger,
}); });
return { return {

View File

@ -2,8 +2,6 @@
const { EventEmitter } = require('events'); const { EventEmitter } = require('events');
const logFactory = require('./logger');
const logger = require('./logger')('server-impl.js');
const migrator = require('../migrator'); const migrator = require('../migrator');
const getApp = require('./app'); const getApp = require('./app');
@ -16,6 +14,7 @@ const AuthenticationRequired = require('./authentication-required');
async function createApp(options) { async function createApp(options) {
// Database dependecies (statefull) // Database dependecies (statefull)
const logger = options.getLogger('server-impl.js');
const stores = createStores(options); const stores = createStores(options);
const eventBus = new EventEmitter(); const eventBus = new EventEmitter();
@ -23,7 +22,7 @@ async function createApp(options) {
{ {
stores, stores,
eventBus, eventBus,
logFactory, logFactory: options.getLogger, // TODO: remove in v4.x
}, },
options options
); );
@ -65,6 +64,7 @@ async function createApp(options) {
async function start(opts) { async function start(opts) {
const options = createOptions(opts); const options = createOptions(opts);
const logger = options.getLogger('server-impl.js');
try { try {
await migrator(options); await migrator(options);

View File

@ -3,6 +3,7 @@
const test = require('ava'); const test = require('ava');
const proxyquire = require('proxyquire'); const proxyquire = require('proxyquire');
const express = require('express'); const express = require('express');
const getLogger = require('../test/fixtures/no-logger');
const getApp = proxyquire('./app', { const getApp = proxyquire('./app', {
'./routes': class Index { './routes': class Index {
@ -38,6 +39,7 @@ test('should call preHook', async t => {
let called = 0; let called = 0;
await serverImpl.start({ await serverImpl.start({
port: 0, port: 0,
getLogger,
preHook: () => { preHook: () => {
called++; called++;
}, },
@ -49,6 +51,7 @@ test('should call preRouterHook', async t => {
let called = 0; let called = 0;
await serverImpl.start({ await serverImpl.start({
port: 0, port: 0,
getLogger,
preRouterHook: () => { preRouterHook: () => {
called++; called++;
}, },

View File

@ -5,7 +5,6 @@ const fs = require('fs');
const mime = require('mime'); const mime = require('mime');
const { featureShema } = require('./routes/admin-api/feature-schema'); const { featureShema } = require('./routes/admin-api/feature-schema');
const strategySchema = require('./routes/admin-api/strategy-schema'); const strategySchema = require('./routes/admin-api/strategy-schema');
const getLogger = require('./logger');
const YAML = require('js-yaml'); const YAML = require('js-yaml');
const { const {
FEATURE_IMPORT, FEATURE_IMPORT,
@ -14,8 +13,6 @@ const {
DROP_STRATEGIES, DROP_STRATEGIES,
} = require('./event-type'); } = require('./event-type');
const logger = getLogger('state-service.js');
const dataSchema = joi.object().keys({ const dataSchema = joi.object().keys({
version: joi.number(), version: joi.number(),
features: joi features: joi
@ -43,6 +40,7 @@ function parseFile(file, data) {
class StateService { class StateService {
constructor(config) { constructor(config) {
this.config = config; this.config = config;
this.logger = config.getLogger('state-service.js');
} }
importFile({ file, dropBeforeImport, userName }) { importFile({ file, dropBeforeImport, userName }) {
@ -57,9 +55,11 @@ class StateService {
const importData = await joi.validate(data, dataSchema); const importData = await joi.validate(data, dataSchema);
if (importData.features) { if (importData.features) {
logger.info(`Importing ${importData.features.length} features`); this.logger.info(
`Importing ${importData.features.length} features`
);
if (dropBeforeImport) { if (dropBeforeImport) {
logger.info(`Dropping existing features`); this.logger.info(`Dropping existing features`);
await eventStore.store({ await eventStore.store({
type: DROP_FEATURES, type: DROP_FEATURES,
createdBy: userName, createdBy: userName,
@ -78,9 +78,11 @@ class StateService {
} }
if (importData.strategies) { if (importData.strategies) {
logger.info(`Importing ${importData.strategies.length} strategies`); this.logger.info(
`Importing ${importData.strategies.length} strategies`
);
if (dropBeforeImport) { if (dropBeforeImport) {
logger.info(`Dropping existing strategies`); this.logger.info(`Dropping existing strategies`);
await eventStore.store({ await eventStore.store({
type: DROP_STRATEGIES, type: DROP_STRATEGIES,
createdBy: userName, createdBy: userName,

View File

@ -3,6 +3,8 @@
const test = require('ava'); const test = require('ava');
const store = require('./../test/fixtures/store'); const store = require('./../test/fixtures/store');
const getLogger = require('./../test/fixtures/no-logger');
const StateService = require('./state-service'); const StateService = require('./state-service');
const { const {
FEATURE_IMPORT, FEATURE_IMPORT,
@ -13,7 +15,7 @@ const {
function getSetup() { function getSetup() {
const stores = store.createStores(); const stores = store.createStores();
return { stateService: new StateService({ stores }), stores }; return { stateService: new StateService({ stores, getLogger }), stores };
} }
test('should import a feature', async t => { test('should import a feature', async t => {

View File

@ -1,5 +0,0 @@
'use strict';
const logger = require('./lib/logger');
exports.setLoggerProvider = logger.setLoggerProvider;

View File

@ -34,7 +34,7 @@
"scripts": { "scripts": {
"start": "node server.js", "start": "node server.js",
"start:google": "node examples/google-auth-unleash.js", "start:google": "node examples/google-auth-unleash.js",
"start:dev": "NODE_ENV=development supervisor --ignore ./node_modules/ server.js", "start:dev": "NODE_ENV=development supervisor --ignore ./node_modules/,website server.js",
"start:dev:pg": "pg_virtualenv npm run start:dev:pg-chain", "start:dev:pg": "pg_virtualenv npm run start:dev:pg-chain",
"start:dev:pg-chain": "export DATABASE_URL=postgres://$PGUSER:$PGPASSWORD@localhost:$PGPORT/postgres ; db-migrate up && npm run start:dev", "start:dev:pg-chain": "export DATABASE_URL=postgres://$PGUSER:$PGPASSWORD@localhost:$PGPORT/postgres ; db-migrate up && npm run start:dev",
"db-migrate": "db-migrate", "db-migrate": "db-migrate",

View File

@ -49,12 +49,13 @@ function createFeatures(store) {
return dbState.features.map(f => store._createFeature(f)); return dbState.features.map(f => store._createFeature(f));
} }
module.exports = async function init(databaseSchema = 'test') { module.exports = async function init(databaseSchema = 'test', getLogger) {
const options = { const options = {
databaseUrl: require('./database-config').getDatabaseUrl(), databaseUrl: require('./database-config').getDatabaseUrl(),
databaseSchema, databaseSchema,
minPool: 0, minPool: 0,
maxPool: 0, maxPool: 0,
getLogger,
}; };
const db = createDb(options); const db = createDb(options);

View File

@ -6,6 +6,7 @@ const supertest = require('supertest');
const getApp = require('../../../lib/app'); const getApp = require('../../../lib/app');
const dbInit = require('./database-init'); const dbInit = require('./database-init');
const getLogger = require('../../fixtures/no-logger');
const StateService = require('../../../lib/state-service'); const StateService = require('../../../lib/state-service');
const { EventEmitter } = require('events'); const { EventEmitter } = require('events');
@ -19,13 +20,14 @@ function createApp(stores, adminAuthentication = 'none', preHook) {
adminAuthentication, adminAuthentication,
secret: 'super-secret', secret: 'super-secret',
sessionAge: 4000, sessionAge: 4000,
stateService: new StateService({ stores }), stateService: new StateService({ stores, getLogger }),
getLogger,
}); });
} }
module.exports = { module.exports = {
async setupApp(name) { async setupApp(name) {
const stores = await dbInit(name); const stores = await dbInit(name, getLogger);
const app = createApp(stores); const app = createApp(stores);
return { return {
@ -34,7 +36,7 @@ module.exports = {
}; };
}, },
async setupAppWithAuth(name) { async setupAppWithAuth(name) {
const stores = await dbInit(name); const stores = await dbInit(name, getLogger);
const app = createApp(stores, 'unsecure'); const app = createApp(stores, 'unsecure');
return { return {
@ -44,7 +46,7 @@ module.exports = {
}, },
async setupAppWithCustomAuth(name, preHook) { async setupAppWithCustomAuth(name, preHook) {
const stores = await dbInit(name); const stores = await dbInit(name, getLogger);
const app = createApp(stores, 'custom', preHook); const app = createApp(stores, 'custom', preHook);
return { return {

11
test/fixtures/no-logger.js vendored Normal file
View File

@ -0,0 +1,11 @@
'use strict';
module.exports = function noLoggerProvider() {
// do something with the name
return {
debug: () => {},
info: () => {},
warn: () => {},
error: () => {},
};
};