katex_server: Add Prometheus metrics.

This commit is contained in:
Alex Vandiver 2024-03-13 16:29:10 +00:00 committed by Tim Abbott
parent c13e3dee24
commit bfe4017663
3 changed files with 69 additions and 0 deletions

View File

@ -69,6 +69,7 @@
"postcss-prefixwrap": "^1.24.0",
"postcss-preset-env": "^9.0.0",
"postcss-simple-vars": "^7.0.0",
"prom-client": "^15.1.0",
"regenerator-runtime": "^0.14.0",
"shebang-loader": "^0.0.1",
"simplebar": "^6.2.0",

View File

@ -214,6 +214,9 @@ dependencies:
postcss-simple-vars:
specifier: ^7.0.0
version: 7.0.1(postcss@8.4.35)
prom-client:
specifier: ^15.1.0
version: 15.1.0
regenerator-runtime:
specifier: ^0.14.0
version: 0.14.1
@ -2727,6 +2730,11 @@ packages:
rimraf: 3.0.2
dev: false
/@opentelemetry/api@1.8.0:
resolution: {integrity: sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==}
engines: {node: '>=8.0.0'}
dev: false
/@pkgjs/parseargs@0.11.0:
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
@ -4360,6 +4368,10 @@ packages:
file-uri-to-path: 1.0.0
dev: false
/bintrees@1.0.2:
resolution: {integrity: sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==}
dev: false
/bit-twiddle@1.0.2:
resolution: {integrity: sha512-B9UhK0DKFZhoTFcfvAzhqsjStvGJp9vYWf3+6SNTtdSQnvIgfkHbgHrg/e4+TH71N2GDu8tpmCVoyfrL1d7ntA==}
dev: false
@ -10573,6 +10585,14 @@ packages:
engines: {node: '>=0.4.0'}
dev: true
/prom-client@15.1.0:
resolution: {integrity: sha512-cCD7jLTqyPdjEPBo/Xk4Iu8jxjuZgZJ3e/oET3L+ZwOuap/7Cw3dH/TJSsZKs1TQLZ2IHpIlRAKw82ef06kmMw==}
engines: {node: ^16 || ^18 || >=20}
dependencies:
'@opentelemetry/api': 1.8.0
tdigest: 0.1.2
dev: false
/promise-inflight@1.0.1:
resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==}
peerDependencies:
@ -12002,6 +12022,12 @@ packages:
yallist: 4.0.0
dev: false
/tdigest@0.1.2:
resolution: {integrity: sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==}
dependencies:
bintrees: 1.0.2
dev: false
/terser-webpack-plugin@5.3.10(webpack@5.90.3):
resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==}
engines: {node: '>= 10.13.0'}

View File

@ -3,6 +3,7 @@ import crypto from "node:crypto";
import bodyParser from "@koa/bodyparser";
import katex from "katex";
import Koa from "koa";
import Prometheus from "prom-client";
const host = "localhost";
const port = Number(process.argv[2] ?? "9700");
@ -30,6 +31,43 @@ const compare_secret = (given_secret: string): boolean => {
const app = new Koa();
app.use(bodyParser());
Prometheus.collectDefaultMetrics();
const httpRequestDurationSeconds = new Prometheus.Histogram({
name: "katex_http_request_duration_seconds",
help: "Duration of HTTP requests in seconds",
labelNames: ["method", "path", "status"] as const,
buckets: [
0.00001, 0.00002, 0.00005, 0.0001, 0.0002, 0.0005, 0.001, 0.002, 0.005, 0.01, 0.02, 0.05,
0.1,
],
});
const httpRequestSizeBytes = new Prometheus.Histogram({
name: "katex_request_size_bytes",
help: "Size of successful KaTeX input in bytes",
labelNames: ["display_mode"] as const,
buckets: [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000],
});
const httpResponseSizeBytes = new Prometheus.Histogram({
name: "katex_response_size_bytes",
help: "Size of successful KaTeX output in bytes",
labelNames: ["display_mode"] as const,
buckets: [100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000],
});
app.use(async (ctx, next) => {
if (ctx.request.method === "GET" && ctx.request.path === "/metrics") {
ctx.body = await Prometheus.register.metrics();
return;
}
const endTimer = httpRequestDurationSeconds.startTimer();
await next();
const {method, path} = ctx.request;
const {status} = ctx.response;
httpRequestDurationSeconds.labels({method, path, status: String(status)}).observe(endTimer());
});
app.use((ctx, _next) => {
if (ctx.request.method !== "POST" || ctx.request.path !== "/") {
ctx.status = 404;
@ -59,8 +97,12 @@ app.use((ctx, _next) => {
return;
}
httpRequestSizeBytes.labels(String(is_display)).observe(Buffer.byteLength(content, "utf8"));
try {
ctx.body = katex.renderToString(content, {displayMode: is_display});
httpResponseSizeBytes
.labels(String(is_display))
.observe(Buffer.byteLength(ctx.body, "utf8"));
} catch (error) {
if (error instanceof katex.ParseError) {
ctx.status = 400;