diff --git a/Catalogger.Backend/Bot/Responders/Channels/ChannelCreateResponder.cs b/Catalogger.Backend/Bot/Responders/Channels/ChannelCreateResponder.cs index 935734a..0fc9d7f 100644 --- a/Catalogger.Backend/Bot/Responders/Channels/ChannelCreateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Channels/ChannelCreateResponder.cs @@ -17,7 +17,6 @@ using Catalogger.Backend.Cache.InMemoryCache; using Catalogger.Backend.Database.Repositories; using Catalogger.Backend.Extensions; using Catalogger.Backend.Services; -using Microsoft.Extensions.Logging.Configuration; using Remora.Discord.API.Abstractions.Gateway.Events; using Remora.Discord.API.Abstractions.Objects; using Remora.Discord.Extensions.Embeds; @@ -36,6 +35,8 @@ public class ChannelCreateResponder( { public async Task RespondAsync(IChannelCreate ch, CancellationToken ct = default) { + using var _ = LogUtils.Enrich(ch); + if (!ch.GuildID.IsDefined()) return Result.Success; channelCache.Set(ch); diff --git a/Catalogger.Backend/Bot/Responders/Channels/ChannelDeleteResponder.cs b/Catalogger.Backend/Bot/Responders/Channels/ChannelDeleteResponder.cs index 7e13bcb..06b4727 100644 --- a/Catalogger.Backend/Bot/Responders/Channels/ChannelDeleteResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Channels/ChannelDeleteResponder.cs @@ -35,6 +35,8 @@ public class ChannelDeleteResponder( public async Task RespondAsync(IChannelDelete evt, CancellationToken ct = default) { + using var __ = LogUtils.Enrich(evt); + if (!evt.GuildID.IsDefined()) { _logger.Debug("Deleted channel {ChannelId} is not in a guild", evt.ID); diff --git a/Catalogger.Backend/Bot/Responders/Channels/ChannelUpdateResponder.cs b/Catalogger.Backend/Bot/Responders/Channels/ChannelUpdateResponder.cs index 7ed3954..5f0ef62 100644 --- a/Catalogger.Backend/Bot/Responders/Channels/ChannelUpdateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Channels/ChannelUpdateResponder.cs @@ -40,6 +40,8 @@ public class ChannelUpdateResponder( public async Task RespondAsync(IChannelUpdate evt, CancellationToken ct = default) { + using var _ = LogUtils.Enrich(evt); + try { if (!channelCache.TryGet(evt.ID, out var oldChannel)) diff --git a/Catalogger.Backend/Bot/Responders/CustomInteractionResponder.cs b/Catalogger.Backend/Bot/Responders/CustomInteractionResponder.cs index 0281302..c07dc6d 100644 --- a/Catalogger.Backend/Bot/Responders/CustomInteractionResponder.cs +++ b/Catalogger.Backend/Bot/Responders/CustomInteractionResponder.cs @@ -13,6 +13,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . +using Catalogger.Backend.Extensions; using Microsoft.Extensions.Options; using Remora.Commands.Services; using Remora.Commands.Tokenization; @@ -23,6 +24,7 @@ using Remora.Discord.Commands.Responders; using Remora.Discord.Commands.Services; using Remora.Discord.Gateway.Responders; using Remora.Results; +using Serilog.Context; namespace Catalogger.Backend.Bot.Responders; @@ -57,21 +59,34 @@ public class CustomInteractionResponder( treeNameResolver ); - public async Task RespondAsync( - IInteractionCreate gatewayEvent, - CancellationToken ct = default - ) + public async Task RespondAsync(IInteractionCreate evt, CancellationToken ct = default) { if (config.Discord.TestMode) { _logger.Information( "Not responding to interaction create event {InteractionId} in {ChannelId} as test mode is enabled", - gatewayEvent.ID, - gatewayEvent.Channel.Map(c => c.ID).OrDefault() + evt.ID, + evt.Channel.Map(c => c.ID).OrDefault() ); return Result.Success; } - return await _inner.RespondAsync(gatewayEvent, ct); + using var _ = LogUtils.PushProperties( + ("Event", nameof(IInteractionCreate)), + ("InteractionId", evt.ID), + ("GuildId", evt.GuildID), + ("UserId", evt.User.Map(u => u.ID)), + ("MemberId", evt.Member.Map(m => m.User.Map(u => u.ID).OrDefault())), + ("ChannelId", evt.Channel.Map(c => c.ID)), + ("InteractionType", evt.Type) + ); + + using var __ = LogContext.PushProperty( + "InteractionData", + evt.Data.HasValue ? (object?)evt.Data.Value : null, + true + ); + + return await _inner.RespondAsync(evt, ct); } } diff --git a/Catalogger.Backend/Bot/Responders/Guilds/AuditLogResponder.cs b/Catalogger.Backend/Bot/Responders/Guilds/AuditLogResponder.cs index 1d88db1..fba79eb 100644 --- a/Catalogger.Backend/Bot/Responders/Guilds/AuditLogResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Guilds/AuditLogResponder.cs @@ -14,6 +14,7 @@ // along with this program. If not, see . using Catalogger.Backend.Cache.InMemoryCache; +using Catalogger.Backend.Extensions; using Remora.Discord.API.Abstractions.Gateway.Events; using Remora.Discord.API.Abstractions.Objects; using Remora.Discord.Gateway.Responders; @@ -28,6 +29,8 @@ public class AuditLogResponder(AuditLogCache auditLogCache, ILogger logger) public Task RespondAsync(IGuildAuditLogEntryCreate evt, CancellationToken ct = default) { + using var _ = LogUtils.Enrich(evt); + if (evt.TargetID == null || evt.UserID == null) return Task.FromResult(Result.Success); diff --git a/Catalogger.Backend/Bot/Responders/Guilds/GuildBanAddResponder.cs b/Catalogger.Backend/Bot/Responders/Guilds/GuildBanAddResponder.cs index f20d8c2..2feb745 100644 --- a/Catalogger.Backend/Bot/Responders/Guilds/GuildBanAddResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Guilds/GuildBanAddResponder.cs @@ -37,6 +37,7 @@ public class GuildBanAddResponder( public async Task RespondAsync(IGuildBanAdd evt, CancellationToken ct = default) { + using var _ = LogUtils.Enrich(evt); var guildConfig = await guildRepository.GetAsync(evt.GuildID); // Delay 2 seconds for the audit log diff --git a/Catalogger.Backend/Bot/Responders/Guilds/GuildBanRemoveResponder.cs b/Catalogger.Backend/Bot/Responders/Guilds/GuildBanRemoveResponder.cs index 99fcce2..cc50908 100644 --- a/Catalogger.Backend/Bot/Responders/Guilds/GuildBanRemoveResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Guilds/GuildBanRemoveResponder.cs @@ -37,6 +37,7 @@ public class GuildBanRemoveResponder( public async Task RespondAsync(IGuildBanRemove evt, CancellationToken ct = default) { + using var _ = LogUtils.Enrich(evt); var guildConfig = await guildRepository.GetAsync(evt.GuildID); // Delay 2 seconds for the audit log diff --git a/Catalogger.Backend/Bot/Responders/Guilds/GuildCreateResponder.cs b/Catalogger.Backend/Bot/Responders/Guilds/GuildCreateResponder.cs index 9d5ac61..55bac7a 100644 --- a/Catalogger.Backend/Bot/Responders/Guilds/GuildCreateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Guilds/GuildCreateResponder.cs @@ -44,6 +44,8 @@ public class GuildCreateResponder( public async Task RespondAsync(IGuildCreate evt, CancellationToken ct = default) { + using var _ = LogUtils.Enrich(evt); + ulong guildId; string? guildName = null; if (evt.Guild.TryPickT0(out var guild, out var unavailableGuild)) @@ -101,6 +103,8 @@ public class GuildCreateResponder( public async Task RespondAsync(IGuildDelete evt, CancellationToken ct = default) { + using var _ = LogUtils.Enrich(evt); + if (evt.IsUnavailable.OrDefault(false)) { _logger.Debug("Guild {GuildId} became unavailable", evt.ID); diff --git a/Catalogger.Backend/Bot/Responders/Guilds/GuildEmojisUpdateResponder.cs b/Catalogger.Backend/Bot/Responders/Guilds/GuildEmojisUpdateResponder.cs index 0ccc859..c70bd41 100644 --- a/Catalogger.Backend/Bot/Responders/Guilds/GuildEmojisUpdateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Guilds/GuildEmojisUpdateResponder.cs @@ -37,6 +37,8 @@ public class GuildEmojisUpdateResponder( public async Task RespondAsync(IGuildEmojisUpdate evt, CancellationToken ct = default) { + using var _ = LogUtils.Enrich(evt); + try { if (!emojiCache.TryGet(evt.GuildID, out var oldEmoji)) diff --git a/Catalogger.Backend/Bot/Responders/Guilds/GuildMembersChunkResponder.cs b/Catalogger.Backend/Bot/Responders/Guilds/GuildMembersChunkResponder.cs index 8a7c786..8a43b46 100644 --- a/Catalogger.Backend/Bot/Responders/Guilds/GuildMembersChunkResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Guilds/GuildMembersChunkResponder.cs @@ -14,6 +14,7 @@ // along with this program. If not, see . using Catalogger.Backend.Cache; +using Catalogger.Backend.Extensions; using Remora.Discord.API.Abstractions.Gateway.Events; using Remora.Discord.Gateway.Responders; using Remora.Results; @@ -27,6 +28,8 @@ public class GuildMembersChunkResponder(ILogger logger, IMemberCache memberCache public async Task RespondAsync(IGuildMembersChunk evt, CancellationToken ct = default) { + using var _ = LogUtils.Enrich(evt); + _logger.Debug( "Received chunk {ChunkIndex} / {ChunkCount} for guild {GuildId}", evt.ChunkIndex + 1, diff --git a/Catalogger.Backend/Bot/Responders/Guilds/GuildUpdateResponder.cs b/Catalogger.Backend/Bot/Responders/Guilds/GuildUpdateResponder.cs index ee43e98..b2992c4 100644 --- a/Catalogger.Backend/Bot/Responders/Guilds/GuildUpdateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Guilds/GuildUpdateResponder.cs @@ -37,6 +37,8 @@ public class GuildUpdateResponder( public async Task RespondAsync(IGuildUpdate evt, CancellationToken ct = default) { + using var _ = LogUtils.Enrich(evt); + try { if (!guildCache.TryGet(evt.ID, out var oldGuild)) diff --git a/Catalogger.Backend/Bot/Responders/Invites/InviteCreateResponder.cs b/Catalogger.Backend/Bot/Responders/Invites/InviteCreateResponder.cs index 329d764..d50f81d 100644 --- a/Catalogger.Backend/Bot/Responders/Invites/InviteCreateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Invites/InviteCreateResponder.cs @@ -37,6 +37,7 @@ public class InviteCreateResponder( public async Task RespondAsync(IInviteCreate evt, CancellationToken ct = default) { + using var _ = LogUtils.Enrich(evt); var guildId = evt.GuildID.Value; var invitesResult = await guildApi.GetGuildInvitesAsync(guildId, ct); diff --git a/Catalogger.Backend/Bot/Responders/Invites/InviteDeleteResponder.cs b/Catalogger.Backend/Bot/Responders/Invites/InviteDeleteResponder.cs index bb9d855..d34b3c8 100644 --- a/Catalogger.Backend/Bot/Responders/Invites/InviteDeleteResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Invites/InviteDeleteResponder.cs @@ -38,6 +38,7 @@ public class InviteDeleteResponder( public async Task RespondAsync(IInviteDelete evt, CancellationToken ct = default) { + using var _ = LogUtils.Enrich(evt); var guildId = evt.GuildID.Value; var dbDeleteCount = await inviteRepository.DeleteInviteAsync(guildId, evt.Code); diff --git a/Catalogger.Backend/Bot/Responders/Members/GuildMemberAddResponder.cs b/Catalogger.Backend/Bot/Responders/Members/GuildMemberAddResponder.cs index b873efe..6d8901c 100644 --- a/Catalogger.Backend/Bot/Responders/Members/GuildMemberAddResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Members/GuildMemberAddResponder.cs @@ -48,6 +48,8 @@ public class GuildMemberAddResponder( public async Task RespondAsync(IGuildMemberAdd member, CancellationToken ct = default) { + using var _ = LogUtils.Enrich(member); + await memberCache.SetAsync(member.GuildID, member); await memberCache.SetMemberNamesAsync(member.GuildID, [member]); diff --git a/Catalogger.Backend/Bot/Responders/Members/GuildMemberRemoveResponder.cs b/Catalogger.Backend/Bot/Responders/Members/GuildMemberRemoveResponder.cs index 94cf8cc..a2e61d1 100644 --- a/Catalogger.Backend/Bot/Responders/Members/GuildMemberRemoveResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Members/GuildMemberRemoveResponder.cs @@ -39,6 +39,8 @@ public class GuildMemberRemoveResponder( public async Task RespondAsync(IGuildMemberRemove evt, CancellationToken ct = default) { + using var _ = LogUtils.Enrich(evt); + try { var embed = new EmbedBuilder() diff --git a/Catalogger.Backend/Bot/Responders/Members/GuildMemberUpdateResponder.cs b/Catalogger.Backend/Bot/Responders/Members/GuildMemberUpdateResponder.cs index e02b790..649c945 100644 --- a/Catalogger.Backend/Bot/Responders/Members/GuildMemberUpdateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Members/GuildMemberUpdateResponder.cs @@ -48,6 +48,8 @@ public class GuildMemberUpdateResponder( CancellationToken ct = default ) { + using var _ = LogUtils.Enrich(newMember); + try { var oldMember = await memberCache.TryGetAsync(newMember.GuildID, newMember.User.ID); diff --git a/Catalogger.Backend/Bot/Responders/ReadyResponder.cs b/Catalogger.Backend/Bot/Responders/ReadyResponder.cs index 192ce72..8c43140 100644 --- a/Catalogger.Backend/Bot/Responders/ReadyResponder.cs +++ b/Catalogger.Backend/Bot/Responders/ReadyResponder.cs @@ -26,19 +26,19 @@ public class ReadyResponder(ILogger logger, WebhookExecutorService webhookExecut { private readonly ILogger _logger = logger.ForContext(); - public Task RespondAsync(IReady gatewayEvent, CancellationToken ct = default) + public Task RespondAsync(IReady evt, CancellationToken ct = default) { - var shardId = gatewayEvent.Shard.TryGet(out var shard) - ? (shard.ShardID, shard.ShardCount) - : (0, 1); + using var _ = LogUtils.Enrich(evt); + + var shardId = evt.Shard.TryGet(out var shard) ? (shard.ShardID, shard.ShardCount) : (0, 1); _logger.Information( "Ready as {User} on shard {ShardId}/{ShardCount}", - gatewayEvent.User.Tag(), + evt.User.Tag(), shardId.Item1, shardId.Item2 ); if (shardId.Item1 == 0) - webhookExecutorService.SetSelfUser(gatewayEvent.User); + webhookExecutorService.SetSelfUser(evt.User); return Task.FromResult(Result.Success); } diff --git a/Catalogger.Backend/Bot/Responders/Roles/RoleCreateResponder.cs b/Catalogger.Backend/Bot/Responders/Roles/RoleCreateResponder.cs index 0d09658..8d079d7 100644 --- a/Catalogger.Backend/Bot/Responders/Roles/RoleCreateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Roles/RoleCreateResponder.cs @@ -35,6 +35,8 @@ public class RoleCreateResponder( public async Task RespondAsync(IGuildRoleCreate evt, CancellationToken ct = default) { + using var _ = LogUtils.Enrich(evt); + _logger.Debug("Received new role {RoleId} in guild {GuildId}", evt.Role.ID, evt.GuildID); roleCache.Set(evt.Role, evt.GuildID); diff --git a/Catalogger.Backend/Bot/Responders/Roles/RoleDeleteResponder.cs b/Catalogger.Backend/Bot/Responders/Roles/RoleDeleteResponder.cs index f76b339..5f9b648 100644 --- a/Catalogger.Backend/Bot/Responders/Roles/RoleDeleteResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Roles/RoleDeleteResponder.cs @@ -35,6 +35,8 @@ public class RoleDeleteResponder( public async Task RespondAsync(IGuildRoleDelete evt, CancellationToken ct = default) { + using var __ = LogUtils.Enrich(evt); + try { if (!roleCache.TryGet(evt.RoleID, out var role)) diff --git a/Catalogger.Backend/Bot/Responders/Roles/RoleUpdateResponder.cs b/Catalogger.Backend/Bot/Responders/Roles/RoleUpdateResponder.cs index 4ed8c2f..656bb02 100644 --- a/Catalogger.Backend/Bot/Responders/Roles/RoleUpdateResponder.cs +++ b/Catalogger.Backend/Bot/Responders/Roles/RoleUpdateResponder.cs @@ -37,6 +37,8 @@ public class RoleUpdateResponder( public async Task RespondAsync(IGuildRoleUpdate evt, CancellationToken ct = default) { + using var _ = LogUtils.Enrich(evt); + try { var newRole = evt.Role; diff --git a/Catalogger.Backend/Extensions/LogUtils.cs b/Catalogger.Backend/Extensions/LogUtils.cs index b8499b5..330e5f7 100644 --- a/Catalogger.Backend/Extensions/LogUtils.cs +++ b/Catalogger.Backend/Extensions/LogUtils.cs @@ -1,4 +1,5 @@ using Remora.Discord.API.Abstractions.Gateway.Events; +using Remora.Discord.API.Abstractions.Objects; using Remora.Rest.Core; using Serilog.Context; @@ -19,7 +20,13 @@ public static class LogUtils ("ChannelId", md.ChannelID), ("MessageId", md.ID) ), - IMessageUpdate mc => PushProperties( + IMessageUpdate mu => PushProperties( + type, + ("GuildId", mu.GuildID), + ("ChannelId", mu.ChannelID), + ("MessageId", mu.ID) + ), + IMessageCreate mc => PushProperties( type, ("GuildId", mc.GuildID), ("ChannelId", mc.ChannelID), @@ -31,6 +38,93 @@ public static class LogUtils ("ChannelId", mdb.ChannelID), ("MessageIds", mdb.IDs) ), + IGuildRoleCreate grc => PushProperties( + type, + ("GuildId", grc.GuildID), + ("RoleId", grc.Role.ID) + ), + IGuildRoleUpdate gru => PushProperties( + type, + ("GuildId", gru.GuildID), + ("RoleId", gru.Role.ID) + ), + IGuildRoleDelete grd => PushProperties( + type, + ("GuildId", grd.GuildID), + ("RoleId", grd.RoleID) + ), + IGuildMemberAdd gma => PushProperties( + type, + ("GuildId", gma.GuildID), + ("UserId", gma.User.Map(u => u.ID)) + ), + IGuildMemberUpdate gmu => PushProperties( + type, + ("GuildId", gmu.GuildID), + ("UserId", gmu.User.ID) + ), + IGuildMemberRemove gmr => PushProperties( + type, + ("GuildId", gmr.GuildID), + ("UserId", gmr.User.ID) + ), + IInviteCreate ic => PushProperties( + type, + ("GuildId", ic.GuildID), + ("ChannelId", ic.ChannelID), + ("InviteCode", ic.Code) + ), + IInviteDelete id => PushProperties( + type, + ("GuildId", id.GuildID), + ("ChannelId", id.ChannelID), + ("Code", id.Code) + ), + IChannelCreate cc => PushProperties( + type, + ("GuildId", cc.GuildID), + ("ChannelId", cc.ID) + ), + IChannelUpdate cu => PushProperties( + type, + ("GuildId", cu.GuildID), + ("ChannelId", cu.ID) + ), + IChannelDelete cd => PushProperties( + type, + ("GuildId", cd.GuildID), + ("ChannelId", cd.ID) + ), + IGuildAuditLogEntryCreate ale => PushProperties( + type, + ("GuildId", ale.GuildID), + ("AuditLogEntryId", ale.ID), + ("ActionType", ale.ActionType) + ), + IGuildBanAdd gba => PushProperties( + type, + ("GuildId", gba.GuildID), + ("UserId", gba.User.ID) + ), + IGuildBanRemove gbr => PushProperties( + type, + ("GuildId", gbr.GuildID), + ("UserId", gbr.User.ID) + ), + IGuildCreate gc => PushProperties( + type, + ("GuildId", gc.Guild.Match(g => g.ID, g => g.ID)) + ), + IGuildDelete gd => PushProperties(type, ("GuildId", gd.ID)), + IGuildEmojisUpdate geu => PushProperties(type, ("GuildId", geu.GuildID)), + IGuildMembersChunk gmc => PushProperties( + type, + ("GuildId", gmc.GuildID), + ("MemberCount", gmc.Members.Count), + ("ChunkIndex", gmc.ChunkIndex), + ("ChunkCount", gmc.ChunkCount) + ), + IGuildUpdate gu => PushProperties(type, ("GuildId", gu.ID)), _ => PushProperties(type), }; }