Skip to content

Commit

Permalink
add bot metric and rename guilds metric to guild
Browse files Browse the repository at this point in the history
  • Loading branch information
wagpa committed Dec 6, 2024
1 parent 8e0e8a9 commit f576a2a
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 12 deletions.
65 changes: 59 additions & 6 deletions src/discord.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::metrics;
use crate::metrics::{
ActivityLabels, BoostLabels, EmoteUsedLabels, GuildsLabels, MemberLabels, MemberStatusLabels,
MemberVoiceLabels, MessageSentLabels,
ActivityLabels, BoostLabels, BotLabels, EmoteUsedLabels, GuildsLabels, MemberLabels,
MemberStatusLabels, MemberVoiceLabels, MessageSentLabels,
};
use axum::async_trait;
use serenity::all::{
Expand Down Expand Up @@ -82,9 +82,9 @@ impl EventHandler for Handler {
async fn guild_create(&self, ctx: Context, guild: Guild, _is_new: Option<bool>) {
info!(guild_id = guild.id.get(), "Guild create");

// Handle `guilds` metric
// Handle `guild` metric
self.metrics_handler
.guilds
.guild
.get_or_create(&GuildsLabels {
guild_id: guild.id.into(),
})
Expand All @@ -106,6 +106,31 @@ impl EventHandler for Handler {
})
.set(guild.member_count as i64);

// Handle `bot` metric
'bot: {
let mut after = None;
loop {
let Ok(members) = guild.members(&ctx.http, None, after).await else {
warn!(guild_id = guild.id.get(), "Failed to count guild bots");
// remove metric to indicate no bots counted
self.metrics_handler.bot.remove(&BotLabels {
guild_id: guild.id.into(),
});
break 'bot;
};
self.metrics_handler
.bot
.get_or_create(&BotLabels {
guild_id: guild.id.into(),
})
.inc_by(members.iter().filter(|member| member.user.bot).count() as i64);
let Some(last) = members.last() else {
break 'bot;
};
after = Some(last.user.id);
}
}

for (user_id, presence) in &guild.presences {
debug!(user_id = user_id.get(), "create presence");

Expand Down Expand Up @@ -173,13 +198,21 @@ impl EventHandler for Handler {
) {
info!(guild_id = incomplete.id.get(), "Guild delete");

// Handle `guilds` metric
// Handle `guild` metric
self.metrics_handler
.guilds
.guild
.get_or_create(&GuildsLabels {
guild_id: incomplete.id.into(),
})
.set(0);

// Handle `bot` metric
self.metrics_handler
.bot
.get_or_create(&BotLabels {
guild_id: incomplete.id.into(),
})
.set(0);
}

async fn guild_member_addition(&self, _ctx: Context, new_member: Member) {
Expand All @@ -196,6 +229,16 @@ impl EventHandler for Handler {
guild_id: new_member.guild_id.into(),
})
.inc();

// Handle `bot` metric
if new_member.user.bot {
self.metrics_handler
.bot
.get_or_create(&BotLabels {
guild_id: new_member.guild_id.into(),
})
.inc();
}
}

async fn guild_member_removal(
Expand All @@ -218,6 +261,16 @@ impl EventHandler for Handler {
guild_id: guild_id.into(),
})
.inc();

// Handle `bot` metric
if user.bot {
self.metrics_handler
.bot
.get_or_create(&BotLabels {
guild_id: guild_id.into(),
})
.dec();
}
}

async fn guild_update(
Expand Down
36 changes: 30 additions & 6 deletions src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@ pub(crate) struct MemberLabels {
pub(crate) guild_id: u64,
}

/// [BotLabels] are the [labels](EncodeLabelSet) for the "bot" metric.
///
/// This metric is not included in the member metric (using a label) as the user bot status has to
/// be explicitly requested on guild creation. As such, they are separated to ensure that the member
/// metric does not suffer from additional requests (that could potentially fail).
#[derive(Clone, Debug, Hash, PartialEq, Eq, EncodeLabelSet)]
pub(crate) struct BotLabels {
pub(crate) guild_id: u64,
}

/// [MemberStatusLabels] are the [labels](EncodeLabelSet) for the "member_status" metric.
#[derive(Clone, Debug, Hash, PartialEq, Eq, EncodeLabelSet)]
pub(crate) struct MemberStatusLabels {
Expand Down Expand Up @@ -122,9 +132,10 @@ pub(crate) struct BoostLabels {
/// Handler is the [servable](serve) bundle of metrics for the exporter.
pub(crate) struct Handler {
registry: Registry,
pub(crate) guilds: Family<GuildsLabels, Gauge>,
pub(crate) guild: Family<GuildsLabels, Gauge>,
pub(crate) message_sent: Family<MessageSentLabels, Counter>,
pub(crate) member: Family<MemberLabels, Gauge>,
pub(crate) bot: Family<BotLabels, Gauge>,
pub(crate) emote_used: Family<EmoteUsedLabels, Counter>,
pub(crate) activity: Family<ActivityLabels, Gauge>,
pub(crate) member_status: Family<MemberStatusLabels, Gauge>,
Expand All @@ -141,9 +152,13 @@ impl Handler {
debug!(prefix = PREFIX, "Building metrics registry");
let mut registry = <Registry>::with_prefix(PREFIX);

debug!(metrics_name = "guilds", "Building metric");
let guilds = Family::<GuildsLabels, Gauge>::default();
registry.register("guilds", "The total number of guilds.", guilds.clone());
debug!(metrics_name = "guild", "Building metric");
let guild = Family::<GuildsLabels, Gauge>::default();
registry.register(
"guild",
"The total number of guilds handled by the exporter.",
guild.clone(),
);

debug!(metrics_name = "message_sent", "Building metric");
let message_sent = Family::<MessageSentLabels, Counter>::default();
Expand Down Expand Up @@ -173,10 +188,18 @@ impl Handler {
let member = Family::<MemberLabels, Gauge>::default();
registry.register(
"member",
"The total number of members on the guild.",
"The total number of members (including bots) on the guild.",
member.clone(),
);

debug!(metrics_name = "bot", "Building metric");
let bot = Family::<BotLabels, Gauge>::default();
registry.register(
"bot",
"The total number of bot members on the guild.",
bot.clone(),
);

debug!(metrics_name = "member_status", "Building metric");
let member_status = Family::<MemberStatusLabels, Gauge>::default();
registry.register(
Expand Down Expand Up @@ -204,11 +227,12 @@ impl Handler {
Self {
registry,
// metrics
guilds,
guild,
message_sent,
emote_used,
activity,
member,
bot,
member_status,
member_voice,
boost,
Expand Down

0 comments on commit f576a2a

Please sign in to comment.