99 lines
2.7 KiB
JavaScript
99 lines
2.7 KiB
JavaScript
|
'use strict';
|
||
|
|
||
|
const _ = require('lodash');
|
||
|
const assert = require('assert');
|
||
|
const moment = require('moment');
|
||
|
const SAPPassport = require('@sap/e2e-trace').Passport;
|
||
|
const consts = require('../constants');
|
||
|
|
||
|
const Logger = require('../logging-tools/Logger');
|
||
|
const NetworkLogger = require('../logging-tools/NetworkLogger');
|
||
|
const Tracer = require('../logging-tools/Tracer');
|
||
|
|
||
|
class LogContext {
|
||
|
constructor(appContext, options) {
|
||
|
this._timeCreated = moment();
|
||
|
this._appContext = appContext;
|
||
|
this._options = processOptions(options);
|
||
|
this._sapPassport = parseSAPPassport(this);
|
||
|
}
|
||
|
|
||
|
getAppContext() {
|
||
|
return this._appContext;
|
||
|
}
|
||
|
|
||
|
getLogger(category) {
|
||
|
return new Logger(this, category);
|
||
|
}
|
||
|
|
||
|
getTracer(location) {
|
||
|
return new Tracer(this, location);
|
||
|
}
|
||
|
|
||
|
get id() {
|
||
|
return get(this, 'id', resolveId);
|
||
|
}
|
||
|
|
||
|
get correlationId() {
|
||
|
return get(this, 'correlationId', resolveCorrelationId);
|
||
|
}
|
||
|
|
||
|
enableNetworkLog(res) {
|
||
|
assert(_.isObject(res), 'Provided response should be an object');
|
||
|
assert(this._options.hasOwnProperty('req'), 'The "req" property should be set to context in advance in order to enable network log');
|
||
|
this._options.res = res;
|
||
|
|
||
|
if (this._appContext._env.loggingOff) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
res.on('finish', () => {
|
||
|
const networkLogger = new NetworkLogger(this);
|
||
|
networkLogger.info();
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function processOptions(options) {
|
||
|
assert(options === undefined || _.isObject(options), 'Expected an object for log context options (if provided)');
|
||
|
options = _.extend({}, options);
|
||
|
assert(options.id === undefined || _.isString(options.id), '"id" (if provided) should be a string');
|
||
|
assert(options.correlationId === undefined || _.isString(options.correlationId), '"correlationId" (if provided) should be a string');
|
||
|
assert(options.req === undefined || _.isObject(options.req), '"req" (if provided) should be an object');
|
||
|
return options;
|
||
|
}
|
||
|
|
||
|
function get(ctx, prop, fnResolve) {
|
||
|
const options = ctx._options;
|
||
|
if (!options.hasOwnProperty(prop)) {
|
||
|
options[prop] = fnResolve(ctx);
|
||
|
}
|
||
|
return options[prop];
|
||
|
}
|
||
|
|
||
|
function resolveId(ctx) {
|
||
|
const req = ctx._options.req;
|
||
|
return (req && (req.headers['x-request-id'] || req.headers['x-vcap-request-id']))
|
||
|
|| ctx._appContext._idGen.nextId();
|
||
|
}
|
||
|
|
||
|
function resolveCorrelationId(ctx) {
|
||
|
const req = ctx._options.req;
|
||
|
return (req && req.headers['x-correlationid']) || ctx.id;
|
||
|
}
|
||
|
|
||
|
function parseSAPPassport(ctx) {
|
||
|
const req = ctx._options.req;
|
||
|
if (!req || !req.headers[SAPPassport.HEADER_NAME]) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
return new SAPPassport(req.headers[SAPPassport.HEADER_NAME]).readUniqueIdentifiers();
|
||
|
} catch (err) {
|
||
|
ctx.getLogger(consts.LIB_CATEGORY).error(err, 'Could not parse SAP Passport');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = LogContext;
|