feat(server): sync data with ack (#4791)

This commit is contained in:
liuyi
2023-11-02 17:05:28 +08:00
committed by GitHub
parent af9663d3e7
commit 6a93203d68
11 changed files with 697 additions and 133 deletions
+94 -13
View File
@@ -1,4 +1,8 @@
import { Counter, Gauge, Summary } from 'prom-client';
import { Counter, Gauge, register, Summary } from 'prom-client';
function getOr<T>(name: string, or: () => T): T {
return (register.getSingleMetric(name) as T) || or();
}
type LabelValues<T extends string> = Partial<Record<T, string | number>>;
type MetricsCreator<T extends string> = (
@@ -14,11 +18,15 @@ export const metricsCreatorGenerator = () => {
name: string,
labelNames?: T[]
): MetricsCreator<T> => {
const counter = new Counter({
const counter = getOr(
name,
help: name,
...(labelNames ? { labelNames } : {}),
});
() =>
new Counter({
name,
help: name,
...(labelNames ? { labelNames } : {}),
})
);
return (value: number, labels: LabelValues<T>) => {
counter.inc(labels, value);
@@ -29,11 +37,15 @@ export const metricsCreatorGenerator = () => {
name: string,
labelNames?: T[]
): MetricsCreator<T> => {
const gauge = new Gauge({
const gauge = getOr(
name,
help: name,
...(labelNames ? { labelNames } : {}),
});
() =>
new Gauge({
name,
help: name,
...(labelNames ? { labelNames } : {}),
})
);
return (value: number, labels: LabelValues<T>) => {
gauge.set(labels, value);
@@ -44,11 +56,15 @@ export const metricsCreatorGenerator = () => {
name: string,
labelNames?: T[]
): TimerMetricsCreator<T> => {
const summary = new Summary({
const summary = getOr(
name,
help: name,
...(labelNames ? { labelNames } : {}),
});
() =>
new Summary({
name,
help: name,
...(labelNames ? { labelNames } : {}),
})
);
return (labels: LabelValues<T>) => {
const now = process.hrtime();
@@ -71,3 +87,68 @@ export const metricsCreatorGenerator = () => {
};
export const metricsCreator = metricsCreatorGenerator();
export const CallTimer = (
name: string,
labels: Record<string, any> = {}
): MethodDecorator => {
const timer = metricsCreator.timer(name, Object.keys(labels));
// @ts-expect-error allow
return (
_target,
_key,
desc: TypedPropertyDescriptor<(...args: any[]) => any>
) => {
const originalMethod = desc.value;
if (!originalMethod) {
return desc;
}
desc.value = function (...args: any[]) {
const endTimer = timer(labels);
let result: any;
try {
result = originalMethod.apply(this, args);
} catch (e) {
endTimer();
throw e;
}
if (result instanceof Promise) {
return result.finally(endTimer);
} else {
endTimer();
return result;
}
};
return desc;
};
};
export const CallCounter = (
name: string,
labels: Record<string, any> = {}
): MethodDecorator => {
const count = metricsCreator.counter(name, Object.keys(labels));
// @ts-expect-error allow
return (
_target,
_key,
desc: TypedPropertyDescriptor<(...args: any[]) => any>
) => {
const originalMethod = desc.value;
if (!originalMethod) {
return desc;
}
desc.value = function (...args: any[]) {
count(1, labels);
return originalMethod.apply(this, args);
};
return desc;
};
};