metrics.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. * decaffeinate suggestions:
  3. * DS101: Remove unnecessary use of Array.from
  4. * DS102: Remove unnecessary code created because of implicit returns
  5. * DS207: Consider shorter variations of null checks
  6. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  7. */
  8. let Metrics;
  9. console.log("using prometheus");
  10. const prom = require('./prom_wrapper');
  11. const {
  12. collectDefaultMetrics
  13. } = prom;
  14. let appname = "unknown";
  15. const hostname = require('os').hostname();
  16. const destructors = [];
  17. require("./uv_threadpool_size");
  18. module.exports = (Metrics = {
  19. register: prom.registry,
  20. initialize(_name, opts) {
  21. if (opts == null) { opts = {}; }
  22. appname = _name;
  23. collectDefaultMetrics({ timeout: 5000, prefix: Metrics.buildPromKey()});
  24. if (opts.ttlInMinutes) {
  25. prom.ttlInMinutes = opts.ttlInMinutes;
  26. }
  27. console.log(`ENABLE_TRACE_AGENT set to ${process.env['ENABLE_TRACE_AGENT']}`);
  28. if (process.env['ENABLE_TRACE_AGENT'] === "true") {
  29. console.log("starting google trace agent");
  30. const traceAgent = require('@google-cloud/trace-agent');
  31. const traceOpts =
  32. {ignoreUrls: [/^\/status/, /^\/health_check/]};
  33. traceAgent.start(traceOpts);
  34. }
  35. console.log(`ENABLE_DEBUG_AGENT set to ${process.env['ENABLE_DEBUG_AGENT']}`);
  36. if (process.env['ENABLE_DEBUG_AGENT'] === "true") {
  37. console.log("starting google debug agent");
  38. const debugAgent = require('@google-cloud/debug-agent');
  39. debugAgent.start({
  40. allowExpressions: true,
  41. serviceContext: {
  42. service: appname,
  43. version: process.env['BUILD_VERSION']
  44. }
  45. });
  46. }
  47. console.log(`ENABLE_PROFILE_AGENT set to ${process.env['ENABLE_PROFILE_AGENT']}`);
  48. if (process.env['ENABLE_PROFILE_AGENT'] === "true") {
  49. console.log("starting google profile agent");
  50. const profiler = require('@google-cloud/profiler');
  51. profiler.start({
  52. serviceContext: {
  53. service: appname,
  54. version: process.env['BUILD_VERSION']
  55. }
  56. });
  57. }
  58. return Metrics.inc("process_startup");
  59. },
  60. registerDestructor(func) {
  61. return destructors.push(func);
  62. },
  63. injectMetricsRoute(app) {
  64. return app.get('/metrics', function(req, res) {
  65. res.set('Content-Type', prom.registry.contentType);
  66. return res.end(prom.registry.metrics());
  67. });
  68. },
  69. buildPromKey(key){
  70. if (key == null) { key = ""; }
  71. return key.replace(/[^a-zA-Z0-9]/g, "_");
  72. },
  73. sanitizeValue(value) {
  74. return parseFloat(value);
  75. },
  76. set(key, value, sampleRate){
  77. if (sampleRate == null) { sampleRate = 1; }
  78. return console.log("counts are not currently supported");
  79. },
  80. inc(key, sampleRate, opts){
  81. if (sampleRate == null) { sampleRate = 1; }
  82. if (opts == null) { opts = {}; }
  83. key = Metrics.buildPromKey(key);
  84. opts.app = appname;
  85. opts.host = hostname;
  86. prom.metric('counter', key).inc(opts);
  87. if (process.env['DEBUG_METRICS']) {
  88. return console.log("doing inc", key, opts);
  89. }
  90. },
  91. count(key, count, sampleRate, opts){
  92. if (sampleRate == null) { sampleRate = 1; }
  93. if (opts == null) { opts = {}; }
  94. key = Metrics.buildPromKey(key);
  95. opts.app = appname;
  96. opts.host = hostname;
  97. prom.metric('counter', key).inc(opts, count);
  98. if (process.env['DEBUG_METRICS']) {
  99. return console.log("doing count/inc", key, opts);
  100. }
  101. },
  102. summary(key, value, opts){
  103. if (opts == null) { opts = {}; }
  104. key = Metrics.buildPromKey(key);
  105. opts.app = appname;
  106. opts.host = hostname;
  107. prom.metric('summary', key).observe(opts, value);
  108. if (process.env['DEBUG_METRICS']) {
  109. return console.log("doing summary", key, value, opts);
  110. }
  111. },
  112. timing(key, timeSpan, sampleRate, opts){
  113. if (opts == null) { opts = {}; }
  114. key = Metrics.buildPromKey("timer_" + key);
  115. opts.app = appname;
  116. opts.host = hostname;
  117. prom.metric('summary', key).observe(opts, timeSpan);
  118. if (process.env['DEBUG_METRICS']) {
  119. return console.log("doing timing", key, opts);
  120. }
  121. },
  122. Timer : class {
  123. constructor(key, sampleRate, opts){
  124. if (sampleRate == null) { sampleRate = 1; }
  125. this.start = new Date();
  126. key = Metrics.buildPromKey(key);
  127. this.key = key;
  128. this.sampleRate = sampleRate;
  129. this.opts = opts;
  130. }
  131. done() {
  132. const timeSpan = new Date - this.start;
  133. Metrics.timing(this.key, timeSpan, this.sampleRate, this.opts);
  134. return timeSpan;
  135. }
  136. },
  137. gauge(key, value, sampleRate, opts){
  138. if (sampleRate == null) { sampleRate = 1; }
  139. key = Metrics.buildPromKey(key);
  140. prom.metric('gauge', key).set({app: appname, host: hostname, status: (opts != null ? opts.status : undefined)}, this.sanitizeValue(value));
  141. if (process.env['DEBUG_METRICS']) {
  142. return console.log("doing gauge", key, opts);
  143. }
  144. },
  145. globalGauge(key, value, sampleRate, opts){
  146. if (sampleRate == null) { sampleRate = 1; }
  147. key = Metrics.buildPromKey(key);
  148. return prom.metric('gauge', key).set({app: appname, status: (opts != null ? opts.status : undefined)},this.sanitizeValue(value));
  149. },
  150. mongodb: require("./mongodb"),
  151. http: require("./http"),
  152. open_sockets: require("./open_sockets"),
  153. event_loop: require("./event_loop"),
  154. memory: require("./memory"),
  155. timeAsyncMethod: require('./timeAsyncMethod'),
  156. close() {
  157. return Array.from(destructors).map((func) =>
  158. func());
  159. }
  160. });