add metrics

This commit is contained in:
Dave Horton
2020-02-18 16:35:09 -05:00
parent b744150b99
commit f5b8853581
6 changed files with 121 additions and 17 deletions
+25 -4
View File
@@ -1,8 +1,7 @@
const Emitter = require('events');
const {getAppserver, isWSS, makeRtpEngineOpts} = require('./utils');
const {isWSS, makeRtpEngineOpts} = require('./utils');
const {forwardInDialogRequests} = require('drachtio-fn-b2b-sugar');
const {parseUri, SipError} = require('drachtio-srf');
const {getRtpEngine} = require('jambonz-rtpengine-utils')(process.env.JAMBONES_RTPENGINES.split(','));
const debug = require('debug')('jambonz:sbc-inbound');
class CallSession extends Emitter {
@@ -13,13 +12,21 @@ class CallSession extends Emitter {
this.srf = req.srf;
this.logger = logger.child({callId: req.get('Call-ID')});
this.getRtpEngine = req.srf.locals.getRtpEngine;
this.getFeatureServer = req.srf.locals.getFeatureServer;
this.stats = this.srf.locals.stats;
this.activeCallIds = this.srf.locals.activeCallIds;
}
async connect() {
const engine = getRtpEngine(this.logger);
this.activeCallIds.add(this.req.get('Call-ID'));
this.stats.gauge('sbc.sip.calls.count', this.activeCallIds.size);
const engine = this.getRtpEngine(this.logger);
if (!engine) {
this.logger.info('No available rtpengines, rejecting call!');
const tags = ['accepted:no', 'sipStatus:480', `originator:${this.req.locals.originator}`];
this.stats.increment('sbc.terminations', tags);
return this.res.send(480);
}
debug(`got engine: ${JSON.stringify(engine)}`);
@@ -31,6 +38,8 @@ class CallSession extends Emitter {
const featureServer = this.getFeatureServer();
if (!featureServer) {
this.logger.info('No available feature servers, rejecting call!');
const tags = ['accepted:no', 'sipStatus:480', `originator:${this.req.locals.originator}`];
this.stats.increment('sbc.terminations', tags);
return this.res.send(480);
}
this.logger.debug(`using feature server ${featureServer}`);
@@ -79,6 +88,8 @@ class CallSession extends Emitter {
}
}
if (this.req.canceled) throw new Error('call canceled');
debug(`sending INVITE to ${proxy} with ${uri}`);
const {uas, uac} = await this.srf.createB2BUA(this.req, this.res, uri, {
proxy,
@@ -102,16 +113,24 @@ class CallSession extends Emitter {
this.logger.info('call connected');
debug('call connected');
this.emit('connected');
const tags = ['accepted:yes', 'sipStatus:200', `originator:${this.req.locals.originator}`];
this.stats.increment('sbc.terminations', tags);
this._setHandlers({uas, uac});
return;
} catch (err) {
this.rtpEngineResource.destroy();
this.activeCallIds.delete(this.req.get('Call-ID'));
this.stats.gauge('sbc.sip.calls.count', this.activeCallIds.size);
if (err instanceof SipError) {
const tags = ['accepted:no', `sipStatus:${err.status}`, `originator:${this.req.locals.originator}`];
this.stats.increment('sbc.terminations', tags);
this.logger.info(`call failed with ${err.status}`);
return this.emit('failed');
}
this.logger.error(err, 'unexpected error routing inbound call');
else if (err.message !== 'call canceled') {
this.logger.error(err, 'unexpected error routing inbound call');
}
}
}
@@ -123,6 +142,8 @@ class CallSession extends Emitter {
dlg.on('destroy', () => {
this.logger.info('call ended');
this.rtpEngineResource.destroy();
this.activeCallIds.delete(this.req.get('Call-ID'));
this.stats.gauge('sbc.sip.calls.count', this.activeCallIds.size);
});
//re-invite
+5 -4
View File
@@ -6,6 +6,7 @@ module.exports = (srf, logger) => {
logger = logger || noopLogger;
let dynamic = true;
let idx = 0;
const stats = srf.locals.stats;
srf.options((req, res) => {
res.send(200);
@@ -14,9 +15,9 @@ module.exports = (srf, logger) => {
const status = req.get('X-FS-Status');
const calls = req.has('X-FS-Calls') ? parseInt(req.get('X-FS-Calls')) : 0;
if (status === 'open') {
if (!contacts) {
if (!contacts.has(uri)) {
logger.info(`adding feature server at ${uri}`);
//stats.gauge('sbc.featureservers', contacts.size + 1);
stats.gauge('sbc.featureservers.count', contacts.size + 1);
}
logger.debug(`Feature server at ${uri} has ${calls} calls`);
contacts.set(uri, {pingTime: new Date(), calls: calls});
@@ -25,7 +26,7 @@ module.exports = (srf, logger) => {
if (contacts.includes(uri)) {
logger.info(`removing feature server at ${uri}`);
contacts.delete(uri);
//stats.gauge('sbc.featureservers', contacts.size + 1);
stats.gauge('sbc.featureservers.count', contacts.size + 1);
}
}
}
@@ -55,7 +56,7 @@ module.exports = (srf, logger) => {
const keys = [ ...contacts.keys() ];
logger.debug({keys}, `there are ${keys.length} feature servers online`);
//stats.gauge('sbc.featureservers', contacts.size);
stats.gauge('sbc.featureservers.count', contacts.size);
}, CHECK_INTERVAL * 1000);
}
+19 -1
View File
@@ -3,9 +3,25 @@ const debug = require('debug')('jambonz:sbc-inbound');
module.exports = function(srf, logger) {
const {lookupSipGatewayBySignalingAddress, lookupAuthHook} = srf.locals.dbHelpers;
const authenticator = require('jambonz-http-authenticator')(lookupAuthHook, logger, {blacklistUnknownRealms: true});
const {stats, activeCallIds} = srf.locals;
function initLocals(req, res, next) {
req.locals = req.locals || {};
const callId = req.get('Call-ID');
req.on('cancel', () => {
logger.info({callId}, 'caller hungup before connecting to feature server');
req.canceled = true;
const tags = ['canceled:yes', 'sipStatus:487'];
if (req.locals.originator) tags.push(`originator:${req.locals.originator}`);
stats.increment('sbc.terminations', tags);
activeCallIds.delete(callId);
stats.gauge('sbc.sip.calls.count', activeCallIds.size);
});
stats.increment('sbc.invites', ['direction:inbound']);
next();
}
async function challengeDeviceCalls(req, res, next) {
req.locals = req.locals || {};
try {
const gateway = await lookupSipGatewayBySignalingAddress(req.source_address, req.source_port);
if (!gateway) {
@@ -19,12 +35,14 @@ module.exports = function(srf, logger) {
if (gateway.application_sid) req.locals.application_sid = gateway.application_sid;
next();
} catch (err) {
stats.increment('sbc.terminations', ['sipStatus:500']);
logger.error(err, `${req.get('Call-ID')} Error looking up related info for inbound call`);
res.send(500);
}
}
return {
initLocals,
challengeDeviceCalls
};
};