Compare commits

...
9 Commits
Author SHA1 Message Date
Dave Horton 7382bf6bd6 bump version 2022-04-06 08:18:08 -04:00
Dave Horton abfce38150 logging 2022-04-01 15:12:44 -04:00
Dave Horton d8035c978e bugfix: error writing call counts 2022-04-01 15:09:46 -04:00
Dave Horton 91cd677ad8 write call_counts time series data tracking inbound call counts by account 2022-04-01 13:08:25 -04:00
Dave Horton 17b53438e2 track account level calls if env JAMBONES_TRACK_ACCOUNT_CALLS is set 2022-04-01 06:51:44 -04:00
Dave Horton f1e2f192b7 Bugfix/mem leak (#29)
* wait for 200 OK to BYE before closing connection to drachtio

* minor logging
2022-03-27 21:50:09 -04:00
Dave Horton 0af8bcc348 remove dlg event handlers on destroy 2022-03-27 20:23:30 -04:00
Dave Horton e067125974 de-link Dialogs so they can be GC'ed at call end 2022-03-27 19:43:39 -04:00
Dave Horton 2dadde64f4 write otel trace_id to call history 2022-03-23 09:29:22 -04:00
7 changed files with 57 additions and 35 deletions
+1 -1
View File
@@ -8,7 +8,7 @@
"jsx": false,
"modules": false
},
"ecmaVersion": 2018
"ecmaVersion": 2020
},
"plugins": ["promise"],
"rules": {
+1 -1
View File
@@ -1,4 +1,4 @@
FROM node:17.7.1-slim
FROM node:17-slim
WORKDIR /opt/app/
COPY package.json ./
RUN npm install
+2
View File
@@ -14,6 +14,7 @@ const opts = Object.assign({
}, {level: process.env.JAMBONES_LOGLEVEL || 'info'});
const logger = require('pino')(opts);
const {
writeCallCount,
queryCdrs,
writeCdrs,
writeAlerts,
@@ -61,6 +62,7 @@ const {getRtpEngine, setRtpEngines} = require('@jambonz/rtpengine-utils')([], lo
});
srf.locals = {...srf.locals,
stats,
writeCallCount,
queryCdrs,
writeCdrs,
writeAlerts,
+23 -8
View File
@@ -171,7 +171,7 @@ class CallSession extends Emitter {
'-Session-Expires',
'-X-Subspace-Forwarded-For'
],
proxyResponseHeaders: ['all'],
proxyResponseHeaders: ['all', '-X-Trace-ID'],
localSdpB: response.sdp,
localSdpA: async(sdp, res) => {
this.rtpEngineOpts.uac.tag = res.getParsedHeader('To').params.tag;
@@ -241,22 +241,30 @@ class CallSession extends Emitter {
this.req.locals.cdr = {
...this.req.locals.cdr,
answered: true,
answered_at: callStart
answered_at: callStart,
trace_id: uac.res?.get('X-Trace-ID') || '00000000000000000000000000000000'
};
}
this.uas = uas;
this.uac = uac;
[uas, uac].forEach((dlg) => {
dlg.on('destroy', () => {
this.logger.info('call ended with normal termination');
dlg.on('destroy', async() => {
const other = dlg.other;
this.rtpEngineResource.destroy().catch((err) => {});
this.activeCallIds.delete(this.req.get('Call-ID'));
dlg.other.destroy().catch((e) => {});
try {
await other.destroy();
} catch (err) {}
this.unsubscribeDTMF(this.logger, this.req.get('Call-ID'), this.rtpEngineOpts.uas.tag);
if (process.env.JAMBONES_HOSTING) {
if (process.env.JAMBONES_HOSTING || process.env.JAMBONES_TRACK_ACCOUNT_CALLS) {
const {account_sid} = this.req.locals;
this.decrKey(this.callCountKey)
.then((count) => this.logger.debug({key: this.callCountKey},
`after hangup there are ${count} active calls for this account`))
.then((count) => {
this.logger.info(
{key: this.callCountKey},
`after hangup there are ${count} active calls for this account`);
return this.req.srf.locals.writeCallCount({account_sid, calls_in_progress: count});
})
.catch((err) => this.logger.error({err}, 'Error decrementing call count'));
}
@@ -274,6 +282,13 @@ class CallSession extends Emitter {
trunk
}).catch((err) => this.logger.error({err}, 'Error writing cdr for completed call'));
}
/* de-link the 2 Dialogs for GC */
dlg.removeAllListeners();
other.removeAllListeners();
dlg.other = null;
other.other = null;
this.logger.info(`call ended with normal termination, there are ${this.activeCallIds.size} active`);
this.srf.endSession(this.req);
});
});
+9 -4
View File
@@ -220,11 +220,11 @@ module.exports = function(srf, logger) {
};
const checkLimits = async(req, res, next) => {
if (!process.env.JAMBONES_HOSTING) return next(); // skip
if (!process.env.JAMBONES_HOSTING && !process.env.JAMBONES_TRACK_ACCOUNT_CALLS) return next(); // skip
const {incrKey, decrKey} = req.srf.locals.realtimeDbHelpers;
const {logger, account_sid} = req.locals;
const {writeAlerts, AlertType} = req.srf.locals;
const {writeCallCount, writeAlerts, AlertType} = req.srf.locals;
assert(account_sid);
const key = makeCallCountKey(account_sid);
@@ -233,10 +233,11 @@ module.exports = function(srf, logger) {
if (status > 200) {
decrKey(key)
.then((count) => {
logger.debug({key}, `after rejection there are ${count} active calls for this account`);
logger.info({key}, `after rejection there are ${count} active calls for this account`);
debug({key}, `after rejection there are ${count} active calls for this account`);
return;
return count;
})
.then((count) => writeCallCount({account_sid, calls_in_progress: count}))
.catch((err) => logger.error({err}, 'checkLimits: decrKey err'));
}
});
@@ -244,6 +245,10 @@ module.exports = function(srf, logger) {
try {
/* increment the call count */
const calls = await incrKey(key);
writeCallCount({account_sid, calls_in_progress: calls})
.then(() => logger.info(`checkLimits: after incrementing there are ${calls} active calls for this account`))
.catch((err) => logger.error({err}, 'checkLimits: error writing call count'));
if (!process.env.JAMBONES_HOSTING) return next();
/* compare to account's limit, though avoid db hit when call count is low */
const minLimit = process.env.MIN_CALL_LIMIT ?
+19 -19
View File
@@ -15,7 +15,7 @@
"@jambonz/realtimedb-helpers": "^0.4.24",
"@jambonz/rtpengine-utils": "^0.3.1",
"@jambonz/stats-collector": "^0.1.6",
"@jambonz/time-series": "^0.1.6",
"@jambonz/time-series": "^0.1.9",
"aws-sdk": "^2.1036.0",
"bent": "^7.3.12",
"cidr-matcher": "^2.1.1",
@@ -1520,9 +1520,9 @@
}
},
"node_modules/@jambonz/time-series": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.1.6.tgz",
"integrity": "sha512-EFO1ZFUazHLCzDYkAbpke0IfmPRogLkGg+KGWwz3SGpnuiltfohQ3TsJ5KG8Gp9mXqdpkyAioWSdaJxGDquthQ==",
"version": "0.1.9",
"resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.1.9.tgz",
"integrity": "sha512-FLD7mLGEMToG7s6LGWr/GtNp61753RBxyYuKSxCVI6G14bm6ydgcBdG85h8EGTVQlIp9dnwbn5ebSVsGb8a46w==",
"dependencies": {
"debug": "^4.3.1",
"influx": "^5.8.0"
@@ -4289,9 +4289,9 @@
}
},
"node_modules/minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
},
"node_modules/mkdirp": {
"version": "0.5.5",
@@ -4399,9 +4399,9 @@
}
},
"node_modules/node-forge": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.2.1.tgz",
"integrity": "sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w==",
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.0.tgz",
"integrity": "sha512-08ARB91bUi6zNKzVmaj3QO7cr397uiDT2nJ63cHjyNtCTWIgvS47j3eT0WfzUwS9+6Z5YshRaoasFkXCKrIYbA==",
"engines": {
"node": ">= 6.13.0"
}
@@ -7278,9 +7278,9 @@
}
},
"@jambonz/time-series": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.1.6.tgz",
"integrity": "sha512-EFO1ZFUazHLCzDYkAbpke0IfmPRogLkGg+KGWwz3SGpnuiltfohQ3TsJ5KG8Gp9mXqdpkyAioWSdaJxGDquthQ==",
"version": "0.1.9",
"resolved": "https://registry.npmjs.org/@jambonz/time-series/-/time-series-0.1.9.tgz",
"integrity": "sha512-FLD7mLGEMToG7s6LGWr/GtNp61753RBxyYuKSxCVI6G14bm6ydgcBdG85h8EGTVQlIp9dnwbn5ebSVsGb8a46w==",
"requires": {
"debug": "^4.3.1",
"influx": "^5.8.0"
@@ -9404,9 +9404,9 @@
}
},
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
},
"mkdirp": {
"version": "0.5.5",
@@ -9492,9 +9492,9 @@
}
},
"node-forge": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.2.1.tgz",
"integrity": "sha512-Fcvtbb+zBcZXbTTVwqGA5W+MKBj56UjVRevvchv5XrcyXbmNdesfZL37nlcWOfpgHhgmxApw3tQbTr4CqNmX4w=="
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.0.tgz",
"integrity": "sha512-08ARB91bUi6zNKzVmaj3QO7cr397uiDT2nJ63cHjyNtCTWIgvS47j3eT0WfzUwS9+6Z5YshRaoasFkXCKrIYbA=="
},
"node-noop": {
"version": "0.0.1",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "sbc-inbound",
"version": "v0.7.4",
"version": "v0.7.5",
"main": "app.js",
"engines": {
"node": ">= 12.0.0"
@@ -31,7 +31,7 @@
"@jambonz/realtimedb-helpers": "^0.4.24",
"@jambonz/rtpengine-utils": "^0.3.1",
"@jambonz/stats-collector": "^0.1.6",
"@jambonz/time-series": "^0.1.6",
"@jambonz/time-series": "^0.1.9",
"aws-sdk": "^2.1036.0",
"bent": "^7.3.12",
"cidr-matcher": "^2.1.1",