function ecsFormat()

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)
  }
}