diff --git a/src/discord.rs b/src/discord.rs index 754f37d..009fc24 100644 --- a/src/discord.rs +++ b/src/discord.rs @@ -2,8 +2,8 @@ use crate::metrics; use crate::metrics::{ - ActivityLabels, BoostLabels, BotLabels, EmoteUsedLabels, GuildsLabels, MemberLabels, - MemberStatusLabels, MemberVoiceLabels, MessageSentLabels, + ActivityLabels, BoostLabels, BotLabels, ChannelLabels, EmoteUsedLabels, GuildsLabels, + MemberLabels, MemberStatusLabels, MemberVoiceLabels, MessageSentLabels, }; use serenity::all::{ parse_emoji, ChannelId, Context, EventHandler, GatewayIntents, Guild, GuildChannel, GuildId, @@ -47,25 +47,25 @@ fn category_channel( ctx: &Context, guild_id: GuildId, channel_id: ChannelId, -) -> (Option, GuildChannel) { +) -> (Option, ChannelId) { // Get base let guild = ctx.cache.guild(guild_id).expect("Guild not found"); let mut channel = &guild.channels[&channel_id]; // Handle category let Some(parent_id) = channel.parent_id else { - return (None, channel.clone()); + return (None, channel.id); }; let category = &guild.channels[&parent_id]; // Handle thread let Some(parent_id) = category.parent_id else { - return (Some(category.clone()), channel.clone()); + return (Some(category.id), channel.id); }; channel = category; let category = &guild.channels[&parent_id]; - (Some(category.clone()), channel.clone()) + (Some(category.id), channel.id) } #[async_trait] @@ -81,6 +81,20 @@ impl EventHandler for Handler { }) .set(1); + // Handle `channel` metric + for channel in guild.channels.values() { + self.metrics_handler + .channel + .get_or_create(&ChannelLabels { + guild_id: guild.id.get(), + channel_id: channel.id.get(), + channel_name: channel.name.clone(), + channel_nsfw: channel.nsfw.into(), + channel_type: channel.kind.name().to_string(), + }) + .set(1); + } + // Handle `boost` metric self.metrics_handler .boost @@ -179,10 +193,8 @@ impl EventHandler for Handler { .member_voice .get_or_create(&MemberVoiceLabels { guild_id: guild.id.into(), - category_id: category.as_ref().map(|ch| ch.id.into()), - category_name: category.as_ref().map(|ch| ch.name.clone()), - channel_id: channel.id.into(), - channel_name: channel.name.clone(), + category_id: category.as_ref().map(|ch| ch.get()), + channel_id: channel.into(), self_stream: voice.self_stream.unwrap_or(false).into(), self_video: voice.self_video.into(), self_deaf: voice.self_deaf.into(), @@ -216,6 +228,85 @@ impl EventHandler for Handler { guild_id: incomplete.id.into(), }) .set(0); + + // TODO handle other metrics as well! Consider syncing with guild_create "is_new" + } + + async fn channel_create(&self, _ctx: Context, channel: GuildChannel) { + info!( + guild_id = channel.guild_id.get(), + channel_id = channel.id.get(), + "Channel create" + ); + + self.metrics_handler + .channel + .get_or_create(&ChannelLabels { + guild_id: channel.guild_id.get(), + channel_id: channel.id.get(), + channel_name: channel.name.clone(), + channel_nsfw: channel.nsfw.into(), + channel_type: channel.kind.name().to_string(), + }) + .set(1); + } + + async fn channel_update(&self, _ctx: Context, old: Option, new: GuildChannel) { + info!( + guild_id = new.guild_id.get(), + channel_id = new.id.get(), + "Channel update" + ); + + // Decrement old if available + if let Some(old) = old { + self.metrics_handler + .channel + .get_or_create(&ChannelLabels { + guild_id: old.guild_id.get(), + channel_id: old.id.get(), + channel_name: old.name.clone(), + channel_nsfw: old.nsfw.into(), + channel_type: old.kind.name().to_string(), + }) + .set(0); + } + + // Increment new + self.metrics_handler + .channel + .get_or_create(&ChannelLabels { + guild_id: new.guild_id.get(), + channel_id: new.id.get(), + channel_name: new.name.clone(), + channel_nsfw: new.nsfw.into(), + channel_type: new.kind.name().to_string(), + }) + .set(1); + } + + async fn channel_delete( + &self, + _ctx: Context, + channel: GuildChannel, + _messages: Option>, + ) { + info!( + guild_id = channel.guild_id.get(), + channel_id = channel.id.get(), + "Channel delete" + ); + + self.metrics_handler + .channel + .get_or_create(&ChannelLabels { + guild_id: channel.guild_id.get(), + channel_id: channel.id.get(), + channel_name: channel.name.clone(), + channel_nsfw: channel.nsfw.into(), + channel_type: channel.kind.name().to_string(), + }) + .set(0); } async fn guild_member_addition(&self, _ctx: Context, new_member: Member) { @@ -317,10 +408,8 @@ impl EventHandler for Handler { .message_sent .get_or_create(&MessageSentLabels { guild_id: guild_id.into(), - category_id: category.as_ref().map(|ch| ch.id.into()), - category_name: category.as_ref().map(|ch| ch.name.clone()), - channel_id: channel.id.into(), - channel_name: channel.name.clone(), + category_id: category.as_ref().map(|ch| ch.get()), + channel_id: channel.into(), }) .inc(); @@ -335,10 +424,8 @@ impl EventHandler for Handler { .emote_used .get_or_create(&EmoteUsedLabels { guild_id: guild_id.into(), - category_id: category.as_ref().map(|ch| ch.id.into()), - category_name: category.as_ref().map(|ch| ch.name.clone()), - channel_id: channel.id.into(), - channel_name: channel.name.clone(), + category_id: category.as_ref().map(|ch| ch.get()), + channel_id: channel.into(), reaction: false.into(), emoji_id: emoji.id.into(), emoji_name: Some(emoji.name), @@ -373,10 +460,8 @@ impl EventHandler for Handler { .emote_used .get_or_create(&EmoteUsedLabels { guild_id: guild_id.into(), - category_id: category.as_ref().map(|ch| ch.id.into()), - category_name: category.as_ref().map(|ch| ch.name.clone()), - channel_id: channel.id.into(), - channel_name: channel.name.clone(), + category_id: category.as_ref().map(|ch| ch.get()), + channel_id: channel.into(), reaction: true.into(), emoji_id: id.into(), emoji_name: name, @@ -482,10 +567,8 @@ impl EventHandler for Handler { .member_voice .get_or_create(&MemberVoiceLabels { guild_id: guild_id.into(), - category_id: category.as_ref().map(|ch| ch.id.into()), - category_name: category.as_ref().map(|ch| ch.name.clone()), - channel_id: channel.id.into(), - channel_name: channel.name.clone(), + category_id: category.as_ref().map(|ch| ch.get()), + channel_id: channel.into(), self_stream: old.self_stream.unwrap_or(false).into(), self_video: old.self_video.into(), self_deaf: old.self_deaf.into(), @@ -514,10 +597,8 @@ impl EventHandler for Handler { .member_voice .get_or_create(&MemberVoiceLabels { guild_id: guild_id.into(), - category_id: category.as_ref().map(|ch| ch.id.into()), - category_name: category.as_ref().map(|ch| ch.name.clone()), - channel_id: channel.id.into(), - channel_name: channel.name.clone(), + category_id: category.as_ref().map(|ch| ch.get()), + channel_id: channel.into(), self_stream: new.self_stream.unwrap_or(false).into(), self_video: new.self_video.into(), self_deaf: new.self_deaf.into(), diff --git a/src/metrics.rs b/src/metrics.rs index 6eca81e..19d536a 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -56,6 +56,16 @@ pub struct GuildsLabels { pub guild_id: u64, } +/// [`ChannelLabels`] are the [labels](EncodeLabelSet) for the `channel` metric. +#[derive(Clone, Debug, Hash, PartialEq, Eq, EncodeLabelSet)] +pub struct ChannelLabels { + pub guild_id: u64, + pub channel_id: u64, + pub channel_name: String, + pub channel_nsfw: Boolean, + pub channel_type: String, +} + /// [`BoostLabels`] are the [labels](EncodeLabelSet) for the `boost` metric. #[derive(Clone, Debug, Hash, PartialEq, Eq, EncodeLabelSet)] pub struct BoostLabels { @@ -90,9 +100,7 @@ pub struct MemberStatusLabels { pub struct MemberVoiceLabels { pub guild_id: u64, pub category_id: Option, - pub category_name: Option, pub channel_id: u64, - pub channel_name: String, pub self_stream: Boolean, pub self_video: Boolean, pub self_deaf: Boolean, @@ -100,13 +108,12 @@ pub struct MemberVoiceLabels { } /// [`MessageSentLabels`] are the [labels](EncodeLabelSet) for the `message_sent` metric. +#[allow(clippy::struct_field_names)] #[derive(Clone, Debug, Hash, PartialEq, Eq, EncodeLabelSet)] pub struct MessageSentLabels { pub guild_id: u64, pub category_id: Option, - pub category_name: Option, pub channel_id: u64, - pub channel_name: String, } /// [`EmoteUsedLabels`] are the [labels](EncodeLabelSet) for the `emote_used` metric. @@ -114,9 +121,7 @@ pub struct MessageSentLabels { pub struct EmoteUsedLabels { pub guild_id: u64, pub category_id: Option, - pub category_name: Option, pub channel_id: u64, - pub channel_name: String, pub reaction: Boolean, pub emoji_id: u64, pub emoji_name: Option, @@ -134,6 +139,7 @@ pub struct ActivityLabels { pub struct Handler { registry: Registry, pub guild: Family, + pub channel: Family, pub boost: Family, pub member: Family, pub bot: Family, @@ -161,6 +167,14 @@ impl Handler { guild.clone(), ); + debug!(metrics_name = "channel", "Building metric"); + let channel = Family::::default(); + registry.register( + "channel", + "The number of channels on the guild.", + channel.clone(), + ); + debug!(metrics_name = "boost", "Building metric"); let boost = Family::::default(); registry.register( @@ -229,6 +243,7 @@ impl Handler { registry, // metrics guild, + channel, boost, member, bot,