-
-
Notifications
You must be signed in to change notification settings - Fork 139
/
swsCoreStats.js
157 lines (126 loc) · 4.9 KB
/
swsCoreStats.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/**
* Created by sv2 on 2/18/17.
* API usage statistics data
*/
'use strict';
const util = require('util');
const debug = require('debug')('sws:corestats');
const promClient = require("prom-client");
const swsSettings = require('./swssettings');
const swsMetrics = require('./swsmetrics');
const swsUtil = require('./swsUtil');
const SwsReqResStats = require('./swsReqResStats');
/* swagger=stats Prometheus metrics */
class SwsCoreStats {
constructor(){
// Statistics for all requests
this.all = null;
// Statistics for requests by method
// Initialized with most frequent ones, other methods will be added on demand if actually used
this.method = null;
// Additional prefix for prometheus metrics. Used if this coreStats instance
// plays special role, i.e. count stats for egress
this.metricsRolePrefix = '';
// Prometheus metrics
this.promClientMetrics = {};
}
// Initialize
initialize(metricsRolePrefix) {
this.metricsRolePrefix = metricsRolePrefix || '';
// Statistics for all requests
this.all = new SwsReqResStats(swsSettings.apdexThreshold);
// Statistics for requests by method
// Initialized with most frequent ones, other methods will be added on demand if actually used
this.method = {
'GET': new SwsReqResStats(swsSettings.apdexThreshold),
'POST': new SwsReqResStats(swsSettings.apdexThreshold),
'PUT': new SwsReqResStats(swsSettings.apdexThreshold),
'DELETE': new SwsReqResStats(swsSettings.apdexThreshold)
};
// metrics
swsMetrics.clearPrometheusMetrics(this.promClientMetrics);
let prefix = swsSettings.metricsPrefix + this.metricsRolePrefix;
this.promClientMetrics = swsMetrics.getPrometheusMetrics(prefix,swsMetrics.coreMetricsDefs);
};
getStats() {
return this.all;
};
getMethodStats() {
return this.method;
};
// Update timeline and stats per tick
tick(ts,totalElapsedSec) {
// Rates
this.all.updateRates(totalElapsedSec);
for( let mname of Object.keys(this.method)) {
this.method[mname].updateRates(totalElapsedSec);
}
};
// Count request
countRequest(req) {
// Count in all
this.all.countRequest(req.sws.req_clength);
// Count by method
var method = req.method;
if (!(method in this.method)) {
this.method[method] = new SwsReqResStats();
}
this.method[method].countRequest(req.sws.req_clength);
// Update prom-client metrics
this.promClientMetrics.api_all_request_total.inc();
this.promClientMetrics.api_all_request_in_processing_total.inc();
req.sws.inflightTimer = setTimeout(function() {
this.promClientMetrics.api_all_request_in_processing_total.dec();
}.bind(this), 250000);
};
countResponse (res) {
var req = res._swsReq;
// Defaults
let duration = req.sws.duration || 0;
let resContentLength = req.sws.res_clength || 0;
// let timelineid = req.sws.timelineid || 0;
// let path = req.sws.api_path || req.sws.originalUrl || req.originalUrl;
/*
if("sws" in req) {
startts = req.sws.startts;
timelineid = req.sws.timelineid;
var endts = Date.now();
req['sws'].endts = endts;
duration = endts - startts;
req['sws'].duration = duration;
req['sws'].res_clength = resContentLength;
path = req['sws'].api_path;
clearTimeout(req.sws.inflightTimer);
}
*/
// Determine status code type
var codeclass = swsUtil.getStatusCodeClass(res.statusCode);
// update counts for all requests
this.all.countResponse(res.statusCode,codeclass,duration,resContentLength);
// Update method-specific stats
var method = req.method;
if (method in this.method) {
var mstat = this.method[method];
mstat.countResponse(res.statusCode,codeclass,duration,resContentLength);
}
// Update Prometheus metrics
switch(codeclass){
case "success":
this.promClientMetrics.api_all_success_total.inc();
break;
case "redirect":
// NOOP //
break;
case "client_error":
this.promClientMetrics.api_all_errors_total.inc();
this.promClientMetrics.api_all_client_error_total.inc();
break;
case "server_error":
this.promClientMetrics.api_all_errors_total.inc();
this.promClientMetrics.api_all_server_error_total.inc();
break;
}
this.promClientMetrics.api_all_request_in_processing_total.dec();
};
}
module.exports = SwsCoreStats;