@jambonz/time-series 0.1.8 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +82 -60
- package/package.json +2 -2
- package/test/unit-tests.js +12 -1
package/index.js
CHANGED
|
@@ -5,6 +5,7 @@ const AlertType = {
|
|
|
5
5
|
WEBHOOK_CONNECTION_FAILURE: 'webhook-connection-failure',
|
|
6
6
|
WEBHOOK_URL_NOTFOUND: 'webhook-url-notfound',
|
|
7
7
|
WEBHOOK_AUTH_FAILURE: 'webhook-auth-failure',
|
|
8
|
+
INVALID_APP_PAYLOAD: 'invalid-app-payload',
|
|
8
9
|
TTS_NOT_PROVISIONED: 'no-tts',
|
|
9
10
|
STT_NOT_PROVISIONED: 'no-stt',
|
|
10
11
|
TTS_FAILURE: 'tts-failure',
|
|
@@ -79,85 +80,81 @@ const writeData = async(client) => {
|
|
|
79
80
|
}
|
|
80
81
|
};
|
|
81
82
|
|
|
82
|
-
const createCallCountsQuery = ({
|
|
83
|
-
let sql =
|
|
84
|
-
if (days) sql +=
|
|
83
|
+
const createCallCountsQuery = ({page, page_size, days, start, end}) => {
|
|
84
|
+
let sql = 'SELECT * from call_counts WHERE account_sid = $account_sid ';
|
|
85
|
+
if (days) sql += 'AND time > $timestamp ';
|
|
85
86
|
else {
|
|
86
|
-
if (start) sql +=
|
|
87
|
-
if (end) sql +=
|
|
87
|
+
if (start) sql += 'AND time >= $start ';
|
|
88
|
+
if (end) sql += 'AND time <= $end ';
|
|
88
89
|
}
|
|
89
90
|
sql += ' ORDER BY time DESC';
|
|
90
|
-
if (page_size) sql +=
|
|
91
|
-
if (page) sql +=
|
|
92
|
-
//console.log(sql);
|
|
91
|
+
if (page_size) sql += ' LIMIT $page_size';
|
|
92
|
+
if (page) sql += ' OFFSET $offset';
|
|
93
93
|
return sql;
|
|
94
94
|
};
|
|
95
95
|
|
|
96
|
-
const createCallCountsCountQuery = ({
|
|
97
|
-
let sql =
|
|
98
|
-
if (days) sql +=
|
|
96
|
+
const createCallCountsCountQuery = ({days, start, end}) => {
|
|
97
|
+
let sql = 'SELECT COUNT(calls_in_progress) from call_counts WHERE account_sid = $account_sid ';
|
|
98
|
+
if (days) sql += 'AND time > $timestamp ';
|
|
99
99
|
else {
|
|
100
|
-
if (start) sql +=
|
|
101
|
-
if (end) sql +=
|
|
100
|
+
if (start) sql += 'AND time >= $start ';
|
|
101
|
+
if (end) sql += 'AND time <= $end ';
|
|
102
102
|
}
|
|
103
|
-
//console.log(sql);
|
|
104
103
|
return sql;
|
|
105
104
|
};
|
|
106
105
|
|
|
107
|
-
const createCdrQuery = ({
|
|
108
|
-
let sql =
|
|
109
|
-
if (trunk) sql +=
|
|
110
|
-
if (direction) sql +=
|
|
111
|
-
if (['true', 'false'].includes(answered)) sql +=
|
|
112
|
-
if (days) sql +=
|
|
106
|
+
const createCdrQuery = ({page, page_size, trunk, direction, answered, days, start, end}) => {
|
|
107
|
+
let sql = 'SELECT * from cdrs WHERE account_sid = $account_sid ';
|
|
108
|
+
if (trunk) sql += 'AND trunk = $trunk ';
|
|
109
|
+
if (direction) sql += 'AND direction = $direction ';
|
|
110
|
+
if (['true', 'false'].includes(answered)) sql += 'AND answered = $answered ';
|
|
111
|
+
if (days) sql += 'AND time > $timestamp ';
|
|
113
112
|
else {
|
|
114
|
-
if (start) sql +=
|
|
115
|
-
if (end) sql +=
|
|
113
|
+
if (start) sql += 'AND time >= $start ';
|
|
114
|
+
if (end) sql += 'AND time <= $end ';
|
|
116
115
|
}
|
|
117
116
|
sql += ' ORDER BY time DESC';
|
|
118
|
-
if (page_size) sql +=
|
|
119
|
-
if (page) sql +=
|
|
120
|
-
//console.log(sql);
|
|
117
|
+
if (page_size) sql += ' LIMIT $page_size';
|
|
118
|
+
if (page) sql += ' OFFSET $offset';
|
|
121
119
|
return sql;
|
|
122
120
|
};
|
|
123
|
-
const createCdrCountQuery = ({
|
|
124
|
-
let sql =
|
|
125
|
-
if (trunk) sql +=
|
|
126
|
-
if (direction) sql +=
|
|
127
|
-
if (['true', 'false'].includes(answered)) sql +=
|
|
128
|
-
if (days) sql +=
|
|
121
|
+
const createCdrCountQuery = ({trunk, direction, answered, days, start, end}) => {
|
|
122
|
+
let sql = 'SELECT COUNT(sip_callid) from cdrs WHERE account_sid = $account_sid ';
|
|
123
|
+
if (trunk) sql += 'AND trunk = $trunk ';
|
|
124
|
+
if (direction) sql += 'AND direction = $direction ';
|
|
125
|
+
if (['true', 'false'].includes(answered)) sql += 'AND answered = $answered ';
|
|
126
|
+
if (days) sql += 'AND time > $timestamp ';
|
|
129
127
|
else {
|
|
130
|
-
if (start) sql +=
|
|
131
|
-
if (end) sql +=
|
|
128
|
+
if (start) sql += 'AND time >= $start ';
|
|
129
|
+
if (end) sql += 'AND time <= $end ';
|
|
132
130
|
}
|
|
133
|
-
//console.log(sql);
|
|
134
131
|
return sql;
|
|
135
132
|
};
|
|
136
133
|
|
|
137
|
-
const createAlertsQuery = ({
|
|
138
|
-
let sql =
|
|
139
|
-
if (
|
|
140
|
-
if (
|
|
134
|
+
const createAlertsQuery = ({target_sid, alert_type, page, page_size, days, start, end}) => {
|
|
135
|
+
let sql = 'SELECT * FROM alerts WHERE account_sid = $account_sid ';
|
|
136
|
+
if (target_sid) sql += 'AND target_sid = $target_sid ';
|
|
137
|
+
if (alert_type) sql += 'AND alert_type = $alert_type ';
|
|
138
|
+
if (days) sql += 'AND time > $timestamp ';
|
|
141
139
|
else {
|
|
142
|
-
if (start) sql +=
|
|
143
|
-
if (end) sql +=
|
|
140
|
+
if (start) sql += 'AND time >= $start ';
|
|
141
|
+
if (end) sql += 'AND time <= $end ';
|
|
144
142
|
}
|
|
145
143
|
sql += ' ORDER BY time DESC';
|
|
146
|
-
if (page_size) sql +=
|
|
147
|
-
if (page) sql +=
|
|
148
|
-
//console.log(sql);
|
|
144
|
+
if (page_size) sql += ' LIMIT $page_size';
|
|
145
|
+
if (page) sql += ' OFFSET $offset';
|
|
149
146
|
return sql;
|
|
150
147
|
};
|
|
151
148
|
|
|
152
|
-
const createAlertsCountQuery = ({
|
|
153
|
-
let sql =
|
|
154
|
-
if (
|
|
155
|
-
if (
|
|
149
|
+
const createAlertsCountQuery = ({target_sid, alert_type, days, start, end}) => {
|
|
150
|
+
let sql = 'SELECT COUNT(message) FROM alerts WHERE account_sid = $account_sid ';
|
|
151
|
+
if (target_sid) sql += 'AND target_sid = $target_sid ';
|
|
152
|
+
if (alert_type) sql += 'AND alert_type = $alert_type ';
|
|
153
|
+
if (days) sql += 'AND time > $timestamp ';
|
|
156
154
|
else {
|
|
157
|
-
if (start) sql +=
|
|
158
|
-
if (end) sql +=
|
|
155
|
+
if (start) sql += 'AND time >= $start ';
|
|
156
|
+
if (end) sql += 'AND time <= $end ';
|
|
159
157
|
}
|
|
160
|
-
//console.log(sql);
|
|
161
158
|
return sql;
|
|
162
159
|
};
|
|
163
160
|
|
|
@@ -194,14 +191,15 @@ const queryCallCounts = async(client, opts) => {
|
|
|
194
191
|
page: opts.page,
|
|
195
192
|
data: []
|
|
196
193
|
};
|
|
194
|
+
const params = generateBindParameters(opts);
|
|
197
195
|
const sqlTotal = createCallCountsCountQuery(opts);
|
|
198
|
-
const obj = await client.queryRaw(sqlTotal);
|
|
196
|
+
const obj = await client.queryRaw(sqlTotal, { placeholders: params});
|
|
199
197
|
//console.log(`sqlTotal: ${sqlTotal}, results: ${JSON.stringify(obj)}`);
|
|
200
198
|
if (!obj.results || !obj.results[0].series) return response;
|
|
201
199
|
response.total = obj.results[0].series[0].values[0][1];
|
|
202
200
|
|
|
203
201
|
const sql = createCallCountsQuery(opts);
|
|
204
|
-
const res = await client.queryRaw(sql);
|
|
202
|
+
const res = await client.queryRaw(sql, { placeholders: params});
|
|
205
203
|
//console.log(`sql: ${sqlTotal}, results: ${JSON.stringify(res)}`);
|
|
206
204
|
if (res.results[0].series && res.results[0].series.length) {
|
|
207
205
|
const {columns, values} = res.results[0].series[0];
|
|
@@ -254,14 +252,15 @@ const queryCdrs = async(client, opts) => {
|
|
|
254
252
|
page: opts.page,
|
|
255
253
|
data: []
|
|
256
254
|
};
|
|
255
|
+
const params = generateBindParameters(opts);
|
|
257
256
|
const sqlTotal = createCdrCountQuery(opts);
|
|
258
|
-
const obj = await client.queryRaw(sqlTotal);
|
|
257
|
+
const obj = await client.queryRaw(sqlTotal, { placeholders: params});
|
|
259
258
|
//console.log(`sql: ${sqlTotal}, results: ${JSON.stringify(obj)}`);
|
|
260
259
|
if (!obj.results || !obj.results[0].series) return response;
|
|
261
260
|
response.total = obj.results[0].series[0].values[0][1];
|
|
262
261
|
|
|
263
262
|
const sql = createCdrQuery(opts);
|
|
264
|
-
const res = await client.queryRaw(sql);
|
|
263
|
+
const res = await client.queryRaw(sql, { placeholders: params});
|
|
265
264
|
if (res.results[0].series && res.results[0].series.length) {
|
|
266
265
|
const {columns, values} = res.results[0].series[0];
|
|
267
266
|
const data = values.map((v) => {
|
|
@@ -284,7 +283,7 @@ const writeAlerts = async(client, alerts) => {
|
|
|
284
283
|
if (!client.locals.initialized) await initDatabase(client, 'alerts');
|
|
285
284
|
alerts = (Array.isArray(alerts) ? alerts : [alerts])
|
|
286
285
|
.map((alert) => {
|
|
287
|
-
const {alert_type, account_sid, url, status, vendor, count, detail, timestamp} = alert;
|
|
286
|
+
const {alert_type, account_sid, target_sid, url, status, vendor, count, detail, timestamp} = alert;
|
|
288
287
|
let message = alert.message;
|
|
289
288
|
if (!message) {
|
|
290
289
|
switch (alert_type) {
|
|
@@ -300,6 +299,9 @@ const writeAlerts = async(client, alerts) => {
|
|
|
300
299
|
case AlertType.WEBHOOK_URL_NOTFOUND:
|
|
301
300
|
message = `webhook url not found: ${url}`;
|
|
302
301
|
break;
|
|
302
|
+
case AlertType.INVALID_APP_PAYLOAD:
|
|
303
|
+
message = `${url} return invalid app payload`;
|
|
304
|
+
break;
|
|
303
305
|
case AlertType.TTS_NOT_PROVISIONED:
|
|
304
306
|
message = `text to speech credentials for ${vendor} have not been provisioned`;
|
|
305
307
|
break;
|
|
@@ -329,7 +331,9 @@ const writeAlerts = async(client, alerts) => {
|
|
|
329
331
|
break;
|
|
330
332
|
}
|
|
331
333
|
}
|
|
332
|
-
|
|
334
|
+
let fields = { message };
|
|
335
|
+
if (target_sid) fields = Object.assign(fields, {target_sid});
|
|
336
|
+
const obj = {measurement: 'alerts', fields: fields, tags: { alert_type, account_sid }};
|
|
333
337
|
if (timestamp) obj.timestamp = timestamp;
|
|
334
338
|
if (detail) obj.fields.detail = detail;
|
|
335
339
|
return obj;
|
|
@@ -342,6 +346,13 @@ const writeAlerts = async(client, alerts) => {
|
|
|
342
346
|
return;
|
|
343
347
|
};
|
|
344
348
|
|
|
349
|
+
const generateBindParameters = (opts) => {
|
|
350
|
+
const params = {...opts};
|
|
351
|
+
if (opts.days) params.timestamp = Date.now() * 1000000 - opts.days * 24 * 60 * 60 * 1000000000;
|
|
352
|
+
if (opts.page) params.offset = opts.page - 1 >= 0 && opts.page_size >= 0 ? (opts.page - 1) * opts.page_size : 0;
|
|
353
|
+
return params;
|
|
354
|
+
};
|
|
355
|
+
|
|
345
356
|
const queryAlerts = async(client, opts) => {
|
|
346
357
|
if (!client.locals.initialized) await initDatabase(client, 'alerts');
|
|
347
358
|
const response = {
|
|
@@ -350,14 +361,15 @@ const queryAlerts = async(client, opts) => {
|
|
|
350
361
|
page: opts.page,
|
|
351
362
|
data: []
|
|
352
363
|
};
|
|
364
|
+
const params = generateBindParameters(opts);
|
|
353
365
|
const sqlTotal = createAlertsCountQuery(opts);
|
|
354
|
-
const obj = await client.queryRaw(sqlTotal);
|
|
366
|
+
const obj = await client.queryRaw(sqlTotal, { placeholders: params});
|
|
355
367
|
//console.log(`query total alerts: ${sqlTotal}: ${JSON.stringify(obj)}`);
|
|
356
368
|
if (!obj.results || !obj.results[0].series) return response;
|
|
357
369
|
response.total = obj.results[0].series[0].values[0][1];
|
|
358
370
|
|
|
359
371
|
const sql = createAlertsQuery(opts);
|
|
360
|
-
const res = await client.queryRaw(sql);
|
|
372
|
+
const res = await client.queryRaw(sql, { placeholders: params});
|
|
361
373
|
if (res.results[0].series && res.results[0].series.length) {
|
|
362
374
|
const {columns, values} = res.results[0].series[0];
|
|
363
375
|
const data = values.map((v) => {
|
|
@@ -379,6 +391,7 @@ module.exports = (logger, opts) => {
|
|
|
379
391
|
|
|
380
392
|
const cdrClient = new Influx.InfluxDB({database: 'cdrs', schemas: schemas.cdr, ...opts});
|
|
381
393
|
const alertClient = new Influx.InfluxDB({database: 'alerts', schemas: schemas.alerts, ...opts});
|
|
394
|
+
const callCountClient = new Influx.InfluxDB({database: 'call_counts', schemas: schemas.call_counts, ...opts});
|
|
382
395
|
|
|
383
396
|
cdrClient.locals = {
|
|
384
397
|
db: 'cdrs',
|
|
@@ -396,15 +409,24 @@ module.exports = (logger, opts) => {
|
|
|
396
409
|
commitInterval: opts.commitInterval || 10,
|
|
397
410
|
data: []
|
|
398
411
|
};
|
|
412
|
+
callCountClient.locals = {
|
|
413
|
+
db: 'call_counts',
|
|
414
|
+
initialized: false,
|
|
415
|
+
writing: false,
|
|
416
|
+
commitSize: opts.commitSize || 1,
|
|
417
|
+
commitInterval: opts.commitInterval || 10,
|
|
418
|
+
data: []
|
|
419
|
+
};
|
|
399
420
|
|
|
400
421
|
if (opts.commitSize > 1 && opts.commitInterval && opts.commitInterval > 2) {
|
|
422
|
+
setInterval(writeData.bind(null, callCountClient), opts.commitInterval * 1000);
|
|
401
423
|
setInterval(writeData.bind(null, cdrClient), opts.commitInterval * 1000);
|
|
402
424
|
setInterval(writeData.bind(null, alertClient), opts.commitInterval * 1000);
|
|
403
425
|
}
|
|
404
426
|
|
|
405
427
|
return {
|
|
406
|
-
writeCallCount: writeCallCount.bind(null,
|
|
407
|
-
queryCallCounts: queryCallCounts.bind(null,
|
|
428
|
+
writeCallCount: writeCallCount.bind(null, callCountClient),
|
|
429
|
+
queryCallCounts: queryCallCounts.bind(null, callCountClient),
|
|
408
430
|
writeCdrs: writeCdrs.bind(null, cdrClient),
|
|
409
431
|
queryCdrs: queryCdrs.bind(null, cdrClient),
|
|
410
432
|
writeAlerts: writeAlerts.bind(null, alertClient),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jambonz/time-series",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"description": "write and query data to time series daetabase",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"license": "MIT",
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"debug": "^4.3.1",
|
|
15
|
-
"influx": "^5.
|
|
15
|
+
"influx": "^5.9.3"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
18
|
"eslint": "^7.23.0",
|
package/test/unit-tests.js
CHANGED
|
@@ -73,6 +73,12 @@ test('write timeseries data', async(t) => {
|
|
|
73
73
|
account_sid: 'yyyy',
|
|
74
74
|
url: 'http://foo.bar'
|
|
75
75
|
},
|
|
76
|
+
{
|
|
77
|
+
alert_type: AlertType.INVALID_APP_PAYLOAD,
|
|
78
|
+
account_sid: 'yyyy',
|
|
79
|
+
target_sid: 'zzzz',
|
|
80
|
+
message: 'invalid app payload'
|
|
81
|
+
},
|
|
76
82
|
{
|
|
77
83
|
alert_type: AlertType.TTS_NOT_PROVISIONED,
|
|
78
84
|
account_sid: 'yyyy',
|
|
@@ -117,7 +123,12 @@ test('write timeseries data', async(t) => {
|
|
|
117
123
|
|
|
118
124
|
result = await queryAlerts({account_sid: 'yyyy', page: 1, page_size: 25, days: 7});
|
|
119
125
|
//console.log(JSON.stringify(result));
|
|
120
|
-
t.ok(result.data.length ===
|
|
126
|
+
t.ok(result.data.length === 12, 'queried alerts');
|
|
127
|
+
t.ok(result.data[0].target_sid === null)
|
|
128
|
+
|
|
129
|
+
result = await queryAlerts({account_sid: 'yyyy', target_sid: 'zzzz', page: 1, page_size: 25, days: 7});
|
|
130
|
+
t.ok(result.data.length === 1, 'queried alerts by target_sid');
|
|
131
|
+
t.ok(result.data[0].target_sid === 'zzzz')
|
|
121
132
|
|
|
122
133
|
result = await writeCallCount(
|
|
123
134
|
{
|