Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions cluebot-ng.config.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ class Config
public static $cb_redis_port = 6379;
public static $cb_redis_db = 1;
public static $cb_redis_pass = '';
public static $metrics_enabled = true;
public static $metrics_port = 9095;
// Bots which are spikey in changes and have very large edit counts
public static $bot_whitelist = ['InternetArchiveBot', 'AnomieBOT', 'Jevansen'];
Expand Down Expand Up @@ -83,10 +82,6 @@ public static function init()
self::$mw_mysql_credentials = json_decode($mysql_credentials, true);
}

if ($metrics_enabled = getenv('CBNG_METRICS_ENABLED')) {
self::$metrics_enabled = $metrics_enabled === 'true';
}

if ($port = getenv('CBNG_METRICS_PORT')) {
self::$metrics_port = (int) $port;
}
Expand Down
4 changes: 1 addition & 3 deletions cluebot-ng.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@

date_default_timezone_set('UTC');
doInit();
if (Config::$metrics_enabled) {
MetricServer::run();
}
MetricServer::run();
HttpFeed::stream();

$logger->info('Waiting for ' . Process::pendingChangesTotal() . ' pending changes');
Expand Down
8 changes: 4 additions & 4 deletions http_feed_functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,13 +173,13 @@ private static function process($event)
{
global $logger;

Metrics::increment('bot_stream_events_received_total', [$event['type'] ?? 'unknown']);
Metrics::increment('bot_stream_events_received_total', [$event['type']]);

// Skip these types, they don't directly have revisions, no point spending time constructing
// an artificial url to throw them away in the namespace check later.
if ($event['type'] === 'log') {
if (in_array($event['type'], ['log', 'categorize', 'external'])) {
$logger->debug('Skipping due to event type: ' . print_r($event, true));
Metrics::increment('bot_stream_events_skipped_total', ['event_type_log']);
Metrics::increment('bot_stream_events_skipped_total', [$event['type']]);
return;
}

Expand Down Expand Up @@ -239,7 +239,7 @@ private static function process($event)
$old_revid = $parsedUrlParams['oldid'] ?? 0;
} else {
$logger->error('Could not determine revision IDs for event: ' . print_r($event, true));
Metrics::increment('bot_stream_events_skipped_total', ['no_revision_ids']);
Metrics::increment('bot_stream_events_failed_parsing_total');
return;
}
}
Expand Down
144 changes: 101 additions & 43 deletions metric_functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,24 @@ public static function init($seedMetrics = true): void
self::registerCounter(
'bot_warnings_issued_total',
'Total warnings issued by level',
['level']
['level'],
[['1'], ['2'], ['3']]
);
self::registerCounter(
'bot_stream_events_received_total',
'Total events received from the MediaWiki EventStream',
['event_type']
['event_type'],
['edit', 'new', 'log', 'categorize', 'external']
);
self::registerCounter(
'bot_stream_events_skipped_total',
'Total events skipped at the stream level',
['reason']
['event_type'],
['log', 'categorize', 'external']
);
self::registerCounter(
'bot_stream_events_failed_parsing_total',
'Total events which could not be parsed',
);
self::registerCounter(
'bot_edits_received_total',
Expand Down Expand Up @@ -105,7 +112,19 @@ public static function init($seedMetrics = true): void
self::registerCounter(
'bot_revert_decisions_total',
'Total revert decisions made',
['decision', 'reason']
['decision', 'reason'],
[
['no', 'Run disabled'],
['no', 'User is myself'],
['no', 'Exclusion compliance'],
['no', 'User is creator'],
['no', 'User has edit count'],
['no', 'Reverted before'],
['yes', 'Angry-reverting on TFA'],
['yes', 'Angry-reverting on angry-optin'],
['yes', 'User has edit count, but warns > 10%'],
['yes', 'Default revert'],
]
);
self::registerCounter(
'bot_reverts_attempted_total',
Expand All @@ -125,17 +144,47 @@ public static function init($seedMetrics = true): void
self::registerCounter(
'bot_reverts_skipped_total',
'Total reverts skipped',
['reason']
['reason'],
[
['missing_revisions'],
['previous_revisions_by_user'],
['own_account'],
['friends_account'],
]
);
self::registerCounter(
'bot_mysql_mw_query_failures_total',
'Total replica MySQL query failures',
['query', 'reason']
['query', 'reason'],
[
['page_metadata', 'no_data'],
['page_metadata', 'timeout'],
['page_metadata', 'error'],
['page_recent_edits', 'no_data'],
['page_recent_edits', 'timeout'],
['page_recent_edits', 'error'],
['page_recent_reverts', 'no_data'],
['page_recent_reverts', 'timeout'],
['page_recent_reverts', 'error'],
['user_registration', 'no_data'],
['user_registration', 'timeout'],
['user_registration', 'error'],
['user_registration_via_revision', 'no_data'],
['user_registration_via_revision', 'timeout'],
['user_registration_via_revision'],
['user_warnings_count', 'no_data'],
['user_warnings_count', 'timeout'],
['user_warnings_count', 'error'],
['user_distinct_pages', 'no_data'],
['user_distinct_pages', 'timeout'],
['user_distinct_pages', 'error'],
]
);
self::registerCounter(
'bot_mysql_mw_credential_conn_limit_total',
'Total times a replica MySQL credential hit its connection limit',
['user']
['user'],
array_map(fn($cred) => [$cred['user']], Config::$mw_mysql_credentials)
);
self::registerCounter(
'bot_mysql_mw_connection_retries_total',
Expand All @@ -153,14 +202,26 @@ public static function init($seedMetrics = true): void
[]
);
self::registerCounter(
'bot_mysql_cb_query_failures_total',
'Total ClueBot MySQL query failures',
['query']
'bot_mysql_cb_query_total',
'Total ClueBot MySQL queries',
['query'],
[
['vandalism_insert'],
['vandalism_update_reverted'],
['vandalism_update_beaten'],
['beaten_insert'],
]
);
self::registerCounter(
'bot_redis_operation_failures_total',
'Total Redis operation failures',
['operation']
'bot_mysql_cb_query_failures_total',
'Total ClueBot MySQL query failures',
['query'],
[
['vandalism_insert'],
['vandalism_update_reverted'],
['vandalism_update_beaten'],
['beaten_insert'],
]
);

// Gauges
Expand Down Expand Up @@ -217,39 +278,45 @@ public static function init($seedMetrics = true): void
private static function seedMetricsStore(): void
{
global $logger;
if (!Config::$metrics_enabled) {
return;
}
try {
@self::registry()->wipeStorage();
} catch (\Throwable $e) {
self::$registry = null;
$logger->debug('Failed to wipe metrics storage: ' . $e->getMessage());
}
foreach (self::$definitions as $metric_name => $definition) {
if (!empty($definition['labels'])) {
continue;
}
try {
if ($definition['type'] === 'counter') {
@self::registry()
->getOrRegisterCounter('cbng', $metric_name, $definition['help'], $definition['labels'])
->incBy(0, []);
} elseif ($definition['type'] === 'gauge') {
@self::registry()
->getOrRegisterGauge('cbng', $metric_name, $definition['help'], $definition['labels'])
->set(0, []);
$labelValueSets = empty($definition['labels']) ? [[]] : ($definition['seed'] ?? []);
foreach ($labelValueSets as $labelValues) {
try {
if ($definition['type'] === 'counter') {
@self::registry()
->getOrRegisterCounter('cbng', $metric_name, $definition['help'], $definition['labels'])
->incBy(0, $labelValues);
} elseif ($definition['type'] === 'gauge') {
@self::registry()
->getOrRegisterGauge('cbng', $metric_name, $definition['help'], $definition['labels'])
->set(0, $labelValues);
}
} catch (\Throwable $e) {
self::$registry = null;
$logger->debug('Failed to seed ' . $metric_name . ': ' . $e->getMessage());
}
} catch (\Throwable $e) {
self::$registry = null;
$logger->debug('Failed to seed ' . $metric_name . ': ' . $e->getMessage());
}
}
}

private static function registerCounter(string $name, string $help, array $labelNames): void
{
self::$definitions[$name] = ['type' => 'counter', 'help' => $help, 'labels' => $labelNames];
private static function registerCounter(
string $name,
string $help,
array $labelNames,
array $seedLabelValues = []
): void {
self::$definitions[$name] = [
'type' => 'counter',
'help' => $help,
'labels' => $labelNames,
'seed' => $seedLabelValues,
];
}

private static function registerGauge(string $name, string $help, array $labelNames): void
Expand Down Expand Up @@ -294,9 +361,6 @@ public static function getMetricFamilySamples()
public static function increment(string $name, array $labelValues = []): void
{
global $logger;
if (!Config::$metrics_enabled) {
return;
}
$definition = self::$definitions[$name] ?? null;
if ($definition === null) {
$logger->warning("Unknown metric: $name");
Expand All @@ -315,9 +379,6 @@ public static function increment(string $name, array $labelValues = []): void
public static function set(string $name, float $value, array $labelValues = []): void
{
global $logger;
if (!Config::$metrics_enabled) {
return;
}
$definition = self::$definitions[$name] ?? null;
if ($definition === null) {
$logger->warning("Unknown metric: $name");
Expand All @@ -336,9 +397,6 @@ public static function set(string $name, float $value, array $labelValues = []):
public static function observe(string $name, float $value, array $labelValues = []): void
{
global $logger;
if (!Config::$metrics_enabled) {
return;
}
$definition = self::$definitions[$name] ?? null;
if ($definition === null) {
$logger->warning("Unknown metric: $name");
Expand Down
Loading