diff --git a/libraries/metrics/metrics.coffee b/libraries/metrics/metrics.coffee index e9a25966b5..22dfd22548 100644 --- a/libraries/metrics/metrics.coffee +++ b/libraries/metrics/metrics.coffee @@ -1,12 +1,19 @@ StatsD = require('lynx') statsd = new StatsD(process.env["STATSD_HOST"] or "localhost", 8125, {on_error:->}) +prom = require('prom-client') +Register = require('prom-client').register +collectDefaultMetrics = prom.collectDefaultMetrics + name = "unknown" hostname = require('os').hostname() buildKey = (key)-> "#{name}.#{hostname}.#{key}" buildGlobalKey = (key)-> "#{name}.global.#{key}" +counters = {} +gauges = {} + destructors = [] require "./uv_threadpool_size" @@ -14,15 +21,36 @@ require "./uv_threadpool_size" module.exports = Metrics = initialize: (_name) -> name = _name + collectDefaultMetrics({ timeout: 5000, prefix: name + "_" }) registerDestructor: (func) -> destructors.push func + injectMetricsRoute: (app) -> + app.get('/metrics', (req, res) -> + res.set('Content-Type', Register.contentType) + res.end(Register.metrics()) + ) + + sanitizeKey: (key) -> + key.replace /[^a-zA-Z0-9]/g, "_" + + sanitizeValue: (value) -> + parseFloat(value) + set : (key, value, sampleRate = 1)-> statsd.set buildKey(key), value, sampleRate inc : (key, sampleRate = 1)-> statsd.increment buildKey(key), sampleRate + key = this.sanitizeKey(key) + if !counters[key] + counters[key] = new prom.Counter({ + name: key, + help: key, + labelNames: ['name','host'] + }) + counters[key].inc({name: name, host: hostname}) count : (key, count, sampleRate = 1)-> statsd.count buildKey(key), count, sampleRate @@ -42,9 +70,25 @@ module.exports = Metrics = gauge : (key, value, sampleRate = 1)-> statsd.gauge buildKey(key), value, sampleRate + key = this.sanitizeKey(key) + if !gauges[key] + gauges[key] = new prom.Gauge({ + name: key, + help: key, + labelNames: ['name','host'] + }) + gauges[key].set({name: name, host: hostname},this.sanitizeValue(value)) globalGauge: (key, value, sampleRate = 1)-> statsd.gauge buildGlobalKey(key), value, sampleRate + key = this.sanitizeKey(key) + if !gauges[key] + gauges[key] = new prom.Gauge({ + name: key, + help: key, + labelNames: ['name','host'] + }) + gauges[key].set({name: name},this.sanitizeValue(value)) mongodb: require "./mongodb" http: require "./http" diff --git a/libraries/metrics/package.json b/libraries/metrics/package.json index e19c11ddf2..cd47fc1466 100644 --- a/libraries/metrics/package.json +++ b/libraries/metrics/package.json @@ -1,14 +1,15 @@ { "name": "metrics-sharelatex", - "version": "1.8.1", + "version": "1.9.0", "description": "A drop-in metrics and monitoring module for node.js apps", "repository": { "type": "git", "url": "https://github.com/sharelatex/metrics-sharelatex.git" }, "dependencies": { - "lynx": "~0.1.1", "coffee-script": "1.6.0", + "lynx": "~0.1.1", + "prom-client": "^11.1.3", "underscore": "~1.6.0" }, "devDependencies": {