mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-15 23:24:52 +09:00
Replace endpointHitCounter
Track summary statistic of total HTTP response durations using a middleware that applies for all requests instead of having every request needing to update the hit counter manually. Deprecates endpointHitCounter.
This commit is contained in:
1 parent
98dc0174d6
commit
5ad89f072f
7 files changed
+23
-24
No files matched your search
@@ -6,7 +6,7 @@ const fs = require("fs-extra");
|
||||
const http = require("http");
|
||||
const https = require("https");
|
||||
const path = require("path");
|
||||
|
||||
const stream = require("stream");
|
||||
|
||||
const libConfig = require("@clusterio/lib/config");
|
||||
const libData = require("@clusterio/lib/data");
|
||||
@@ -26,9 +26,10 @@ const UserManager = require("./UserManager");
|
||||
const WsServer = require("./WsServer");
|
||||
|
||||
|
||||
const hitCounter = new libPrometheus.Counter(
|
||||
"clusterio_master_http_hits_total",
|
||||
"How many HTTP requests in total have been received"
|
||||
const endpointDurationSummary = new libPrometheus.Summary(
|
||||
"clusterio_master_http_endpoint_duration_seconds",
|
||||
"Time it took to respond to a an HTTP request",
|
||||
{ labels: ["route"] }
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -487,7 +488,15 @@ class Master {
|
||||
|
||||
static addAppRoutes(app, pluginInfos) {
|
||||
app.use((req, res, next) => {
|
||||
hitCounter.inc();
|
||||
let start = process.hrtime.bigint();
|
||||
stream.finished(res, () => {
|
||||
let routePath = "static";
|
||||
if (req.route && req.route.path) {
|
||||
routePath = req.route.path;
|
||||
}
|
||||
let end = process.hrtime.bigint();
|
||||
endpointDurationSummary.labels(routePath).observe(Number(end - start) / 1e9);
|
||||
});
|
||||
next();
|
||||
});
|
||||
app.use(compression());
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
// Shared metrics
|
||||
"use strict";
|
||||
const libPrometheus = require("@clusterio/lib/prometheus");
|
||||
const util = require("util");
|
||||
|
||||
exports.endpointHitCounter = new libPrometheus.Counter(
|
||||
"clusterio_master_http_endpoint_hits_total",
|
||||
"How many requests a particular HTTP endpoint has gotten",
|
||||
{ labels: ["route"] }
|
||||
{ labels: ["route"], register: false }
|
||||
);
|
||||
|
||||
exports.endpointHitCounter.labels = util.deprecate(
|
||||
exports.endpointHitCounter.labels, "incrementing endpointHitCounter is no longer needed and has no effect"
|
||||
);
|
||||
@@ -19,8 +19,6 @@ const libPlugin = require("@clusterio/lib/plugin");
|
||||
const libPrometheus = require("@clusterio/lib/prometheus");
|
||||
const { logger } = require("@clusterio/lib/logging");
|
||||
|
||||
const { endpointHitCounter } = require("./metrics");
|
||||
|
||||
const finished = util.promisify(nodeStream.finished);
|
||||
|
||||
|
||||
@@ -41,8 +39,6 @@ function mergeSamples(destinationResult, sourceResult) {
|
||||
|
||||
// Prometheus polling endpoint
|
||||
async function getMetrics(req, res, next) {
|
||||
endpointHitCounter.labels(req.route.path).inc();
|
||||
|
||||
let results = [];
|
||||
let pluginResults = await libPlugin.invokeHook(req.app.locals.master.plugins, "onMetrics");
|
||||
for (let metricIterator of pluginResults) {
|
||||
@@ -181,7 +177,6 @@ function validateUserToken(req, res, next) {
|
||||
|
||||
// Handle an uploaded export package.
|
||||
async function uploadExport(req, res) {
|
||||
endpointHitCounter.labels(req.route.path).inc();
|
||||
if (req.get("Content-Type") !== "application/zip") {
|
||||
res.sendStatus(415);
|
||||
return;
|
||||
@@ -340,7 +335,6 @@ async function uploadSave(req, res) {
|
||||
res.status(403).json({ request_errors: [err.message] });
|
||||
return;
|
||||
}
|
||||
endpointHitCounter.labels(req.route.path).inc();
|
||||
|
||||
let contentType = req.get("Content-Type");
|
||||
let match = contentTypeRegExp.exec(contentType);
|
||||
@@ -479,7 +473,6 @@ async function uploadMod(req, res) {
|
||||
res.status(403).json({ request_errors: [err.message] });
|
||||
return;
|
||||
}
|
||||
endpointHitCounter.labels(req.route.path).inc();
|
||||
|
||||
let contentType = req.get("Content-Type");
|
||||
let match = contentTypeRegExp.exec(contentType);
|
||||
|
||||
@@ -44,8 +44,6 @@ class MasterPlugin extends libPlugin.BaseMasterPlugin {
|
||||
}, 60e3).unref();
|
||||
|
||||
this.master.app.get("/api/player_auth/servers", (req, res) => {
|
||||
this.metrics.endpointHitCounter.labels(req.route.path).inc();
|
||||
|
||||
let servers = [];
|
||||
for (let instance of this.master.instances.values()) {
|
||||
if (instance.status === "running" && instance.config.get("player_auth.load_plugin")) {
|
||||
@@ -56,12 +54,10 @@ class MasterPlugin extends libPlugin.BaseMasterPlugin {
|
||||
});
|
||||
|
||||
this.master.app.post("/api/player_auth/player_code", express.json(), (req, res, next) => {
|
||||
this.metrics.endpointHitCounter.labels(req.route.path).inc();
|
||||
this.handlePlayerCode(req, res).catch(next);
|
||||
});
|
||||
|
||||
this.master.app.post("/api/player_auth/verify", express.json(), (req, res, next) => {
|
||||
this.metrics.endpointHitCounter.labels(req.route.path).inc();
|
||||
this.handleVerify(req, res).catch(next);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ class MasterPlugin extends libPlugin.BaseMasterPlugin {
|
||||
|
||||
this.subscribedControlLinks = new Set();
|
||||
|
||||
routes.addApiRoutes(this.master.app, this.items, this.metrics.endpointHitCounter);
|
||||
routes.addApiRoutes(this.master.app, this.items);
|
||||
}
|
||||
|
||||
updateStorage() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"use strict";
|
||||
function addApiRoutes(app, items, endpointHitCounter) {
|
||||
function addApiRoutes(app, items) {
|
||||
|
||||
/**
|
||||
* GET endpoint to read the masters current inventory of items.
|
||||
@@ -10,7 +10,6 @@ function addApiRoutes(app, items, endpointHitCounter) {
|
||||
* @returns {object[]} JSON [{name:"iron-plate", count:100},{name:"copper-plate",count:5}]
|
||||
*/
|
||||
app.get("/api/inventory", (req, res) => {
|
||||
endpointHitCounter.labels(req.route.path).inc();
|
||||
res.header("Access-Control-Allow-Origin", "*");
|
||||
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
|
||||
// Check it and send it
|
||||
@@ -31,7 +30,6 @@ function addApiRoutes(app, items, endpointHitCounter) {
|
||||
* @returns {object} JSON {"iron-plate":100, "copper-plate":5}
|
||||
*/
|
||||
app.get("/api/inventoryAsObject", (req, res) => {
|
||||
endpointHitCounter.labels(req.route.path).inc();
|
||||
res.header("Access-Control-Allow-Origin", "*");
|
||||
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
|
||||
// Check it and send it
|
||||
|
||||
+1
-3
@@ -219,9 +219,7 @@ class MockMaster {
|
||||
|
||||
async function createMasterPlugin(MasterPluginClass, info) {
|
||||
let master = new MockMaster();
|
||||
let metrics = {
|
||||
endpointHitCounter: new libPrometheus.Counter("hit_counter", "Hit Counter", { labels: ["route"] }),
|
||||
};
|
||||
let metrics = {};
|
||||
let logger = new MockLogger();
|
||||
let plugin = new MasterPluginClass(info, master, metrics, logger);
|
||||
await plugin.init();
|
||||
|
||||
Reference in new issue
Block a user