mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-19 15:26:59 +08:00
refactor(infra): directory structure (#4615)
This commit is contained in:
18
packages/backend/server/src/metrics/controller.ts
Normal file
18
packages/backend/server/src/metrics/controller.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { Controller, Get, Res } from '@nestjs/common';
|
||||
import type { Response } from 'express';
|
||||
import { register } from 'prom-client';
|
||||
|
||||
import { PrismaService } from '../prisma';
|
||||
|
||||
@Controller()
|
||||
export class MetricsController {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
@Get('/metrics')
|
||||
async index(@Res() res: Response): Promise<void> {
|
||||
res.header('Content-Type', register.contentType);
|
||||
const prismaMetrics = await this.prisma.$metrics.prometheus();
|
||||
const appMetrics = await register.metrics();
|
||||
res.send(appMetrics + prismaMetrics);
|
||||
}
|
||||
}
|
||||
12
packages/backend/server/src/metrics/index.ts
Normal file
12
packages/backend/server/src/metrics/index.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Global, Module } from '@nestjs/common';
|
||||
|
||||
import { MetricsController } from '../metrics/controller';
|
||||
import { Metrics } from './metrics';
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
providers: [Metrics],
|
||||
exports: [Metrics],
|
||||
controllers: [MetricsController],
|
||||
})
|
||||
export class MetricsModule {}
|
||||
28
packages/backend/server/src/metrics/metrics.ts
Normal file
28
packages/backend/server/src/metrics/metrics.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { Injectable, OnModuleDestroy } from '@nestjs/common';
|
||||
import { register } from 'prom-client';
|
||||
|
||||
import { metricsCreator } from './utils';
|
||||
|
||||
@Injectable()
|
||||
export class Metrics implements OnModuleDestroy {
|
||||
onModuleDestroy(): void {
|
||||
register.clear();
|
||||
}
|
||||
|
||||
socketIOEventCounter = metricsCreator.counter('socket_io_counter', ['event']);
|
||||
socketIOEventTimer = metricsCreator.timer('socket_io_timer', ['event']);
|
||||
socketIOConnectionGauge = metricsCreator.gauge(
|
||||
'socket_io_connection_counter'
|
||||
);
|
||||
|
||||
gqlRequest = metricsCreator.counter('gql_request', ['operation']);
|
||||
gqlError = metricsCreator.counter('gql_error', ['operation']);
|
||||
gqlTimer = metricsCreator.timer('gql_timer', ['operation']);
|
||||
|
||||
jwstCodecMerge = metricsCreator.counter('jwst_codec_merge');
|
||||
jwstCodecDidnotMatch = metricsCreator.counter('jwst_codec_didnot_match');
|
||||
jwstCodecFail = metricsCreator.counter('jwst_codec_fail');
|
||||
|
||||
authCounter = metricsCreator.counter('auth');
|
||||
authFailCounter = metricsCreator.counter('auth_fail', ['reason']);
|
||||
}
|
||||
73
packages/backend/server/src/metrics/utils.ts
Normal file
73
packages/backend/server/src/metrics/utils.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import { Counter, Gauge, Summary } from 'prom-client';
|
||||
|
||||
type LabelValues<T extends string> = Partial<Record<T, string | number>>;
|
||||
type MetricsCreator<T extends string> = (
|
||||
value: number,
|
||||
labels: LabelValues<T>
|
||||
) => void;
|
||||
type TimerMetricsCreator<T extends string> = (
|
||||
labels: LabelValues<T>
|
||||
) => () => number;
|
||||
|
||||
export const metricsCreatorGenerator = () => {
|
||||
const counterCreator = <T extends string>(
|
||||
name: string,
|
||||
labelNames?: T[]
|
||||
): MetricsCreator<T> => {
|
||||
const counter = new Counter({
|
||||
name,
|
||||
help: name,
|
||||
...(labelNames ? { labelNames } : {}),
|
||||
});
|
||||
|
||||
return (value: number, labels: LabelValues<T>) => {
|
||||
counter.inc(labels, value);
|
||||
};
|
||||
};
|
||||
|
||||
const gaugeCreator = <T extends string>(
|
||||
name: string,
|
||||
labelNames?: T[]
|
||||
): MetricsCreator<T> => {
|
||||
const gauge = new Gauge({
|
||||
name,
|
||||
help: name,
|
||||
...(labelNames ? { labelNames } : {}),
|
||||
});
|
||||
|
||||
return (value: number, labels: LabelValues<T>) => {
|
||||
gauge.set(labels, value);
|
||||
};
|
||||
};
|
||||
|
||||
const timerCreator = <T extends string>(
|
||||
name: string,
|
||||
labelNames?: T[]
|
||||
): TimerMetricsCreator<T> => {
|
||||
const summary = new Summary({
|
||||
name,
|
||||
help: name,
|
||||
...(labelNames ? { labelNames } : {}),
|
||||
});
|
||||
|
||||
return (labels: LabelValues<T>) => {
|
||||
const now = process.hrtime();
|
||||
|
||||
return () => {
|
||||
const delta = process.hrtime(now);
|
||||
const value = delta[0] + delta[1] / 1e9;
|
||||
|
||||
summary.observe(labels, value);
|
||||
return value;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
counter: counterCreator,
|
||||
gauge: gaugeCreator,
|
||||
timer: timerCreator,
|
||||
};
|
||||
};
|
||||
|
||||
export const metricsCreator = metricsCreatorGenerator();
|
||||
Reference in New Issue
Block a user