@jambonz/time-series 0.1.7 → 0.1.10

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 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',
@@ -49,6 +50,15 @@ const schemas = {
49
50
  'account_sid',
50
51
  'alert_type'
51
52
  ]
53
+ },
54
+ call_counts: {
55
+ measurement: 'call_counts',
56
+ fields: {
57
+ calls_in_progress: Influx.FieldType.INTEGER,
58
+ },
59
+ tags: [
60
+ 'account_sid'
61
+ ]
52
62
  }
53
63
  };
54
64
 
@@ -70,9 +80,33 @@ const writeData = async(client) => {
70
80
  }
71
81
  };
72
82
 
83
+ const createCallCountsQuery = ({account_sid, page, page_size, days, start, end}) => {
84
+ let sql = `SELECT * from call_counts WHERE account_sid = '${account_sid}'`;
85
+ if (days) sql += `AND time > now() - ${days}d `;
86
+ else {
87
+ if (start) sql += `AND time >= '${start}' `;
88
+ if (end) sql += `AND time <= '${end}' `;
89
+ }
90
+ sql += ' ORDER BY time DESC';
91
+ if (page_size) sql += ` LIMIT ${page_size}`;
92
+ if (page) sql += ` OFFSET ${(page - 1) * page_size}`;
93
+ //console.log(sql);
94
+ return sql;
95
+ };
96
+
97
+ const createCallCountsCountQuery = ({account_sid, days, start, end}) => {
98
+ let sql = `SELECT COUNT(calls_in_progress) from call_counts WHERE account_sid = '${account_sid}' `;
99
+ if (days) sql += `AND time > now() - ${days}d `;
100
+ else {
101
+ if (start) sql += `AND time >= '${start}' `;
102
+ if (end) sql += `AND time <= '${end}' `;
103
+ }
104
+ //console.log(sql);
105
+ return sql;
106
+ };
73
107
 
