add optional sender info collection, chat members count collection; some structurizing; reactions collector disclaimer

This commit is contained in:
soffee 2026-01-23 16:58:48 +03:00
parent 6b6c680ad5
commit fd68586d93
8 changed files with 196 additions and 107 deletions

View file

@ -12,6 +12,6 @@ services:
- "--keywords-file" - "--keywords-file"
- "/app/keywords.yml" - "/app/keywords.yml"
- "--watch-file" - "--watch-file"
- "--reactions-collector-load-history" # - "--reactions-collector-load-history"
ports: ports:
- 0.0.0.0:9669:9669 - 0.0.0.0:9669:9669

View file

@ -11,8 +11,8 @@
"build": "tsc" "build": "tsc"
}, },
"dependencies": { "dependencies": {
"@mtcute/dispatcher": "^0.24.2", "@mtcute/dispatcher": "^0.27.6",
"@mtcute/node": "^0.24.0", "@mtcute/node": "^0.27.6",
"command-line-args": "^6.0.1", "command-line-args": "^6.0.1",
"dotenv-cli": "^8.0.0", "dotenv-cli": "^8.0.0",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",

152
pnpm-lock.yaml generated
View file

@ -9,11 +9,11 @@ importers:
.: .:
dependencies: dependencies:
'@mtcute/dispatcher': '@mtcute/dispatcher':
specifier: ^0.24.2 specifier: ^0.27.6
version: 0.24.2 version: 0.27.6
'@mtcute/node': '@mtcute/node':
specifier: ^0.24.0 specifier: ^0.27.6
version: 0.24.0 version: 0.27.6
command-line-args: command-line-args:
specifier: ^6.0.1 specifier: ^6.0.1
version: 6.0.1 version: 6.0.1
@ -369,22 +369,25 @@ packages:
resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@fuman/io@0.0.14': '@fuman/io@0.0.17':
resolution: {integrity: sha512-upZlnaLguCsMg1JHpbp/L96uwu8JyO/DRKNbwGFg3PoJRjsjutasduWX23HV2W3Ts/BKgMc5XQpMgezbJ3OsYQ==} resolution: {integrity: sha512-VmMnfHtXzBfEddEfptn/oYshUzWqW2XUkdVnwKuHWphEQTQZrOWxC7G12FI9U2EhEYt4nRdrUTYk65U8GVJWYw==}
'@fuman/net@0.0.14': '@fuman/net@0.0.17':
resolution: {integrity: sha512-FD3+TWHYoc5nSOy4VMHEadP7psPhtgLD+XI9zFszapzaK4wgM3kd3KqzXc+gMe7LltY7h0jtupxoskVxtB9uuw==} resolution: {integrity: sha512-x/kK3kWQ+gy5rfsoS6QVCsodh9n/XJeM3c6m1YHPUiQ0gWWQd4CC1bcQ/rh2UHh9DQyJJeWjCQXWH2xmsVCcFQ==}
'@fuman/node@0.0.14': '@fuman/node@0.0.17':
resolution: {integrity: sha512-z62BG9G4+fZ6PzStU/hmBbqT/8IimoDPGLU/w9uwhhRtEQhlTGb2VE9OegnYL0Rne4USHx+RRAUVZDeIlrGNTw==} resolution: {integrity: sha512-XXRlJthuCnJBnIrg/tZcqCfv/cPuXuNOVUN521oJgKrW8FyFmt+lAt2MlYw3TROumGNRMtvn3ySjdQRpBT2sLw==}
peerDependencies: peerDependencies:
ws: ^8.18.1 ws: ^8.18.1
peerDependenciesMeta: peerDependenciesMeta:
ws: ws:
optional: true optional: true
'@fuman/utils@0.0.14': '@fuman/utils@0.0.15':
resolution: {integrity: sha512-HmQo6DXoYBtkN12rZsMSZRTUynByioOHpMZjfrePwUwXuKBYm9F1Rm4R7tGLTNJTG1zMXBJw1Xwy/cRqwzrujw==} resolution: {integrity: sha512-3H3WzkfG7iLKCa/yNV4s80lYD4yr5hgiNzU13ysLY2BcDqFjM08XGYuLd5wFVp4V8+DA/fe8gIDW96To/JwDyA==}
'@fuman/utils@0.0.17':
resolution: {integrity: sha512-hy1Xu1146nOspVam8FC6p4yakb1FV1V3KrS85RzcHiK7AccFKR43Fgtv8exC8Ybsw6MtMU+MRNyaPqVhA+7TsA==}
'@humanfs/core@0.19.1': '@humanfs/core@0.19.1':
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
@ -409,32 +412,32 @@ packages:
'@jridgewell/sourcemap-codec@1.5.0': '@jridgewell/sourcemap-codec@1.5.0':
resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
'@mtcute/core@0.24.2': '@mtcute/core@0.27.6':
resolution: {integrity: sha512-ZWNPQotQqgNIj0ng8kKN8C36Z+wr8V26RVCxHxB0oLKM4Z5ESIw/6PnjAABqlW9FM6Z3TaEbkUgJkYR1OoYZsQ==} resolution: {integrity: sha512-OqjQ2hchF15yJAjcAgBuWx4RCnvMED0P3kiUfU3EsDMMIJlh8TgOgm0QspIda/Uz7icZ5+pi0rHyCYblw2MMKw==}
'@mtcute/dispatcher@0.24.2': '@mtcute/dispatcher@0.27.6':
resolution: {integrity: sha512-29/OBJt51P0H5gOcd3AC4uge54jQcLWaSzq44jN5+AdfD//pqOYWGT5CfurPjyEkqZkwHw13vvRIPMaQUUkdIA==} resolution: {integrity: sha512-5ZmI5cmyeWVYY5BtPlGYB0b4oxmF86xiP/c1Wo3VQ0SElYuknf+xZDlFxt6AMlHk9d/v2rxEd+dBXB5kRczpUA==}
'@mtcute/file-id@0.23.0': '@mtcute/file-id@0.27.6':
resolution: {integrity: sha512-7n6Ppz2nkb7swYY0Kx2jpKHFxDIkJ2q3B86w2H3dZlixH7IYXzYWSbX1uzz72rDF9Se6hp+0VZ38Pj4hLkw80w==} resolution: {integrity: sha512-ZSPxbGjS6YdcZv4xW0zHJ/iR28nEBisG3G6gDTwVS4gU51SJ4vlGcwGjF1uLyEeuGGbPFemQHLCP6CMSzqMRvA==}
'@mtcute/html-parser@0.24.0': '@mtcute/html-parser@0.27.6':
resolution: {integrity: sha512-TFJ9An/jI95YH+wxxCsgE1wEdGrNj15Dx1SWPzHOnzlBqL/kjO9UrPEFdIoeOK6BBoejRNVkQgwnoqBiJCIaOA==} resolution: {integrity: sha512-zxTuT0nv0CBR4qy7KyKB9vGQ++DxeiofKJEwHFSj5oG/7qUARm21G5GZaVlel/v7oRzx6V3u9mKDzdlbv8BcxA==}
'@mtcute/markdown-parser@0.24.0': '@mtcute/markdown-parser@0.27.6':
resolution: {integrity: sha512-j+SeBp/6uTpqIB/GMrrPT9l97xmaRKZIb3mrTNt9Y6M9BS8gYqDkqlmMbhrT6flyU6/TNpyJ5YaGMIQt0OssQw==} resolution: {integrity: sha512-YB4HXeDGQi+ilbOp1qDJ/iP3VfBFrsR+gEyQcaQo/PAR4NLtD+rZ5veWM/OSVjbawYl2OpFpfXzQdINAAlaEJg==}
'@mtcute/node@0.24.0': '@mtcute/node@0.27.6':
resolution: {integrity: sha512-l+/ITNTD3uoPu9kNGFfu4na1+LN4y1i/KrcHBxq98xWyaBjxZTuD+ROvrwyKdt2mAqtAI+hFjlfgXoCdpT+osQ==} resolution: {integrity: sha512-fDnufwcRJyqMr7rpCIiSW6GIRR1j+tgM8Og1Rx38U16Ftmu3gB7Xt5K7lHJJWQHDhv59w8AiU+NksiPdTXbxxQ==}
'@mtcute/tl-runtime@0.23.0': '@mtcute/tl-runtime@0.24.3':
resolution: {integrity: sha512-/XsHBnSPkcP7dF+I8xjNdeTnYN5aWWyDHsHRAFB/5DWOBk3ATkiLg4ch/kmwYk6Rr/GUud6GG4dgCnbz9nUlxQ==} resolution: {integrity: sha512-61J3cgYgNOQT532GdIiuezRrSC7v6cc9MfvWv9GO27bRGf7JUKWVbFt4U0KzQ9Tp0J1uMOUfi1EbQKkYKacIKQ==}
'@mtcute/tl@204.0.0': '@mtcute/tl@221.0.0':
resolution: {integrity: sha512-ldWqKJ60BX2VKPE3DwjXpP8pdlEJ4yiHHVfSdielTYTItBM++PNqTO5y6dS2iZMcsk7xFrnGWmtaWd74L+VNRw==} resolution: {integrity: sha512-Wp01L9nznTMLl2s9rbKnzQ8pij72eF4HK2XIziOQoJXiObPKZxQdxvMj+C6l0ArxMFmpT0H0/3EL5RB7O6VPwg==}
'@mtcute/wasm@0.23.0': '@mtcute/wasm@0.27.0':
resolution: {integrity: sha512-T9CZHsEtz6SX6ATf6K2yZQ5kPbGLz0Nr/eiOLSueg/FRteG4lqVOfbFFSwZfs5I5t0Klvc94e1WnF6nNUGKXRQ==} resolution: {integrity: sha512-1v4eO1N1BVRQ8L+cyUsMAeLXs5suTGXyVv/tftkbd/mGGHxc+fvOWItp3Fmq+GIwN7m4VX7kztuMMLhHxv2i2Q==}
'@napi-rs/wasm-runtime@0.2.8': '@napi-rs/wasm-runtime@0.2.8':
resolution: {integrity: sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==} resolution: {integrity: sha512-OBlgKdX7gin7OIq4fadsjpg+cp2ZphvAIKucHsNfTdJiqdOmOEwQd/bHi0VwNrcw5xpBJyUw6cK/QilCqy1BSg==}
@ -707,8 +710,9 @@ packages:
base64-js@1.5.1: base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
better-sqlite3@11.3.0: better-sqlite3@12.6.2:
resolution: {integrity: sha512-iHt9j8NPYF3oKCNOO5ZI4JwThjt3Z6J6XrcwG85VNMVzv1ByqrHWv5VILEbCMFWDsoHhXvQ7oC8vgRXFAKgl9w==} resolution: {integrity: sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA==}
engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x}
bindings@1.5.0: bindings@1.5.0:
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
@ -2226,22 +2230,24 @@ snapshots:
'@eslint/core': 0.13.0 '@eslint/core': 0.13.0
levn: 0.4.1 levn: 0.4.1
'@fuman/io@0.0.14': '@fuman/io@0.0.17':
dependencies: dependencies:
'@fuman/utils': 0.0.14 '@fuman/utils': 0.0.17
'@fuman/net@0.0.14': '@fuman/net@0.0.17':
dependencies: dependencies:
'@fuman/io': 0.0.14 '@fuman/io': 0.0.17
'@fuman/utils': 0.0.14 '@fuman/utils': 0.0.17
'@fuman/node@0.0.14': '@fuman/node@0.0.17':
dependencies: dependencies:
'@fuman/io': 0.0.14 '@fuman/io': 0.0.17
'@fuman/net': 0.0.14 '@fuman/net': 0.0.17
'@fuman/utils': 0.0.14 '@fuman/utils': 0.0.17
'@fuman/utils@0.0.14': {} '@fuman/utils@0.0.15': {}
'@fuman/utils@0.0.17': {}
'@humanfs/core@0.19.1': {} '@humanfs/core@0.19.1': {}
@ -2258,62 +2264,62 @@ snapshots:
'@jridgewell/sourcemap-codec@1.5.0': {} '@jridgewell/sourcemap-codec@1.5.0': {}
'@mtcute/core@0.24.2': '@mtcute/core@0.27.6':
dependencies: dependencies:
'@fuman/io': 0.0.14 '@fuman/io': 0.0.17
'@fuman/net': 0.0.14 '@fuman/net': 0.0.17
'@fuman/utils': 0.0.14 '@fuman/utils': 0.0.17
'@mtcute/file-id': 0.23.0 '@mtcute/file-id': 0.27.6
'@mtcute/tl': 204.0.0 '@mtcute/tl': 221.0.0
'@mtcute/tl-runtime': 0.23.0 '@mtcute/tl-runtime': 0.24.3
'@types/events': 3.0.0 '@types/events': 3.0.0
long: 5.2.3 long: 5.2.3
'@mtcute/dispatcher@0.24.2': '@mtcute/dispatcher@0.27.6':
dependencies: dependencies:
'@fuman/utils': 0.0.14 '@fuman/utils': 0.0.17
'@mtcute/core': 0.24.2 '@mtcute/core': 0.27.6
'@mtcute/file-id@0.23.0': '@mtcute/file-id@0.27.6':
dependencies: dependencies:
'@fuman/utils': 0.0.14 '@fuman/utils': 0.0.17
'@mtcute/tl-runtime': 0.23.0 '@mtcute/tl-runtime': 0.24.3
long: 5.2.3 long: 5.2.3
'@mtcute/html-parser@0.24.0': '@mtcute/html-parser@0.27.6':
dependencies: dependencies:
'@mtcute/core': 0.24.2 '@mtcute/core': 0.27.6
htmlparser2: 10.0.0 htmlparser2: 10.0.0
long: 5.2.3 long: 5.2.3
'@mtcute/markdown-parser@0.24.0': '@mtcute/markdown-parser@0.27.6':
dependencies: dependencies:
'@mtcute/core': 0.24.2 '@mtcute/core': 0.27.6
long: 5.2.3 long: 5.2.3
'@mtcute/node@0.24.0': '@mtcute/node@0.27.6':
dependencies: dependencies:
'@fuman/net': 0.0.14 '@fuman/net': 0.0.17
'@fuman/node': 0.0.14 '@fuman/node': 0.0.17
'@fuman/utils': 0.0.14 '@fuman/utils': 0.0.17
'@mtcute/core': 0.24.2 '@mtcute/core': 0.27.6
'@mtcute/html-parser': 0.24.0 '@mtcute/html-parser': 0.27.6
'@mtcute/markdown-parser': 0.24.0 '@mtcute/markdown-parser': 0.27.6
'@mtcute/wasm': 0.23.0 '@mtcute/wasm': 0.27.0
better-sqlite3: 11.3.0 better-sqlite3: 12.6.2
transitivePeerDependencies: transitivePeerDependencies:
- ws - ws
'@mtcute/tl-runtime@0.23.0': '@mtcute/tl-runtime@0.24.3':
dependencies: dependencies:
'@fuman/utils': 0.0.14 '@fuman/utils': 0.0.15
long: 5.2.3 long: 5.2.3
'@mtcute/tl@204.0.0': '@mtcute/tl@221.0.0':
dependencies: dependencies:
long: 5.2.3 long: 5.2.3
'@mtcute/wasm@0.23.0': {} '@mtcute/wasm@0.27.0': {}
'@napi-rs/wasm-runtime@0.2.8': '@napi-rs/wasm-runtime@0.2.8':
dependencies: dependencies:
@ -2592,7 +2598,7 @@ snapshots:
base64-js@1.5.1: {} base64-js@1.5.1: {}
better-sqlite3@11.3.0: better-sqlite3@12.6.2:
dependencies: dependencies:
bindings: 1.5.0 bindings: 1.5.0
prebuild-install: 7.1.3 prebuild-install: 7.1.3

View file

@ -13,8 +13,18 @@ export interface Configuration {
includePeers?: number[]; includePeers?: number[];
excludePeers?: number[]; excludePeers?: number[];
keywords?: RawKeywordLike[]; keywords?: RawKeywordLike[];
reactionsCollectorLoadHistory: boolean; collectors: {
reactionsCollectorLoadHistorySize: number; dialogs: boolean;
messages: boolean;
reactions: boolean;
}
reactionsCollector: {
loadHistory: boolean,
loadHistorySize: number,
},
messagesCollector: {
includeSender: boolean,
},
} }
const optionDefinitions: OptionDefinition[] = [ const optionDefinitions: OptionDefinition[] = [
@ -25,8 +35,12 @@ const optionDefinitions: OptionDefinition[] = [
{ name: "watch-file", alias: "w", type: Boolean, defaultValue: false }, { name: "watch-file", alias: "w", type: Boolean, defaultValue: false },
{ name: "include-peers", alias: "i", type: String, multiple: true }, { name: "include-peers", alias: "i", type: String, multiple: true },
{ name: "exclude-peers", alias: "x", type: String, multiple: true }, { name: "exclude-peers", alias: "x", type: String, multiple: true },
{ name: "reactions-collector", type: Boolean, defaultValue: false },
{ name: "reactions-collector-load-history", type: Boolean, defaultValue: false }, { name: "reactions-collector-load-history", type: Boolean, defaultValue: false },
{ name: "reactions-collector-load-history-size", type: Number, defaultValue: 1000 }, { name: "reactions-collector-load-history-size", type: Number, defaultValue: 1000 },
{ name: "dialogs-collector", type: Boolean, defaultValue: true },
{ name: "messages-collector", type: Boolean, defaultValue: true },
{ name: "messages-collector-include-sender", type: Boolean, defaultValue: false },
]; ];
const cli = cmdline(optionDefinitions); const cli = cmdline(optionDefinitions);
@ -38,8 +52,18 @@ const config: Configuration = {
keywordsFile: cli["keywords-file"], keywordsFile: cli["keywords-file"],
watchFile: cli["watch-file"], watchFile: cli["watch-file"],
keywords: cli["keywords-file"] ? await readKeywords(cli["keywords-file"]) : undefined, keywords: cli["keywords-file"] ? await readKeywords(cli["keywords-file"]) : undefined,
reactionsCollectorLoadHistory: cli["reactions-collector-load-history"], collectors: {
reactionsCollectorLoadHistorySize: cli["reactions-collector-load-history-size"], dialogs: cli["dialogs-collector"],
messages: cli["messages-collector"],
reactions: cli["reactions-collector"],
},
reactionsCollector: {
loadHistory: cli["reactions-collector-load-history"],
loadHistorySize: cli["reactions-collector-load-history-size"],
},
messagesCollector: {
includeSender: cli["messages-collector-include-sender"],
},
}; };
if (cli["include-peers"] && cli["exclude-peers"]) { if (cli["include-peers"] && cli["exclude-peers"]) {

View file

@ -32,9 +32,18 @@ const user = await tg.start({
console.log("Logged in as", user.username); console.log("Logged in as", user.username);
metrics.collectDialogMetrics(tg, registry); if (config.collectors.dialogs) {
metrics.collectNewMessageMetrics(dp, registry); metrics.collectDialogMetrics(tg, registry);
metrics.collectReactionsMetrics(tg, dp, registry); }
if (config.collectors.messages) {
metrics.collectNewMessageMetrics(dp, registry);
}
if (config.collectors.reactions) {
console.log("[WARN] reactions-collector is enabled, but it is very experimental and almost does not work. i don't recommend enabling it especially for production use.")
metrics.collectReactionsMetrics(tg, dp, registry);
}
if (config.keywords) { if (config.keywords) {
const counter = new metrics.KeywordsCounter(dp, rawToPatterns(config.keywords)); const counter = new metrics.KeywordsCounter(dp, rawToPatterns(config.keywords));
@ -45,7 +54,7 @@ if (config.keywords) {
if (curr.mtimeMs === prev.mtimeMs) { if (curr.mtimeMs === prev.mtimeMs) {
return; return;
} }
console.log("[watch-file] Keywords file was updated. Re-reading keywords configuration..."); console.log("[watch-file] Keywords file was updated. Reloading keywords configuration...");
try { try {
config.keywords = await readKeywords(config.keywordsFile); config.keywords = await readKeywords(config.keywordsFile);
counter.setKeywords(rawToPatterns(config.keywords)); counter.setKeywords(rawToPatterns(config.keywords));

View file

@ -41,9 +41,27 @@ export function collectDialogMetrics(tg: TelegramClient, registry: Registry) {
}, },
}); });
const members = new Gauge({
name: "messenger_dialog_chat_members_count",
help: "Number of members in the chat",
labelNames: ["peerId"],
collect: async () => {
members.reset();
for (const d of await dialogs.get()) {
if (d.peer.type !== "chat") continue;
if (d.peer.membersCount === null) continue;
members.set({
peerId: d.peer.id,
}, d.peer.membersCount);
}
},
});
dialogs.registerMetrics(registry); dialogs.registerMetrics(registry);
registry.registerMetric(info); registry.registerMetric(info);
registry.registerMetric(unread); registry.registerMetric(unread);
registry.registerMetric(members);
} }
class DialogsHolder { class DialogsHolder {

View file

@ -2,37 +2,71 @@ import type { Dispatcher } from "@mtcute/dispatcher";
import type { Registry } from "prom-client"; import type { Registry } from "prom-client";
import { PropagationAction } from "@mtcute/dispatcher"; import { PropagationAction } from "@mtcute/dispatcher";
import { Counter } from "prom-client"; import { Counter, Gauge } from "prom-client";
import { config } from "../config.js"; import { config } from "../config.js";
import { peersConfigFilter } from "../filters.js"; import { peersConfigFilter } from "../filters.js";
export function collectNewMessageMetrics(dp: Dispatcher, registry: Registry) { export function collectNewMessageMetrics(dp: Dispatcher, registry: Registry) {
const sendersMap = new Map<number, string>();
const senderInfo = new Gauge({
name: "messenger_dialog_sender_info",
help: "Sender's information exposed as labels",
labelNames: ["senderId", "displayName"],
collect: () => {
senderInfo.reset();
for (const [senderId, displayName] of sendersMap.entries()) {
senderInfo.set({ senderId, displayName }, 1);
}
},
});
let labelNames;
if (config.messagesCollector.includeSender) {
labelNames = ["peerId", "senderId"];
} else {
labelNames = ["peerId"];
}
const messages = new Counter({ const messages = new Counter({
name: "messenger_dialog_messages_count", name: "messenger_dialog_messages_count",
help: "Messages count since exporter startup", help: "Messages count since exporter startup",
labelNames: ["peerId"], labelNames,
}); });
const media = new Counter({ const media = new Counter({
name: "messenger_dialog_media_sent_count", name: "messenger_dialog_media_sent_count",
help: "Medias sent since exporter startup", help: "Medias sent since exporter startup",
labelNames: ["peerId"], labelNames,
}); });
const stickers = new Counter({ const stickers = new Counter({
name: "messenger_dialog_stickers_sent_count", name: "messenger_dialog_stickers_sent_count",
help: "Stickers sent since exporter startup", help: "Stickers sent since exporter startup",
labelNames: ["peerId"], labelNames,
}); });
const voice = new Counter({ const voice = new Counter({
name: "messenger_dialog_voice_messages_count", name: "messenger_dialog_voice_messages_count",
help: "Voice messages sent since exporter startup", help: "Voice messages sent since exporter startup",
labelNames: ["peerId"], labelNames,
}); });
dp.onNewMessage(peersConfigFilter(config), (msg) => { dp.onNewMessage(peersConfigFilter(config), (msg) => {
let labelValues;
if (config.messagesCollector.includeSender) {
sendersMap.set(msg.sender.id, msg.sender.displayName);
labelValues = {
peerId: msg.chat.id,
senderId: msg.sender.id,
};
} else {
labelValues = {
peerId: msg.chat.id,
};
}
if (msg.media) { if (msg.media) {
let counter; let counter;
switch (msg.media.type) { switch (msg.media.type) {
@ -58,19 +92,17 @@ export function collectNewMessageMetrics(dp: Dispatcher, registry: Registry) {
} }
} }
if (counter) { if (counter) {
counter.inc({ counter.inc(labelValues);
peerId: msg.chat.id,
});
} }
} }
messages.inc({ messages.inc(labelValues);
peerId: msg.chat.id,
});
return PropagationAction.Continue; return PropagationAction.Continue;
}); });
if (config.messagesCollector.includeSender) {
registry.registerMetric(senderInfo);
}
registry.registerMetric(media); registry.registerMetric(media);
registry.registerMetric(stickers); registry.registerMetric(stickers);
registry.registerMetric(voice); registry.registerMetric(voice);

View file

@ -115,10 +115,10 @@ export async function collectReactionsMetrics(tg: TelegramClient, dp: Dispatcher
registry.registerMetric(messagesSize); registry.registerMetric(messagesSize);
registry.registerMetric(reactionsSize); registry.registerMetric(reactionsSize);
if (config.reactionsCollectorLoadHistory) { if (config.reactionsCollector.loadHistory) {
console.log("fetching dialogs history into reactions collector cache...."); console.log("fetching dialogs history into reactions collector cache....");
const historyIterOptions = { const historyIterOptions = {
limit: config.reactionsCollectorLoadHistorySize, limit: config.reactionsCollector.loadHistorySize,
}; };
for await (const dialog of tg.iterDialogs()) { for await (const dialog of tg.iterDialogs()) {
console.log("fetching dialog with peer id", dialog.peer.id); console.log("fetching dialog with peer id", dialog.peer.id);