mirror of
https://github.com/imputnet/cobalt.git
synced 2025-06-28 09:28:29 +00:00
Merge db7930eb86
into 35530459b6
This commit is contained in:
commit
e9ec0899b3
@ -36,6 +36,7 @@
|
|||||||
"ipaddr.js": "2.2.0",
|
"ipaddr.js": "2.2.0",
|
||||||
"mime": "^4.0.4",
|
"mime": "^4.0.4",
|
||||||
"nanoid": "^5.0.9",
|
"nanoid": "^5.0.9",
|
||||||
|
"prom-client": "^15.1.3",
|
||||||
"set-cookie-parser": "2.6.0",
|
"set-cookie-parser": "2.6.0",
|
||||||
"undici": "^5.19.1",
|
"undici": "^5.19.1",
|
||||||
"url-pattern": "1.0.3",
|
"url-pattern": "1.0.3",
|
||||||
|
@ -3,6 +3,7 @@ import http from "node:http";
|
|||||||
import rateLimit from "express-rate-limit";
|
import rateLimit from "express-rate-limit";
|
||||||
import { setGlobalDispatcher, ProxyAgent } from "undici";
|
import { setGlobalDispatcher, ProxyAgent } from "undici";
|
||||||
import { getCommit, getBranch, getRemote, getVersion } from "@imput/version-info";
|
import { getCommit, getBranch, getRemote, getVersion } from "@imput/version-info";
|
||||||
|
import { httpRequests, httpRequestDuration, WORKER_ID, aggregatorRegistry } from "../misc/metrics.js";
|
||||||
|
|
||||||
import jwt from "../security/jwt.js";
|
import jwt from "../security/jwt.js";
|
||||||
import stream from "../stream/stream.js";
|
import stream from "../stream/stream.js";
|
||||||
@ -10,7 +11,7 @@ import match from "../processing/match.js";
|
|||||||
|
|
||||||
import { env } from "../config.js";
|
import { env } from "../config.js";
|
||||||
import { extract } from "../processing/url.js";
|
import { extract } from "../processing/url.js";
|
||||||
import { Bright, Cyan } from "../misc/console-text.js";
|
import { Bright, Cyan, Green } from "../misc/console-text.js";
|
||||||
import { hashHmac } from "../security/secrets.js";
|
import { hashHmac } from "../security/secrets.js";
|
||||||
import { createStore } from "../store/redis-ratelimit.js";
|
import { createStore } from "../store/redis-ratelimit.js";
|
||||||
import { randomizeCiphers } from "../misc/randomize-ciphers.js";
|
import { randomizeCiphers } from "../misc/randomize-ciphers.js";
|
||||||
@ -39,6 +40,8 @@ const corsConfig = env.corsWildcard ? {} : {
|
|||||||
optionsSuccessStatus: 200
|
optionsSuccessStatus: 200
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const metrics = Boolean(env.metrics && env.metricsPort);
|
||||||
|
|
||||||
const fail = (res, code, context) => {
|
const fail = (res, code, context) => {
|
||||||
const { status, body } = createResponse("error", { code, context });
|
const { status, body } = createResponse("error", { code, context });
|
||||||
res.status(status).json(body);
|
res.status(status).json(body);
|
||||||
@ -54,6 +57,7 @@ export const runAPI = async (express, app, __dirname, isPrimary = true) => {
|
|||||||
version: version,
|
version: version,
|
||||||
url: env.apiURL,
|
url: env.apiURL,
|
||||||
startTime: `${startTimestamp}`,
|
startTime: `${startTimestamp}`,
|
||||||
|
metrics: metrics,
|
||||||
turnstileSitekey: env.sessionEnabled ? env.turnstileSitekey : undefined,
|
turnstileSitekey: env.sessionEnabled ? env.turnstileSitekey : undefined,
|
||||||
services: [...env.enabledServices].map(e => {
|
services: [...env.enabledServices].map(e => {
|
||||||
return friendlyServiceName(e);
|
return friendlyServiceName(e);
|
||||||
@ -111,6 +115,19 @@ export const runAPI = async (express, app, __dirname, isPrimary = true) => {
|
|||||||
|
|
||||||
app.set('trust proxy', ['loopback', 'uniquelocal']);
|
app.set('trust proxy', ['loopback', 'uniquelocal']);
|
||||||
|
|
||||||
|
if (metrics) {
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
const end = httpRequestDuration.startTimer({ method: req.method, worker_id: WORKER_ID });
|
||||||
|
|
||||||
|
res.on('finish', () => {
|
||||||
|
httpRequests.labels(req.method, res.statusCode.toString(), WORKER_ID).inc();
|
||||||
|
end();
|
||||||
|
});
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
app.use('/', cors({
|
app.use('/', cors({
|
||||||
methods: ['GET', 'POST'],
|
methods: ['GET', 'POST'],
|
||||||
exposedHeaders: [
|
exposedHeaders: [
|
||||||
@ -370,7 +387,29 @@ export const runAPI = async (express, app, __dirname, isPrimary = true) => {
|
|||||||
if (env.ytSessionServer) {
|
if (env.ytSessionServer) {
|
||||||
YouTubeSession.setup();
|
YouTubeSession.setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (metrics && isPrimary) {
|
||||||
|
const metricsApp = express();
|
||||||
|
|
||||||
|
metricsApp.get('/metrics', async (req, res) => {
|
||||||
|
try {
|
||||||
|
const data = await aggregatorRegistry.clusterMetrics();
|
||||||
|
res.set('Content-Type', 'text/plain');
|
||||||
|
res.end(data);
|
||||||
|
} catch (err) {
|
||||||
|
res.status(500).end(err.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
metricsApp.get('/*', (req, res) => {
|
||||||
|
res.redirect('/metrics');
|
||||||
|
});
|
||||||
|
|
||||||
|
metricsApp.listen(env.metricsPort, '0.0.0.0', () => {
|
||||||
|
console.log(`${Green('[✓]')} prometheus metrics running on 0.0.0.0:${env.metricsPort}/metrics`);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
setupTunnelHandler();
|
setupTunnelHandler();
|
||||||
}
|
}
|
@ -65,6 +65,9 @@ export const loadEnvs = (env = process.env) => {
|
|||||||
|
|
||||||
enabledServices,
|
enabledServices,
|
||||||
|
|
||||||
|
metrics: env.METRICS_ENABLED,
|
||||||
|
metricsPort: env.METRICS_PORT,
|
||||||
|
|
||||||
customInnertubeClient: env.CUSTOM_INNERTUBE_CLIENT,
|
customInnertubeClient: env.CUSTOM_INNERTUBE_CLIENT,
|
||||||
ytSessionServer: env.YOUTUBE_SESSION_SERVER,
|
ytSessionServer: env.YOUTUBE_SESSION_SERVER,
|
||||||
ytSessionReloadInterval: 300,
|
ytSessionReloadInterval: 300,
|
||||||
|
50
api/src/misc/metrics.js
Normal file
50
api/src/misc/metrics.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
import { collectDefaultMetrics, Counter, Histogram, Registry, AggregatorRegistry } from 'prom-client';
|
||||||
|
|
||||||
|
import cluster from 'node:cluster';
|
||||||
|
|
||||||
|
export const WORKER_ID = `worker_${cluster.worker?.id ?? process.pid}`;
|
||||||
|
|
||||||
|
export const registry = new Registry();
|
||||||
|
export const aggregatorRegistry = new AggregatorRegistry();
|
||||||
|
|
||||||
|
collectDefaultMetrics({
|
||||||
|
register: registry
|
||||||
|
});
|
||||||
|
|
||||||
|
export const failedRequests = new Counter({
|
||||||
|
name: 'cobalt_fail_request_count',
|
||||||
|
help: 'Total number of failed requests',
|
||||||
|
labelNames: ['service', 'worker_id'],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const successfulRequests = new Counter({
|
||||||
|
name: 'cobalt_success_request_count',
|
||||||
|
help: 'Total number of successful requests',
|
||||||
|
labelNames: ['service', 'worker_id'],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const httpRequests = new Counter({
|
||||||
|
name: 'http_requests_total',
|
||||||
|
help: 'Total number of HTTP requests',
|
||||||
|
labelNames: ['method', 'status', 'worker_id'],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const httpRequestDuration = new Histogram({
|
||||||
|
name: 'http_request_duration_seconds',
|
||||||
|
help: 'Duration of HTTP requests in seconds',
|
||||||
|
labelNames: ['method', 'worker_id'],
|
||||||
|
buckets: [0.1, 0.5, 1, 1.5, 2, 5],
|
||||||
|
});
|
||||||
|
|
||||||
|
registry.registerMetric(failedRequests);
|
||||||
|
registry.registerMetric(successfulRequests);
|
||||||
|
registry.registerMetric(httpRequests);
|
||||||
|
registry.registerMetric(httpRequestDuration);
|
||||||
|
|
||||||
|
export function incrementFailed(service) {
|
||||||
|
failedRequests.labels(service, WORKER_ID).inc();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function incrementSuccessful(service) {
|
||||||
|
successfulRequests.labels(service, WORKER_ID).inc();
|
||||||
|
}
|
@ -8,6 +8,8 @@ import matchAction from "./match-action.js";
|
|||||||
|
|
||||||
import { friendlyServiceName } from "./service-alias.js";
|
import { friendlyServiceName } from "./service-alias.js";
|
||||||
|
|
||||||
|
import { incrementFailed, incrementSuccessful } from "../misc/metrics.js"
|
||||||
|
|
||||||
import bilibili from "./services/bilibili.js";
|
import bilibili from "./services/bilibili.js";
|
||||||
import reddit from "./services/reddit.js";
|
import reddit from "./services/reddit.js";
|
||||||
import twitter from "./services/twitter.js";
|
import twitter from "./services/twitter.js";
|
||||||
@ -286,12 +288,16 @@ export default async function({ host, patternMatch, params, isSession }) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (env.metrics && env.metricsPort) incrementFailed(host);
|
||||||
|
|
||||||
return createResponse("error", {
|
return createResponse("error", {
|
||||||
code: `error.api.${r.error}`,
|
code: `error.api.${r.error}`,
|
||||||
context,
|
context,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (env.metrics && env.metricsPort) incrementSuccessful(host);
|
||||||
|
|
||||||
let localProcessing = params.localProcessing;
|
let localProcessing = params.localProcessing;
|
||||||
|
|
||||||
const lpEnv = env.forceLocalProcessing;
|
const lpEnv = env.forceLocalProcessing;
|
||||||
|
@ -64,6 +64,14 @@ this document is not final and will expand over time. feel free to improve it!
|
|||||||
|
|
||||||
[*view details*](#service-specific)
|
[*view details*](#service-specific)
|
||||||
|
|
||||||
|
### prometheus metrics vars
|
||||||
|
| name | value example |
|
||||||
|
|:---------------------------------|:-------------------------|
|
||||||
|
| METRICS | `1` |
|
||||||
|
| METRICS_PORT | `9100` |
|
||||||
|
|
||||||
|
[*view details*](#metrics)
|
||||||
|
|
||||||
## general
|
## general
|
||||||
[*jump to the table*](#general-vars)
|
[*jump to the table*](#general-vars)
|
||||||
|
|
||||||
@ -256,3 +264,16 @@ the value is a string.
|
|||||||
when set to `1`, cobalt will try to use higher quality audio if user requests it via `youtubeBetterAudio`. will negatively impact the rate limit of a secondary youtube client with a session.
|
when set to `1`, cobalt will try to use higher quality audio if user requests it via `youtubeBetterAudio`. will negatively impact the rate limit of a secondary youtube client with a session.
|
||||||
|
|
||||||
the value is a number, either `0` or `1`.
|
the value is a number, either `0` or `1`.
|
||||||
|
|
||||||
|
## prometheus metrics
|
||||||
|
[*jump to the table*](#prometheus-metrics-vars)
|
||||||
|
|
||||||
|
### METRICS
|
||||||
|
enable prometheus compatible metrics. metrics include: successful/failed requests to services, http requests, and http requests duration.
|
||||||
|
|
||||||
|
the value is a number, either `0` or `1`.
|
||||||
|
|
||||||
|
### METRICS_PORT
|
||||||
|
port from which the metrics will be server under. these are local to the container/host.
|
||||||
|
|
||||||
|
the value is a number from 1024 to 65535.
|
@ -49,6 +49,9 @@ importers:
|
|||||||
nanoid:
|
nanoid:
|
||||||
specifier: ^5.0.9
|
specifier: ^5.0.9
|
||||||
version: 5.0.9
|
version: 5.0.9
|
||||||
|
prom-client:
|
||||||
|
specifier: ^15.1.3
|
||||||
|
version: 15.1.3
|
||||||
set-cookie-parser:
|
set-cookie-parser:
|
||||||
specifier: 2.6.0
|
specifier: 2.6.0
|
||||||
version: 2.6.0
|
version: 2.6.0
|
||||||
@ -613,6 +616,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ==}
|
resolution: {integrity: sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ==}
|
||||||
engines: {node: '>=8.0'}
|
engines: {node: '>=8.0'}
|
||||||
|
|
||||||
|
'@opentelemetry/api@1.9.0':
|
||||||
|
resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==}
|
||||||
|
engines: {node: '>=8.0.0'}
|
||||||
|
|
||||||
'@pkgjs/parseargs@0.11.0':
|
'@pkgjs/parseargs@0.11.0':
|
||||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
@ -930,6 +937,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
|
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
bintrees@1.0.2:
|
||||||
|
resolution: {integrity: sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==}
|
||||||
|
|
||||||
body-parser@1.20.3:
|
body-parser@1.20.3:
|
||||||
resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==}
|
resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==}
|
||||||
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
|
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
|
||||||
@ -1749,6 +1759,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
|
resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
|
||||||
engines: {node: '>=0.4.0'}
|
engines: {node: '>=0.4.0'}
|
||||||
|
|
||||||
|
prom-client@15.1.3:
|
||||||
|
resolution: {integrity: sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==}
|
||||||
|
engines: {node: ^16 || ^18 || >=20}
|
||||||
|
|
||||||
proxy-addr@2.0.7:
|
proxy-addr@2.0.7:
|
||||||
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
|
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
|
||||||
engines: {node: '>= 0.10'}
|
engines: {node: '>= 0.10'}
|
||||||
@ -1982,6 +1996,9 @@ packages:
|
|||||||
syscall-napi@0.0.6:
|
syscall-napi@0.0.6:
|
||||||
resolution: {integrity: sha512-qHbwjyFXAAekKUXxl70lhDiBYJ3e7XM7kQwu7LV3F0pHMenKox+VcZPZkRkhdmL/wNJD3NmrMGnL7161kdecUQ==}
|
resolution: {integrity: sha512-qHbwjyFXAAekKUXxl70lhDiBYJ3e7XM7kQwu7LV3F0pHMenKox+VcZPZkRkhdmL/wNJD3NmrMGnL7161kdecUQ==}
|
||||||
|
|
||||||
|
tdigest@0.1.2:
|
||||||
|
resolution: {integrity: sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==}
|
||||||
|
|
||||||
thenify-all@1.6.0:
|
thenify-all@1.6.0:
|
||||||
resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
|
resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
|
||||||
engines: {node: '>=0.8'}
|
engines: {node: '>=0.8'}
|
||||||
@ -2363,7 +2380,7 @@ snapshots:
|
|||||||
'@eslint/config-array@0.19.1':
|
'@eslint/config-array@0.19.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@eslint/object-schema': 2.1.5
|
'@eslint/object-schema': 2.1.5
|
||||||
debug: 4.3.6
|
debug: 4.4.0
|
||||||
minimatch: 3.1.2
|
minimatch: 3.1.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
@ -2375,7 +2392,7 @@ snapshots:
|
|||||||
'@eslint/eslintrc@3.2.0':
|
'@eslint/eslintrc@3.2.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
ajv: 6.12.6
|
ajv: 6.12.6
|
||||||
debug: 4.3.6
|
debug: 4.4.0
|
||||||
espree: 10.3.0
|
espree: 10.3.0
|
||||||
globals: 14.0.0
|
globals: 14.0.0
|
||||||
ignore: 5.3.1
|
ignore: 5.3.1
|
||||||
@ -2478,6 +2495,8 @@ snapshots:
|
|||||||
|
|
||||||
'@oozcitak/util@8.3.8': {}
|
'@oozcitak/util@8.3.8': {}
|
||||||
|
|
||||||
|
'@opentelemetry/api@1.9.0': {}
|
||||||
|
|
||||||
'@pkgjs/parseargs@0.11.0':
|
'@pkgjs/parseargs@0.11.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@ -2675,7 +2694,7 @@ snapshots:
|
|||||||
'@typescript-eslint/types': 8.18.0
|
'@typescript-eslint/types': 8.18.0
|
||||||
'@typescript-eslint/typescript-estree': 8.18.0(typescript@5.5.4)
|
'@typescript-eslint/typescript-estree': 8.18.0(typescript@5.5.4)
|
||||||
'@typescript-eslint/visitor-keys': 8.18.0
|
'@typescript-eslint/visitor-keys': 8.18.0
|
||||||
debug: 4.3.6
|
debug: 4.4.0
|
||||||
eslint: 9.16.0
|
eslint: 9.16.0
|
||||||
typescript: 5.5.4
|
typescript: 5.5.4
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@ -2690,7 +2709,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/typescript-estree': 8.18.0(typescript@5.5.4)
|
'@typescript-eslint/typescript-estree': 8.18.0(typescript@5.5.4)
|
||||||
'@typescript-eslint/utils': 8.18.0(eslint@9.16.0)(typescript@5.5.4)
|
'@typescript-eslint/utils': 8.18.0(eslint@9.16.0)(typescript@5.5.4)
|
||||||
debug: 4.3.6
|
debug: 4.4.0
|
||||||
eslint: 9.16.0
|
eslint: 9.16.0
|
||||||
ts-api-utils: 1.3.0(typescript@5.5.4)
|
ts-api-utils: 1.3.0(typescript@5.5.4)
|
||||||
typescript: 5.5.4
|
typescript: 5.5.4
|
||||||
@ -2703,7 +2722,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/types': 8.18.0
|
'@typescript-eslint/types': 8.18.0
|
||||||
'@typescript-eslint/visitor-keys': 8.18.0
|
'@typescript-eslint/visitor-keys': 8.18.0
|
||||||
debug: 4.3.6
|
debug: 4.4.0
|
||||||
fast-glob: 3.3.2
|
fast-glob: 3.3.2
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
minimatch: 9.0.5
|
minimatch: 9.0.5
|
||||||
@ -2746,7 +2765,7 @@ snapshots:
|
|||||||
|
|
||||||
agent-base@6.0.2:
|
agent-base@6.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
debug: 4.3.6
|
debug: 4.4.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
@ -2790,6 +2809,8 @@ snapshots:
|
|||||||
|
|
||||||
binary-extensions@2.3.0: {}
|
binary-extensions@2.3.0: {}
|
||||||
|
|
||||||
|
bintrees@1.0.2: {}
|
||||||
|
|
||||||
body-parser@1.20.3:
|
body-parser@1.20.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
bytes: 3.1.2
|
bytes: 3.1.2
|
||||||
@ -3320,7 +3341,7 @@ snapshots:
|
|||||||
https-proxy-agent@5.0.1:
|
https-proxy-agent@5.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
agent-base: 6.0.2
|
agent-base: 6.0.2
|
||||||
debug: 4.3.6
|
debug: 4.4.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
@ -3608,6 +3629,11 @@ snapshots:
|
|||||||
|
|
||||||
progress@2.0.3: {}
|
progress@2.0.3: {}
|
||||||
|
|
||||||
|
prom-client@15.1.3:
|
||||||
|
dependencies:
|
||||||
|
'@opentelemetry/api': 1.9.0
|
||||||
|
tdigest: 0.1.2
|
||||||
|
|
||||||
proxy-addr@2.0.7:
|
proxy-addr@2.0.7:
|
||||||
dependencies:
|
dependencies:
|
||||||
forwarded: 0.2.0
|
forwarded: 0.2.0
|
||||||
@ -3866,6 +3892,10 @@ snapshots:
|
|||||||
syscall-napi@0.0.6:
|
syscall-napi@0.0.6:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
tdigest@0.1.2:
|
||||||
|
dependencies:
|
||||||
|
bintrees: 1.0.2
|
||||||
|
|
||||||
thenify-all@1.6.0:
|
thenify-all@1.6.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
thenify: 3.3.1
|
thenify: 3.3.1
|
||||||
|
Loading…
Reference in New Issue
Block a user