74
108
  const createCdrQuery = ({account_sid, page, page_size, trunk, direction, answered, days, start, end}) => {
75
- let sql = `SELECT * from cdrs WHERE account_sid = '${account_sid}' `;
109
+ let sql = `SELECT * from cdrs WHERE account_sid = '${account_sid}'`;
76
110
  if (trunk) sql += `AND trunk = '${trunk}' `;
77
111
  if (direction) sql += `AND direction = '${direction}' `;
78
112
  if (['true', 'false'].includes(answered)) sql += `AND answered = '${answered}' `;
@@ -101,8 +135,9 @@ const createCdrCountQuery = ({account_sid, trunk, direction, answered, days, sta
101
135
  return sql;
102
136
  };
103
137
 
104
- const createAlertsQuery = ({account_sid, alert_type, page, page_size, days, start, end}) => {
138
+ const createAlertsQuery = ({account_sid, target_sid, alert_type, page, page_size, days, start, end}) => {
105
139
  let sql = `SELECT * FROM alerts WHERE account_sid = '${account_sid}' `;
140
+ if (target_sid) sql += `AND target_sid = '${target_sid}' `;
106
141
  if (alert_type) sql += `AND alert_type = '${alert_type}' `;
107
142
  if (days) sql += `AND time > now() - ${days}d `;
108
143
  else {
@@ -116,8 +151,9 @@ const createAlertsQuery = ({account_sid, alert_type, page, page_size, days, star
116
151
  return sql;
117
152
  };
118
153
 
119
- const createAlertsCountQuery = ({account_sid, alert_type, days, start, end}) => {
154
+ const createAlertsCountQuery = ({account_sid, target_sid, alert_type, days, start, end}) => {
120
155
  let sql = `SELECT COUNT(message) FROM alerts WHERE account_sid = '${account_sid}' `;
156
+ if (target_sid) sql += `AND target_sid = '${target_sid}' `;
121
157
  if (alert_type) sql += `AND alert_type = '${alert_type}' `;
122
158
  if (days) sql += `AND time > now() - ${days}d `;
123
159
  else {
@@ -136,6 +172,57 @@ const initDatabase = async(client, dbName) => {
136
172
  client.locals.initialized = true;
137
173
  };
138
174
 
175
+ const writeCallCount = async(client, count) => {
176
+ if (!client.locals.initialized) await initDatabase(client, 'call_counts');
177
+ const {account_sid, ...fields} = count;
178
+ const data = {
179
+ measurement: 'call_counts',
180
+ fields,
181
+ tags: {
182
+ account_sid
183
+ }
184
+ };
185
+ client.locals.data = [...client.locals.data, ...[data]];
186
+ if (client.locals.data.length >= client.locals.commitSize) {
187
+ await writeData(client);
188
+ }
189
+ return;
190
+ };
191
+
192
+ const queryCallCounts = async(client, opts) => {
193
+ if (!client.locals.initialized) await initDatabase(client, 'call_counts');
194
+ const response = {
195
+ total: 0,
196
+ page_size: opts.page_size,
197
+ page: opts.page,
198
+ data: []
199
+ };
200
+ const sqlTotal = createCallCountsCountQuery(opts);
201
+ const obj = await client.queryRaw(sqlTotal);
202
+ //console.log(`sqlTotal: ${sqlTotal}, results: ${JSON.stringify(obj)}`);
203
+ if (!obj.results || !obj.results[0].series) return response;
204
+ response.total = obj.results[0].series[0].values[0][1];
205
+
206
+ const sql = createCallCountsQuery(opts);
207
+ const res = await client.queryRaw(sql);
208
+ //console.log(`sql: ${sqlTotal}, results: ${JSON.stringify(res)}`);
209
+ if (res.results[0].series && res.results[0].series.length) {
210
+ const {columns, values} = res.results[0].series[0];
211
+ const data = values.map((v) => {
212
+ const obj = {};
213
+ v.forEach((val, idx) => {
214
+ v.forEach((val, idx) => {
215
+ const key = columns[idx];
216
+ obj[key] = val;
217
+ });
218
+ });
219
+ return obj;
220
+ });
221
+ response.data = data;
222
+ }
223
+ return response;
224
+ };
225
+
139
226
  const writeCdrs = async(client, cdrs) => {
140
227
  if (!client.locals.initialized) await initDatabase(client, 'cdrs');
141
228
  cdrs = (Array.isArray(cdrs) ? cdrs : [cdrs])
@@ -200,7 +287,7 @@ const writeAlerts = async(client, alerts) => {
200
287
  if (!client.locals.initialized) await initDatabase(client, 'alerts');
201
288
  alerts = (Array.isArray(alerts) ? alerts : [alerts])
202
289
  .map((alert) => {
203
- const {alert_type, account_sid, url, status, vendor, count, detail, timestamp} = alert;
290
+ const {alert_type, account_sid, target_sid, url, status, vendor, count, detail, timestamp} = alert;
204
291
  let message = alert.message;
205
292
  if (!message) {
206
293
  switch (alert_type) {
@@ -216,6 +303,9 @@ const writeAlerts = async(client, alerts) => {
216
303
  case AlertType.WEBHOOK_URL_NOTFOUND:
217
304
  message = `webhook url not found: ${url}`;
218
305
  break;
306
+ case AlertType.INVALID_APP_PAYLOAD:
307
+ message = `${url} return invalid app payload`;
308
+ break;
219
309
  case AlertType.TTS_NOT_PROVISIONED:
220
310
  message = `text to speech credentials for ${vendor} have not been provisioned`;
221
311
  break;
@@ -245,7 +335,9 @@ const writeAlerts = async(client, alerts) => {
245
335
  break;
246
336
  }
247
337
  }
248
- const obj = {measurement: 'alerts', fields: { message }, tags: { alert_type, account_sid }};
338
+ let fields = { message };
339
+ if (target_sid) fields = Object.assign(fields, {target_sid});
340
+ const obj = {measurement: 'alerts', fields: fields, tags: { alert_type, account_sid }};
249
341
  if (timestamp) obj.timestamp = timestamp;
250
342
  if (detail) obj.fields.detail = detail;
251
343
  return obj;
@@ -295,6 +387,7 @@ module.exports = (logger, opts) => {
295
387
 
296
388
  const cdrClient = new Influx.InfluxDB({database: 'cdrs', schemas: schemas.cdr, ...opts});
297
389
  const alertClient = new Influx.InfluxDB({database: 'alerts', schemas: schemas.alerts, ...opts});
390
+ const callCountClient = new Influx.InfluxDB({database: 'call_counts', schemas: schemas.call_counts, ...opts});
298
391
 
299
392
  cdrClient.locals = {
300
393
  db: 'cdrs',
@@ -312,13 +405,24 @@ module.exports = (logger, opts) => {
312
405
  commitInterval: opts.commitInterval || 10,
313
406
  data: []
314
407
  };
408
+ callCountClient.locals = {
409
+ db: 'call_counts',
410
+ initialized: false,
411
+ writing: false,
412
+ commitSize: opts.commitSize || 1,
413
+ commitInterval: opts.commitInterval || 10,
414
+ data: []
415
+ };
315
416
 
316
417
  if (opts.commitSize > 1 && opts.commitInterval && opts.commitInterval > 2) {
418
+ setInterval(writeData.bind(null, callCountClient), opts.commitInterval * 1000);
317
419
  setInterval(writeData.bind(null, cdrClient), opts.commitInterval * 1000);
318
420
  setInterval(writeData.bind(null, alertClient), opts.commitInterval * 1000);
319
421
  }
320
422
 
321
423
  return {
424
+ writeCallCount: writeCallCount.bind(null, callCountClient),
425
+ queryCallCounts: queryCallCounts.bind(null, callCountClient),
322
426
  writeCdrs: writeCdrs.bind(null, cdrClient),
323
427
  queryCdrs: queryCdrs.bind(null, cdrClient),
324
428
  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.7",
3
+ "version": "0.1.10",
4
4
  "description": "write and query data to time series daetabase",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -3,6 +3,8 @@ const Influx = require('influx');
3
3
  const consoleLogger = {error: console.error, info: console.log, debug: console.log};
4
4
 
5
5
  const {
6
+ writeCallCount,
7
+ queryCallCounts,
6
8
  writeCdrs,
7
9
  queryCdrs,
8
10
  writeAlerts,
@@ -10,7 +12,7 @@ const {
10
12
  AlertType
11
13
  } = require('..')(consoleLogger, '127.0.0.1', {commitSize: 1});
12
14
 
13
- test('write cdr data', async(t) => {
15
+ test('write timeseries data', async(t) => {
14
16
  let result = await writeCdrs([{
15
17
  from: 'me',
16
18
  to: 'you',
@@ -71,6 +73,12 @@ test('write cdr data', async(t) => {
71
73
  account_sid: 'yyyy',
72
74
  url: 'http://foo.bar'
73
75
  },
76
+ {
77
+ alert_type: AlertType.INVALID_APP_PAYLOAD,
78
+ account_sid: 'yyyy',
79
+ target_sid: 'zzzz',
80
+ message: 'invalid app payload'
81
+ },
74
82
  {
75
83
  alert_type: AlertType.TTS_NOT_PROVISIONED,
76
84
  account_sid: 'yyyy',
@@ -115,6 +123,27 @@ test('write cdr data', async(t) => {
115
123
 
116
124
  result = await queryAlerts({account_sid: 'yyyy', page: 1, page_size: 25, days: 7});
117
125
  //console.log(JSON.stringify(result));
118
- t.ok(result.data.length === 11, 'queried alerts')
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')
132
+
133
+ result = await writeCallCount(
134
+ {
135
+ calls_in_progress: 49,
136
+ account_sid: 'yyyy'
137
+ });
138
+ result = await writeCallCount(
139
+ {
140
+ calls_in_progress: 50,
141
+ account_sid: 'yyyy'
142
+ });
143
+ t.pass('wrote call counts');
144
+
145
+ result = await queryCallCounts({account_sid: 'yyyy', page: 1, page_size: 25, days: 7});
146
+ //console.log(JSON.stringify(result));
147
+ t.ok(result.data.length === 2, 'queried call counts');
119
148
 
120
149
  });