in packages/ecs-morgan-format/index.js [65:180]
function ecsFormat (opts) {
let format = morgan.combined
let apmIntegration = true
if (opts && typeof opts === 'object') {
// Usage: ecsFormat({ /* opts */ })
if (opts.format != null) {
format = opts.format
}
if (opts.apmIntegration != null) {
apmIntegration = opts.apmIntegration
}
} else if (opts) {
// Usage: ecsFormat(format)
format = opts
opts = {}
} else {
// Usage: ecsFormat()
opts = {}
}
// Resolve to a format function a la morgan's own `getFormatFunction`.
let fmt = morgan[format] || format
if (typeof fmt !== 'function') {
fmt = morgan.compile(fmt)
}
let apm = null
if (apmIntegration && elasticApm && elasticApm.isStarted && elasticApm.isStarted()) {
apm = elasticApm
}
const extraFields = {}
// Set a number of correlation fields from (a) the given options or (b) an
// APM agent, if there is one running.
let serviceName = opts.serviceName
if (serviceName == null && apm) {
// istanbul ignore next
serviceName = (apm.getServiceName
? apm.getServiceName() // added in elastic-apm-node@3.11.0
: apm._conf.serviceName) // fallback to private `_conf`
}
if (serviceName) {
extraFields['service.name'] = serviceName
}
let serviceVersion = opts.serviceVersion
// istanbul ignore next
if (serviceVersion == null && apm) {
serviceVersion = (apm.getServiceVersion
? apm.getServiceVersion() // added in elastic-apm-node@...
: apm._conf.serviceVersion) // fallback to private `_conf`
}
if (serviceVersion) {
extraFields['service.version'] = serviceVersion
}
let serviceEnvironment = opts.serviceEnvironment
if (serviceEnvironment == null && apm) {
// istanbul ignore next
serviceEnvironment = (apm.getServiceEnvironment
? apm.getServiceEnvironment() // added in elastic-apm-node@...
: apm._conf.environment) // fallback to private `_conf`
}
if (serviceEnvironment) {
extraFields['service.environment'] = serviceEnvironment
}
let serviceNodeName = opts.serviceNodeName
if (serviceNodeName == null && apm) {
// istanbul ignore next
serviceNodeName = (apm.getServiceNodeName
? apm.getServiceNodeName() // added in elastic-apm-node@...
: apm._conf.serviceNodeName) // fallback to private `_conf`
}
if (serviceNodeName) {
extraFields['service.node.name'] = serviceNodeName
}
let eventDataset = opts.eventDataset
if (eventDataset == null && serviceName) {
eventDataset = serviceName
}
if (eventDataset) {
extraFields['event.dataset'] = eventDataset
}
return function formatter (token, req, res) {
const ecsFields = {
'@timestamp': new Date().toISOString(),
'log.level': res.statusCode < 500 ? 'info' : 'error',
message: fmt(token, req, res),
'ecs.version': version,
...extraFields
}
// https://www.elastic.co/guide/en/ecs/current/ecs-tracing.html
if (apm) {
const tx = apm.currentTransaction
// istanbul ignore else
if (tx) {
ecsFields['trace.id'] = tx.traceId
ecsFields['transaction.id'] = tx.id
// Not including `span.id` because the way morgan logs (on the HTTP
// Response "finished" event), any spans during the request handler
// are no longer active.
}
}
// https://www.elastic.co/guide/en/ecs/current/ecs-http.html
formatHttpRequest(ecsFields, req)
formatHttpResponse(ecsFields, res)
return stringify(ecsFields)
}
}