mirror of
https://gitlab.com/soapbox-pub/ditto.git
synced 2025-12-06 03:19:46 +00:00
Update Prometheus metrics to conform to best practices
This commit is contained in:
parent
3fa97c0533
commit
5454942a2c
8 changed files with 42 additions and 48 deletions
|
|
@ -2,12 +2,11 @@ import { register } from 'prom-client';
|
|||
|
||||
import { AppController } from '@/app.ts';
|
||||
import { DittoDB } from '@/db/DittoDB.ts';
|
||||
import { dbAvailableConnectionsGauge, dbPoolSizeGauge } from '@/metrics.ts';
|
||||
import { dbAvailableConnectionsGauge } from '@/metrics.ts';
|
||||
|
||||
/** Prometheus/OpenMetrics controller. */
|
||||
export const metricsController: AppController = async (c) => {
|
||||
// Update some metrics at request time.
|
||||
dbPoolSizeGauge.set(DittoDB.poolSize);
|
||||
dbAvailableConnectionsGauge.set(DittoDB.availableConnections);
|
||||
|
||||
const metrics = await register.metrics();
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import {
|
|||
import { AppController } from '@/app.ts';
|
||||
import { Conf } from '@/config.ts';
|
||||
import { relayInfoController } from '@/controllers/nostr/relay-info.ts';
|
||||
import { relayConnectionsGauge, relayEventCounter, relayMessageCounter } from '@/metrics.ts';
|
||||
import { relayConnectionsGauge, relayEventsCounter, relayMessagesCounter } from '@/metrics.ts';
|
||||
import * as pipeline from '@/pipeline.ts';
|
||||
import { RelayError } from '@/RelayError.ts';
|
||||
import { Storages } from '@/storages.ts';
|
||||
|
|
@ -54,10 +54,10 @@ function connectStream(socket: WebSocket, ip: string | undefined) {
|
|||
|
||||
const result = n.json().pipe(n.clientMsg()).safeParse(e.data);
|
||||
if (result.success) {
|
||||
relayMessageCounter.inc({ verb: result.data[0] });
|
||||
relayMessagesCounter.inc({ verb: result.data[0] });
|
||||
handleMsg(result.data);
|
||||
} else {
|
||||
relayMessageCounter.inc();
|
||||
relayMessagesCounter.inc();
|
||||
send(['NOTICE', 'Invalid message.']);
|
||||
}
|
||||
};
|
||||
|
|
@ -130,7 +130,7 @@ function connectStream(socket: WebSocket, ip: string | undefined) {
|
|||
|
||||
/** Handle EVENT. Store the event. */
|
||||
async function handleEvent([_, event]: NostrClientEVENT): Promise<void> {
|
||||
relayEventCounter.inc({ kind: event.kind.toString() });
|
||||
relayEventsCounter.inc({ kind: event.kind.toString() });
|
||||
try {
|
||||
// This will store it (if eligible) and run other side-effects.
|
||||
await pipeline.handleEvent(event, AbortSignal.timeout(1000));
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Stickynotes } from '@soapbox/stickynotes';
|
||||
import { Logger } from 'kysely';
|
||||
import { dbQueryCounter, dbQueryTimeHistogram } from '@/metrics.ts';
|
||||
import { dbQueriesCounter, dbQueryDurationHistogram } from '@/metrics.ts';
|
||||
|
||||
/** Log the SQL for queries. */
|
||||
export const KyselyLogger: Logger = (event) => {
|
||||
|
|
@ -9,8 +9,8 @@ export const KyselyLogger: Logger = (event) => {
|
|||
const { query, queryDurationMillis } = event;
|
||||
const { sql, parameters } = query;
|
||||
|
||||
dbQueryCounter.inc();
|
||||
dbQueryTimeHistogram.observe(queryDurationMillis);
|
||||
dbQueriesCounter.inc();
|
||||
dbQueryDurationHistogram.observe(queryDurationMillis);
|
||||
|
||||
console.debug(
|
||||
sql,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { Semaphore } from '@lambdalisue/async';
|
|||
import { Stickynotes } from '@soapbox/stickynotes';
|
||||
|
||||
import { Conf } from '@/config.ts';
|
||||
import { firehoseEventCounter } from '@/metrics.ts';
|
||||
import { firehoseEventsCounter } from '@/metrics.ts';
|
||||
import { Storages } from '@/storages.ts';
|
||||
import { nostrNow } from '@/utils.ts';
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ export async function startFirehose(): Promise<void> {
|
|||
if (msg[0] === 'EVENT') {
|
||||
const event = msg[2];
|
||||
console.debug(`NostrEvent<${event.kind}> ${event.id}`);
|
||||
firehoseEventCounter.inc({ kind: event.kind });
|
||||
firehoseEventsCounter.inc({ kind: event.kind });
|
||||
|
||||
sem.lock(async () => {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,86 +1,81 @@
|
|||
import { Counter, Gauge, Histogram } from 'prom-client';
|
||||
|
||||
export const httpRequestCounter = new Counter({
|
||||
name: 'http_requests_total',
|
||||
export const httpRequestsCounter = new Counter({
|
||||
name: 'ditto_http_requests_total',
|
||||
help: 'Total number of HTTP requests',
|
||||
labelNames: ['method'],
|
||||
});
|
||||
|
||||
export const httpResponseCounter = new Counter({
|
||||
name: 'http_responses_total',
|
||||
export const httpResponsesCounter = new Counter({
|
||||
name: 'ditto_http_responses_total',
|
||||
help: 'Total number of HTTP responses',
|
||||
labelNames: ['method', 'path', 'status'],
|
||||
});
|
||||
|
||||
export const streamingConnectionsGauge = new Gauge({
|
||||
name: 'streaming_connections',
|
||||
name: 'ditto_streaming_connections',
|
||||
help: 'Number of active connections to the streaming API',
|
||||
});
|
||||
|
||||
export const fetchCounter = new Counter({
|
||||
name: 'fetch_total',
|
||||
name: 'ditto_fetch_total',
|
||||
help: 'Total number of fetch requests',
|
||||
labelNames: ['method'],
|
||||
});
|
||||
|
||||
export const firehoseEventCounter = new Counter({
|
||||
name: 'firehose_events_total',
|
||||
export const firehoseEventsCounter = new Counter({
|
||||
name: 'ditto_firehose_events_total',
|
||||
help: 'Total number of Nostr events processed by the firehose',
|
||||
labelNames: ['kind'],
|
||||
});
|
||||
|
||||
export const pipelineEventCounter = new Counter({
|
||||
name: 'pipeline_events_total',
|
||||
export const pipelineEventsCounter = new Counter({
|
||||
name: 'ditto_pipeline_events_total',
|
||||
help: 'Total number of Nostr events processed by the pipeline',
|
||||
labelNames: ['kind'],
|
||||
});
|
||||
|
||||
export const policyEventCounter = new Counter({
|
||||
name: 'policy_events_total',
|
||||
export const policyEventsCounter = new Counter({
|
||||
name: 'ditto_policy_events_total',
|
||||
help: 'Total number of policy OK responses',
|
||||
labelNames: ['ok'],
|
||||
});
|
||||
|
||||
export const relayEventCounter = new Counter({
|
||||
name: 'relay_events_total',
|
||||
export const relayEventsCounter = new Counter({
|
||||
name: 'ditto_relay_events_total',
|
||||
help: 'Total number of EVENT messages processed by the relay',
|
||||
labelNames: ['kind'],
|
||||
});
|
||||
|
||||
export const relayMessageCounter = new Counter({
|
||||
name: 'relay_messages_total',
|
||||
export const relayMessagesCounter = new Counter({
|
||||
name: 'ditto_relay_messages_total',
|
||||
help: 'Total number of Nostr messages processed by the relay',
|
||||
labelNames: ['verb'],
|
||||
});
|
||||
|
||||
export const relayConnectionsGauge = new Gauge({
|
||||
name: 'relay_connections',
|
||||
name: 'ditto_relay_connections',
|
||||
help: 'Number of active connections to the relay',
|
||||
});
|
||||
|
||||
export const dbQueryCounter = new Counter({
|
||||
name: 'db_query_total',
|
||||
export const dbQueriesCounter = new Counter({
|
||||
name: 'ditto_db_queries_total',
|
||||
help: 'Total number of database queries',
|
||||
labelNames: ['kind'],
|
||||
});
|
||||
|
||||
export const dbEventCounter = new Counter({
|
||||
name: 'db_events_total',
|
||||
export const dbEventsCounter = new Counter({
|
||||
name: 'ditto_db_events_total',
|
||||
help: 'Total number of database inserts',
|
||||
labelNames: ['kind'],
|
||||
});
|
||||
|
||||
export const dbPoolSizeGauge = new Gauge({
|
||||
name: 'db_pool_size',
|
||||
help: 'Number of connections in the database pool',
|
||||
});
|
||||
|
||||
export const dbAvailableConnectionsGauge = new Gauge({
|
||||
name: 'db_available_connections',
|
||||
name: 'ditto_db_available_connections',
|
||||
help: 'Number of available connections in the database pool',
|
||||
});
|
||||
|
||||
export const dbQueryTimeHistogram = new Histogram({
|
||||
name: 'db_query_duration_ms',
|
||||
export const dbQueryDurationHistogram = new Histogram({
|
||||
name: 'ditto_db_query_duration_ms',
|
||||
help: 'Duration of database queries',
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import { MiddlewareHandler } from '@hono/hono';
|
||||
|
||||
import { httpRequestCounter, httpResponseCounter } from '@/metrics.ts';
|
||||
import { httpRequestsCounter, httpResponsesCounter } from '@/metrics.ts';
|
||||
|
||||
/** Prometheus metrics middleware that tracks HTTP requests by methods and responses by status code. */
|
||||
export const metricsMiddleware: MiddlewareHandler = async (c, next) => {
|
||||
// HTTP Request.
|
||||
const { method } = c.req;
|
||||
httpRequestCounter.inc({ method });
|
||||
httpRequestsCounter.inc({ method });
|
||||
|
||||
// Wait for other handlers to run.
|
||||
await next();
|
||||
|
|
@ -16,5 +16,5 @@ export const metricsMiddleware: MiddlewareHandler = async (c, next) => {
|
|||
// Get a parameterized path name like `/posts/:id` instead of `/posts/1234`.
|
||||
// Tries to find actual route names first before falling back on potential middleware handlers like `app.use('*')`.
|
||||
const path = c.req.matchedRoutes.find((r) => r.method !== 'ALL')?.path ?? c.req.routePath;
|
||||
httpResponseCounter.inc({ method, status, path });
|
||||
httpResponsesCounter.inc({ method, status, path });
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { Conf } from '@/config.ts';
|
|||
import { DittoDB } from '@/db/DittoDB.ts';
|
||||
import { deleteAttachedMedia } from '@/db/unattached-media.ts';
|
||||
import { DittoEvent } from '@/interfaces/DittoEvent.ts';
|
||||
import { pipelineEventCounter, policyEventCounter } from '@/metrics.ts';
|
||||
import { pipelineEventsCounter, policyEventsCounter } from '@/metrics.ts';
|
||||
import { RelayError } from '@/RelayError.ts';
|
||||
import { AdminSigner } from '@/signers/AdminSigner.ts';
|
||||
import { hydrateEvents } from '@/storages/hydrate.ts';
|
||||
|
|
@ -40,7 +40,7 @@ async function handleEvent(event: DittoEvent, signal: AbortSignal): Promise<void
|
|||
if (encounterEvent(event)) return;
|
||||
if (await existsInDB(event)) return;
|
||||
debug(`NostrEvent<${event.kind}> ${event.id}`);
|
||||
pipelineEventCounter.inc({ kind: event.kind });
|
||||
pipelineEventsCounter.inc({ kind: event.kind });
|
||||
|
||||
if (event.kind !== 24133) {
|
||||
await policyFilter(event);
|
||||
|
|
@ -71,7 +71,7 @@ async function policyFilter(event: NostrEvent): Promise<void> {
|
|||
|
||||
try {
|
||||
const result = await policyWorker.call(event);
|
||||
policyEventCounter.inc({ ok: String(result[2]) });
|
||||
policyEventsCounter.inc({ ok: String(result[2]) });
|
||||
debug(JSON.stringify(result));
|
||||
RelayError.assert(result);
|
||||
} catch (e) {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import { nip27 } from 'nostr-tools';
|
|||
|
||||
import { Conf } from '@/config.ts';
|
||||
import { DittoDatabase } from '@/db/DittoDB.ts';
|
||||
import { dbEventCounter } from '@/metrics.ts';
|
||||
import { dbEventsCounter } from '@/metrics.ts';
|
||||
import { RelayError } from '@/RelayError.ts';
|
||||
import { purifyEvent } from '@/storages/hydrate.ts';
|
||||
import { isNostrId, isURL } from '@/utils.ts';
|
||||
|
|
@ -73,7 +73,7 @@ class EventsDB implements NStore {
|
|||
async event(event: NostrEvent, opts: { signal?: AbortSignal; timeout?: number } = {}): Promise<void> {
|
||||
event = purifyEvent(event);
|
||||
this.console.debug('EVENT', JSON.stringify(event));
|
||||
dbEventCounter.inc({ kind: event.kind });
|
||||
dbEventsCounter.inc({ kind: event.kind });
|
||||
|
||||
if (await this.isDeletedAdmin(event)) {
|
||||
throw new RelayError('blocked', 'event deleted by admin');
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue