diff --git a/lib/call-session.js b/lib/call-session.js index 589b967..a101eab 100644 --- a/lib/call-session.js +++ b/lib/call-session.js @@ -354,6 +354,15 @@ class CallSession extends Emitter { const tags = ['accepted:no', `sipStatus:${err.status}`, `originator:${this.req.locals.originator}`]; this.stats.increment('sbc.terminations', tags); this.logger.info(`call failed to connect to feature server with ${err.status}`); + + /* capture trace_id from the feature server's error response for the CDR */ + if (this.req.locals.cdr && err.res) { + const trace_id = err.res.get('X-Trace-ID'); + if (trace_id) { + this.req.locals.cdr.trace_id = trace_id; + } + } + this.emit('failed'); } else if (err.message !== 'call canceled') { diff --git a/lib/middleware.js b/lib/middleware.js index 123ba9c..25c982e 100644 --- a/lib/middleware.js +++ b/lib/middleware.js @@ -31,6 +31,7 @@ module.exports = function(srf, logger) { queryCallLimits, } = srf.locals.dbHelpers; const {stats, writeCdrs, lookupAuthCarriersForAccountAndSP, getApplicationForDidAndCarrier} = srf.locals; + const {retrieveKey} = srf.locals.realtimeDbHelpers; const initLocals = (req, res, next) => { const callId = req.get('Call-ID'); @@ -60,13 +61,31 @@ module.exports = function(srf, logger) { /* write cdr for non-success response here */ res.once('end', ({status}) => { if (req.locals.cdr && req.locals.cdr.account_sid && status > 200 && 401 !== status) { - const trunk = ['trunk', 'teams'].includes(req.locals.originator) ? req.locals.carrier : req.locals.originator; - writeCdrs({...req.locals.cdr, - terminated_at: Date.now(), - termination_reason: status === 487 === status ? 'caller abandoned' : 'failed', - sip_status: status, - trunk - }).catch((err) => logger.error({err}, 'Error writing cdr for call failure')); + const writeCdr = () => { + const trunk = ['trunk', 'teams'].includes(req.locals.originator) ? + req.locals.carrier : req.locals.originator; + writeCdrs({...req.locals.cdr, + terminated_at: Date.now(), + termination_reason: status === 487 === status ? 'caller abandoned' : 'failed', + sip_status: status, + trunk, + ...(req.locals.application_sid && {application_sid: req.locals.application_sid}) + }).catch((err) => logger.error({err}, 'Error writing cdr for call failure')); + }; + + /* if trace_id is missing, look it up from Redis using the original Call-ID */ + if (!req.locals.cdr.trace_id) { + retrieveKey(`callid:${callId}`) + .then((trace_id) => { + if (trace_id) req.locals.cdr.trace_id = trace_id; + return; + }) + .catch((err) => logger.debug({err, callId}, 'Error retrieving trace_id from Redis')) + .finally(() => writeCdr()) + .catch(() => {}); + } else { + writeCdr(); + } } });