118 lines
3 KiB
JavaScript
118 lines
3 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
const _ = require('lodash');
|
||
|
const assert = require('assert');
|
||
|
|
||
|
const Env = require('../Env');
|
||
|
const IdGenerator = require('../IdGenerator');
|
||
|
const LevelsContainer = require('../levels-container');
|
||
|
const LogContext = require('./LogContext');
|
||
|
const normalizeComponent = require('../common').normalizeComponent;
|
||
|
const consts = require('../constants');
|
||
|
|
||
|
const ListLog = require('../formats/ListLog');
|
||
|
const Trace = require('../formats/Trace');
|
||
|
const CFLog = require('../formats/CFLog');
|
||
|
|
||
|
class AppContext {
|
||
|
constructor(options) {
|
||
|
this._options = processOptions(options);
|
||
|
this._env = new Env();
|
||
|
this._idGen = new IdGenerator();
|
||
|
this._levels = new LevelsContainer();
|
||
|
this._formatters = initFormatters(this);
|
||
|
this._customFieldNames = [];
|
||
|
enableRuntimeLevelChanging(this);
|
||
|
}
|
||
|
|
||
|
setCustomFields(fields) {
|
||
|
assert(_.isArray(fields), 'Fields argument should be an array');
|
||
|
this._customFieldNames = fields || [];
|
||
|
}
|
||
|
|
||
|
_containsCustomField(obj) {
|
||
|
if (!obj) {
|
||
|
return null;
|
||
|
}
|
||
|
return this._customFieldNames.some((prop) => {
|
||
|
return obj.hasOwnProperty(prop);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
_filterCustomFields(obj) {
|
||
|
if (!obj) {
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
return this._customFieldNames.reduce((p, c) => {
|
||
|
if (obj.hasOwnProperty(c)) {
|
||
|
p[c] = typeof obj[c] === 'string' ? obj[c] : JSON.stringify(obj[c]);
|
||
|
}
|
||
|
return p;
|
||
|
}, {});
|
||
|
}
|
||
|
|
||
|
createLogContext(options) {
|
||
|
return new LogContext(this, options);
|
||
|
}
|
||
|
|
||
|
setLevel(component, level) {
|
||
|
this._levels.set(normalizeComponent(component), level);
|
||
|
}
|
||
|
|
||
|
unsetLevel(component) {
|
||
|
this._levels.unset(normalizeComponent(component));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function processOptions(options) {
|
||
|
assert(options === undefined || _.isObject(options), 'Expected an object for application-wide options (if provided)');
|
||
|
options = options || {};
|
||
|
assert(options.csnComponent === undefined || _.isString(options.csnComponent), '"csnComponent" (if provided) should be a string');
|
||
|
return options;
|
||
|
}
|
||
|
|
||
|
function initFormatters(ctx) {
|
||
|
const env = ctx._env;
|
||
|
if (env.runsOnCF) {
|
||
|
var log = new CFLog(env);
|
||
|
var trace = new CFLog(env);
|
||
|
} else {
|
||
|
log = new ListLog(env);
|
||
|
trace = new Trace(env);
|
||
|
}
|
||
|
return { log, trace };
|
||
|
}
|
||
|
|
||
|
function enableRuntimeLevelChanging(ctx) {
|
||
|
const runtimeMessaging = loadXSRuntimeMessaging(ctx);
|
||
|
if (!runtimeMessaging) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
const rtConn = runtimeMessaging.getRuntimeConnection();
|
||
|
rtConn.on('ready', () => {
|
||
|
const consumer = rtConn.consumer('SetLoggingLevel');
|
||
|
consumer.on('handleDelivery', (component, level) => {
|
||
|
if (level) {
|
||
|
ctx.setLevel(component, level);
|
||
|
} else {
|
||
|
ctx.unsetLevel(component);
|
||
|
}
|
||
|
});
|
||
|
ctx._consumer = consumer;
|
||
|
});
|
||
|
rtConn.unref();
|
||
|
ctx._rtConn = rtConn;
|
||
|
}
|
||
|
|
||
|
function loadXSRuntimeMessaging(ctx) {
|
||
|
try {
|
||
|
return require('sap_xsrt_messaging');
|
||
|
} catch (exc) {
|
||
|
ctx.createLogContext({ id: '' }).getLogger(consts.LIB_CATEGORY).warning('Dynamic log level switching not available');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = AppContext;
|