Exporting metrics for node.js, express, router, and codimd realtime status.

1. **/metrics/router** : exporting node.js/express Prometheus metrics by
[prometheus-api-metrics](https://www.npmjs.com/package/prometheus-api-metrics)

2. **/metrics/codimd** : exporting codimd realtime status (/status) as
Prometheus metrics

Signed-off-by: tarlety <tarlety@gmail.com>
This commit is contained in:
tarlety 2020-04-28 09:13:16 +08:00 committed by tarlety
parent 4fd6293963
commit 09eb8556db
No known key found for this signature in database
GPG Key ID: BF59BB0B218D1BFA
6 changed files with 161 additions and 0 deletions

7
app.js
View File

@ -17,6 +17,7 @@ var passportSocketIo = require('passport.socketio')
var helmet = require('helmet')
var i18n = require('i18n')
var flash = require('connect-flash')
var apiMetrics = require('prometheus-api-metrics')
// core
var config = require('./lib/config')
@ -56,6 +57,12 @@ function createHttpServer () {
var app = express()
var server = createHttpServer()
// API and process monitoring with Prometheus for Node.js micro-service
app.use(apiMetrics({
metricsPath: "/metrics/router",
excludeRoutes: ["/metrics/codimd"]
}))
// logger
app.use(morgan('combined', {
stream: logger.stream

View File

@ -28,6 +28,7 @@ appRouter.get('/404', errorPageController.errorNotFound)
appRouter.get('/500', errorPageController.errorInternalError)
appRouter.get('/status', wrap(statusController.getStatus))
appRouter.get('/metrics/codimd', wrap(statusController.getMetrics))
appRouter.get('/config', statusController.getConfig)
// register auth module

View File

@ -14,6 +14,17 @@ exports.getStatus = async (req, res) => {
res.send(data)
}
exports.getMetrics = async (req, res) => {
const data = await realtime.getStatus()
res.set({
'Cache-Control': 'private', // only cache by client
'X-Robots-Tag': 'noindex, nofollow', // prevent crawling
'Content-Type': 'text/plain; charset=utf-8'
})
res.render('../js/lib/common/metrics.ejs', data)
}
exports.getConfig = (req, res) => {
const data = {
domain: config.domain,

129
package-lock.json generated
View File

@ -1032,6 +1032,14 @@
"unified": "^6.1.6"
}
},
"@types/accepts": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz",
"integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==",
"requires": {
"@types/node": "*"
}
},
"@types/body-parser": {
"version": "1.17.1",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.1.tgz",
@ -1061,6 +1069,22 @@
"@types/node": "*"
}
},
"@types/content-disposition": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/@types/content-disposition/-/content-disposition-0.5.3.tgz",
"integrity": "sha512-P1bffQfhD3O4LW0ioENXUhZ9OIa0Zn+P7M+pWgkCKaT53wVLSq0mrKksCID/FGHpFhRSxRGhgrQmfhRuzwtKdg=="
},
"@types/cookies": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/@types/cookies/-/cookies-0.7.4.tgz",
"integrity": "sha512-oTGtMzZZAVuEjTwCjIh8T8FrC8n/uwy+PG0yTvQcdZ7etoel7C7/3MSd7qrukENTgQtotG7gvBlBojuVs7X5rw==",
"requires": {
"@types/connect": "*",
"@types/express": "*",
"@types/keygrip": "*",
"@types/node": "*"
}
},
"@types/estree": {
"version": "0.0.39",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
@ -1092,6 +1116,38 @@
"integrity": "sha512-mky/O83TXmGY39P1H9YbUpjV6l6voRYlufqfFCvel8l1phuy8HRjdWc1rrPuN53ITBJlbyMSV6z3niOySO5pgQ==",
"dev": true
},
"@types/http-assert": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.1.tgz",
"integrity": "sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ=="
},
"@types/keygrip": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@types/keygrip/-/keygrip-1.0.2.tgz",
"integrity": "sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw=="
},
"@types/koa": {
"version": "2.11.3",
"resolved": "https://registry.npmjs.org/@types/koa/-/koa-2.11.3.tgz",
"integrity": "sha512-ABxVkrNWa4O/Jp24EYI/hRNqEVRlhB9g09p48neQp4m3xL1TJtdWk2NyNQSMCU45ejeELMQZBYyfstyVvO2H3Q==",
"requires": {
"@types/accepts": "*",
"@types/content-disposition": "*",
"@types/cookies": "*",
"@types/http-assert": "*",
"@types/keygrip": "*",
"@types/koa-compose": "*",
"@types/node": "*"
}
},
"@types/koa-compose": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/@types/koa-compose/-/koa-compose-3.2.5.tgz",
"integrity": "sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==",
"requires": {
"@types/koa": "*"
}
},
"@types/ldapjs": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@types/ldapjs/-/ldapjs-1.0.5.tgz",
@ -1124,6 +1180,11 @@
"integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==",
"dev": true
},
"@types/qs": {
"version": "6.9.1",
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.1.tgz",
"integrity": "sha512-lhbQXx9HKZAPgBkISrBcmAcMpZsmpe/Cd/hY7LGZS5OfkySUBItnPZHgQPssWYUET8elF+yCFBbP1Q0RZPTdaw=="
},
"@types/range-parser": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
@ -2837,6 +2898,11 @@
"file-uri-to-path": "1.0.0"
}
},
"bintrees": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz",
"integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ="
},
"bl": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz",
@ -13276,6 +13342,61 @@
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
},
"prom-client": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/prom-client/-/prom-client-12.0.0.tgz",
"integrity": "sha512-JbzzHnw0VDwCvoqf8y1WDtq4wSBAbthMB1pcVI/0lzdqHGJI3KBJDXle70XK+c7Iv93Gihqo0a5LlOn+g8+DrQ==",
"requires": {
"tdigest": "^0.1.1"
}
},
"prometheus-api-metrics": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/prometheus-api-metrics/-/prometheus-api-metrics-2.2.5.tgz",
"integrity": "sha512-ESjR6ANqISesFbnwXq+d0D/edAiUcY6OTz/bMhywbLYcODjm/8XAzhqpeG8mrmdbk59Y/bpKacie5yILFFPDJg==",
"requires": {
"@types/express": "^4.17.6",
"@types/express-serve-static-core": "^4.17.5",
"@types/koa": "^2.11.3",
"debug": "^3.2.6",
"pkginfo": "^0.4.1"
},
"dependencies": {
"@types/express": {
"version": "4.17.6",
"resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.6.tgz",
"integrity": "sha512-n/mr9tZI83kd4azlPG5y997C/M4DNABK9yErhFM6hKdym4kkmd9j0vtsJyjFIwfRBxtrxZtAfGZCNRIBMFLK5w==",
"requires": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "*",
"@types/qs": "*",
"@types/serve-static": "*"
}
},
"@types/express-serve-static-core": {
"version": "4.17.5",
"resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.5.tgz",
"integrity": "sha512-578YH5Lt88AKoADy0b2jQGwJtrBxezXtVe/MBqWXKZpqx91SnC0pVkVCcxcytz3lWW+cHBYDi3Ysh0WXc+rAYw==",
"requires": {
"@types/node": "*",
"@types/range-parser": "*"
}
},
"debug": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
"requires": {
"ms": "^2.1.1"
}
},
"pkginfo": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz",
"integrity": "sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8="
}
}
},
"promise": {
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
@ -15469,6 +15590,14 @@
"csextends": "^1.0.3"
}
},
"tdigest": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz",
"integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=",
"requires": {
"bintrees": "1.0.1"
}
},
"tedious": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/tedious/-/tedious-6.2.1.tgz",

View File

@ -86,6 +86,8 @@
"passport.socketio": "~3.7.0",
"pg": "~6.1.2",
"pg-hstore": "~2.3.2",
"prom-client": "^12.0.0",
"prometheus-api-metrics": "^2.2.5",
"randomcolor": "~0.5.4",
"readline-sync": "~1.4.7",
"request": "~2.88.0",

View File

@ -0,0 +1,11 @@
online_notes <%- onlineNotes %>
online_users <%- onlineUsers %>
distinct_online_users <%- distinctOnlineUsers %>
notes_count <%- notesCount %>
registered_users <%- registeredUsers %>
online_registered_users <%- onlineRegisteredUsers %>
distinct_online_registered_users <%- distinctOnlineRegisteredUsers %>
is_connection_busy <%- isConnectionBusy ? 1 : 0 %>
connection_socket_queue_length <%- connectionSocketQueueLength %>
is_disconnect_busy <%- isDisconnectBusy ? 1: 0 %>
disconnect_socket_queue_length <%- disconnectSocketQueueLength %>