'use strict'; const _ = require('lodash'); const moment = require('moment'); const format = require('util').format; const EOL = require('os').EOL; class EntryContext { constructor(logContext, options) { this._timeCreated = moment(); this._appContext = logContext._appContext; this._logContext = logContext; this._env = logContext._appContext._env; this._req = logContext._options.req; this._res = logContext._options.res; this._options = options; var messageArgs = Array.prototype.slice.call(options.messageArgs || []); this._error = processError(messageArgs); this._customFieldObject = processCustomFields(this._appContext, messageArgs); this._message = buildMessage(this._error, messageArgs, { addStack: options.addStack }); } get customFields() { return this._customFieldObject; } get timeCreated() { return this._timeCreated; } get timeCreatedNanos() { const nanosecPerMillisec = 1e6; return this._timeCreated.valueOf() * nanosecPerMillisec; } get timezoneOffset() { return this._timeCreated.format('Z'); } get level() { return this._options.level; } get component() { return this._options.component; } get csnComponent() { return this._appContext._options.csnComponent; } get user() { const req = this._req; return req && req.user && req.user.id; } get sessionId() { const req = this._req; return req && req.session && req.session.id; } get rootContextId() { const sapPassport = this._logContext._sapPassport; return sapPassport && sapPassport.rootContextID; } get transactionId() { const sapPassport = this._logContext._sapPassport; return sapPassport && this._logContext._sapPassport.transactionID; } get connectionId() { const sapPassport = this._logContext._sapPassport; return sapPassport && this._logContext._sapPassport.connectionID; } get connectionCounter() { const sapPassport = this._logContext._sapPassport; if (sapPassport && sapPassport.hasOwnProperty('connectionCounter')) { return sapPassport.connectionCounter.toString(); } } get id() { return this._logContext.id; } get correlationId() { return this._logContext.correlationId; } get type() { return this._options.type; } get loggingToolName() { return this._options.loggingToolName; } get containerId() { return this._env.instanceIp; } get componentType() { return 'application'; } get componentId() { return this._env.vcapApp['application_id']; } get componentName() { return this._env.vcapApp['application_name']; } get componentInstance() { return this._env.vcapApp['instance_index']; } get sourceInstance() { return this._env.vcapApp['instance_index']; } get organizationId() { return this._env.vcapApp['organization_id']; } get organizationName() { return this._env.vcapApp['organization_name']; } get spaceId() { return this._env.vcapApp['space_id']; } get spaceName() { return this._env.vcapApp['space_name']; } get hasRequest() { return !!this._req; } get reqPath() { const req = this._req; return req.originalUrl || req.url; } get reqSize() { return this._req.headers['content-length']; } get reqReceivedAt() { return this._logContext._timeCreated; } get reqProtocol() { const version = this._req.httpVersion; let protocol = 'HTTP'; if (version) { protocol += '/' + version; } return protocol; } get reqMethod() { return this._req.method; } get reqDirection() { return 'IN'; } get xForwardedFor() { return this._req.headers['x-forwarded-for']; } get referer() { return this._req.headers['referer']; } get remoteHost() { return this._req.connection.remoteAddress; } get remoteIp() { return this._req.connection.remoteAddress; } get remotePort() { return this._req.connection.remotePort; } get resSentAt() { return this._timeCreated; } get resTime() { return this.resSentAt.valueOf() - this.reqReceivedAt.valueOf(); } get resStatus() { return this._res.statusCode; } get resSize() { const resHeaders = this._res.headers; return resHeaders && resHeaders['content-length']; } get resContentType() { const resHeaders = this._res.headers; return resHeaders && resHeaders['content-type']; } get hasError() { return !!this._error; } get error() { return this._error; } set message(str) { this._message = str; } get message() { return this._message; } } function processError(messageArgs) { return isError(messageArgs[0]) ? messageArgs.shift() : null; } function processCustomFields(appContext, messageArgs) { if (messageArgs.length > 0 && appContext._containsCustomField(messageArgs[messageArgs.length - 1])) { let customFields = messageArgs.pop(); return appContext._filterCustomFields(customFields); } return null; } function buildMessage(error, messageArgs, options) { for (let i in messageArgs) { if (isError(messageArgs[i])) { messageArgs[i] = '[Error: ' + messageArgs[i].message + ']'; } else if (_.isDate(messageArgs[i])) { messageArgs[i] = messageArgs[i].toISOString(); } } let message = format.apply(null, messageArgs); if (!error) { return message; } if (message) { message += ': ' + error.message; // like verror & Linux } else { message = error.message; } if (options.addStack && error.stack) { message += EOL + error.stack; } return message; } function isError(err) { return err && typeof err === 'object' && 'stack' in err && 'message' in err; } module.exports = EntryContext;