-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Expand file tree
/
Copy pathprom-instruments.ts
More file actions
67 lines (59 loc) · 2.54 KB
/
prom-instruments.ts
File metadata and controls
67 lines (59 loc) · 2.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// Prometheus instruments referenced from the hot path (PadMessageHandler).
//
// Defined in a separate file so that PadMessageHandler can import the
// recording helpers without creating a circular import with prometheus.ts
// (which already requires PadMessageHandler to read sessioninfos).
//
// The metrics themselves are added to the central Registry by prometheus.ts.
//
// Everything here is gated behind settings.scalingDiveMetrics (default false).
// When the flag is off the recording helpers short-circuit to no-ops and the
// metrics are never registered, so production deployments don't pay for
// instrumentation they don't use.
import client from 'prom-client';
import settings from './utils/Settings';
export const enabled = (): boolean => settings.scalingDiveMetrics === true;
export const changesetApplyDuration = new client.Histogram({
name: 'etherpad_changeset_apply_duration_seconds',
help: 'Time spent applying an incoming USER_CHANGES message on the server (apply path only, excludes fan-out to other clients)',
buckets: [0.001, 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 5],
});
export const socketEmitsTotal = new client.Counter({
name: 'etherpad_socket_emits_total',
help: 'Number of socket.io broadcast emits, bucketed by message type',
labelNames: ['type'],
});
export const padUsersGauge = new client.Gauge({
name: 'etherpad_pad_users',
help: 'Active users connected to a pad, keyed by padId',
labelNames: ['padId'],
});
// Allowlist of message-type label values. Anything outside this set is rolled
// into 'other' so a misbehaving plugin or HTTP-API caller passing a
// user-controlled msgString cannot explode prom-client's internal label-cardinality
// state.
const KNOWN_TYPES = new Set([
'NEW_CHANGES',
'ACCEPT_COMMIT',
'CHAT_MESSAGE',
'CLIENT_VARS',
'CLIENT_MESSAGE',
'CUSTOM',
'USER_NEWINFO',
'USERINFO_UPDATE',
'USER_LEAVE',
]);
/** Start a timer for the changeset apply path. Call the returned function when done.
* Returns a no-op stopper when the feature flag is off. */
export const recordChangesetApply = (): (() => void) => {
if (!enabled()) return () => {};
return changesetApplyDuration.startTimer();
};
/** Increment the socket-emit counter for the given message type.
* No-op when the feature flag is off. Unknown/missing types are bucketed as
* 'other' to keep label cardinality bounded. */
export const recordSocketEmit = (type: string | undefined): void => {
if (!enabled()) return;
const label = type && KNOWN_TYPES.has(type) ? type : 'other';
socketEmitsTotal.labels(label).inc();
};