From 4d2a8a151a120f800ecf94eb5cd30fff91275998 Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Mon, 23 Mar 2026 20:13:20 +0000 Subject: [PATCH 01/16] feat: create flyway migration for metrics_events table for the new dimensions column --- application/src/main/resources/db/V17__Add_Metric_Dimensions.sql | 1 + 1 file changed, 1 insertion(+) create mode 100644 application/src/main/resources/db/V17__Add_Metric_Dimensions.sql diff --git a/application/src/main/resources/db/V17__Add_Metric_Dimensions.sql b/application/src/main/resources/db/V17__Add_Metric_Dimensions.sql new file mode 100644 index 0000000000..2dec78a8d4 --- /dev/null +++ b/application/src/main/resources/db/V17__Add_Metric_Dimensions.sql @@ -0,0 +1 @@ +ALTER TABLE metric_events ADD COLUMN dimensions TEXT; From 71da3bfe0a644655b97b51577b47e5428bd44069 Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Mon, 23 Mar 2026 20:13:41 +0000 Subject: [PATCH 02/16] feat: create new count method that accepts dimensions --- .../tjbot/features/analytics/Metrics.java | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/analytics/Metrics.java b/application/src/main/java/org/togetherjava/tjbot/features/analytics/Metrics.java index 9aa0c797fe..5efa489897 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/analytics/Metrics.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/analytics/Metrics.java @@ -1,12 +1,17 @@ package org.togetherjava.tjbot.features.analytics; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.togetherjava.tjbot.db.Database; import org.togetherjava.tjbot.db.generated.tables.MetricEvents; +import javax.annotation.Nullable; + import java.time.Instant; +import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -15,6 +20,7 @@ */ public final class Metrics { private static final Logger logger = LoggerFactory.getLogger(Metrics.class); + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private final Database database; @@ -35,21 +41,40 @@ public Metrics(Database database) { * @param event the event to save */ public void count(String event) { + count(event, Map.of()); + } + + /** + * Track an event execution with custom dimensions. + * + * @param event the event to save + * @param dimensions key-value pairs providing additional context for the event + */ + public void count(String event, Map dimensions) { logger.debug("Counting new record for event: {}", event); - Instant moment = Instant.now(); - service.submit(() -> processEvent(event, moment)); + service.submit(() -> processEvent(event, Instant.now(), + dimensions.isEmpty() ? null : serializeDimensions(dimensions))); + } + private static String serializeDimensions(Map dimensions) { + try { + return OBJECT_MAPPER.writeValueAsString(dimensions); + } catch (JsonProcessingException e) { + throw new IllegalArgumentException("Failed to serialize dimensions", e); + } } /** * * @param event the event to save * @param happenedAt the moment when the event is dispatched + * @param dimensionsJson optional JSON-serialized dimensions, or null */ - private void processEvent(String event, Instant happenedAt) { + private void processEvent(String event, Instant happenedAt, @Nullable String dimensionsJson) { database.write(context -> context.newRecord(MetricEvents.METRIC_EVENTS) .setEvent(event) .setHappenedAt(happenedAt) + .setDimensions(dimensionsJson) .insert()); } From 1157a1d026528e34b6e1d9720c8d34ea8c0c7308 Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Mon, 23 Mar 2026 20:31:09 +0000 Subject: [PATCH 03/16] fix: instant and serializedDimensions outside of the executor --- .../togetherjava/tjbot/features/analytics/Metrics.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/analytics/Metrics.java b/application/src/main/java/org/togetherjava/tjbot/features/analytics/Metrics.java index 5efa489897..4fe2e3af2d 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/analytics/Metrics.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/analytics/Metrics.java @@ -52,8 +52,12 @@ public void count(String event) { */ public void count(String event, Map dimensions) { logger.debug("Counting new record for event: {}", event); - service.submit(() -> processEvent(event, Instant.now(), - dimensions.isEmpty() ? null : serializeDimensions(dimensions))); + + Instant happenedAt = Instant.now(); + String serializedDimensions = serializeDimensions(dimensions); + + service.submit(() -> processEvent(event, happenedAt, + dimensions.isEmpty() ? null : serializedDimensions)); } private static String serializeDimensions(Map dimensions) { From a5e1a0e3d6034bf95c444d3ed9a59fb7de6cfff9 Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Mon, 23 Mar 2026 20:57:56 +0000 Subject: [PATCH 04/16] docs: update the docs on `count` so people understand what dimensions are --- .../tjbot/features/analytics/Metrics.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/analytics/Metrics.java b/application/src/main/java/org/togetherjava/tjbot/features/analytics/Metrics.java index 4fe2e3af2d..9da595eaab 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/analytics/Metrics.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/analytics/Metrics.java @@ -45,12 +45,16 @@ public void count(String event) { } /** - * Track an event execution with custom dimensions. + * Track an event execution with additional contextual data. * - * @param event the event to save - * @param dimensions key-value pairs providing additional context for the event + * @param event the name of the event to record (e.g. "user_signup", "purchase") + * @param dimensions optional key-value pairs providing extra context about the event. These are + * often referred to as "metadata" and can include things like: userId: "12345", name: + * "John Smith", channel_name: "chit-chat" etc. This data helps with filtering, grouping, + * and analyzing events later. Note: A value for a metric should be a Java primitive + * (String, int, double, long float). */ - public void count(String event, Map dimensions) { + public void count(String event, Map dimensions) { logger.debug("Counting new record for event: {}", event); Instant happenedAt = Instant.now(); @@ -60,7 +64,7 @@ public void count(String event, Map dimensions) { dimensions.isEmpty() ? null : serializedDimensions)); } - private static String serializeDimensions(Map dimensions) { + private static String serializeDimensions(Map dimensions) { try { return OBJECT_MAPPER.writeValueAsString(dimensions); } catch (JsonProcessingException e) { From af40204cbcda3a145a0deda67c4f7ad606e0aa6f Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Mon, 23 Mar 2026 21:02:13 +0000 Subject: [PATCH 05/16] feat: use dimensions on metrics that use a postfix in their name --- .../togetherjava/tjbot/features/code/CodeMessageHandler.java | 2 +- .../tjbot/features/help/AutoPruneHelperRoutine.java | 2 +- .../togetherjava/tjbot/features/help/HelpThreadCommand.java | 2 +- .../java/org/togetherjava/tjbot/features/tags/TagCommand.java | 3 ++- .../tjbot/features/tophelper/TopHelpersAssignmentRoutine.java | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/code/CodeMessageHandler.java b/application/src/main/java/org/togetherjava/tjbot/features/code/CodeMessageHandler.java index 38b2c44164..bddd391352 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/code/CodeMessageHandler.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/code/CodeMessageHandler.java @@ -188,7 +188,7 @@ public void onButtonClick(ButtonInteractionEvent event, List args) { CodeFence code = extractCodeOrFallback(originalMessage.get().getContentRaw()); // Apply the selected action - metrics.count("code_action-" + codeAction.getLabel()); + metrics.count("code_action", Map.of("name", codeAction.getLabel())); return event.getHook() .editOriginalEmbeds(codeAction.apply(code)) .setActionRow(createButtons(originalMessageId, codeAction)); diff --git a/application/src/main/java/org/togetherjava/tjbot/features/help/AutoPruneHelperRoutine.java b/application/src/main/java/org/togetherjava/tjbot/features/help/AutoPruneHelperRoutine.java index 34ac5140ba..86d952fbc6 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/help/AutoPruneHelperRoutine.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/help/AutoPruneHelperRoutine.java @@ -112,7 +112,7 @@ private void pruneRoleIfFull(List members, Role targetRole, if (isRoleFull(withRole)) { logger.debug("Helper role {} is full, starting to prune.", targetRole.getName()); - metrics.count("autoprune_helper-" + targetRole.getName()); + metrics.count("autoprune_helper", Map.of("role", targetRole.getName())); pruneRole(targetRole, withRole, selectRoleChannel, when); } } diff --git a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCommand.java b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCommand.java index 459fc5a904..6c1450e308 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCommand.java @@ -162,7 +162,7 @@ private void changeCategory(SlashCommandInteractionEvent event, ThreadChannel he event.deferReply().queue(); refreshCooldownFor(Subcommand.CHANGE_CATEGORY, helpThread); - metrics.count("help-category-" + category); + metrics.count("help-category", Map.of("category", category)); helper.changeChannelCategory(helpThread, category) .flatMap(_ -> sendCategoryChangedMessage(helpThread.getGuild(), event.getHook(), helpThread, category)) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/tags/TagCommand.java b/application/src/main/java/org/togetherjava/tjbot/features/tags/TagCommand.java index 7581c5c750..b578239e73 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/tags/TagCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/tags/TagCommand.java @@ -28,6 +28,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -91,7 +92,7 @@ public void onSlashCommand(SlashCommandInteractionEvent event) { if (tagSystem.handleIsUnknownTag(id, event)) { return; } - metrics.count("tag-" + id); + metrics.count("tag", Map.of("id", id)); String tagContent = tagSystem.getTag(id).orElseThrow(); MessageEmbed contentEmbed = new EmbedBuilder().setDescription(tagContent) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/tophelper/TopHelpersAssignmentRoutine.java b/application/src/main/java/org/togetherjava/tjbot/features/tophelper/TopHelpersAssignmentRoutine.java index cb6449a24f..bc571e200c 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/tophelper/TopHelpersAssignmentRoutine.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/tophelper/TopHelpersAssignmentRoutine.java @@ -260,7 +260,7 @@ private void manageTopHelperRole(Collection currentTopHelpers, } for (long topHelperUserId : selectedTopHelperIds) { - metrics.count("top_helper-" + topHelperUserId); + metrics.count("top_helper", Map.of("userId", topHelperUserId)); } reportRoleManageSuccess(event); } From 3f2ef465edf3f3e10e12ffb03e83fefbab39bf88 Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Mon, 23 Mar 2026 21:09:14 +0000 Subject: [PATCH 06/16] feat: create migration for the offending metrics to use dimensions --- .../db/V17__Add_Metric_Dimensions.sql | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/application/src/main/resources/db/V17__Add_Metric_Dimensions.sql b/application/src/main/resources/db/V17__Add_Metric_Dimensions.sql index 2dec78a8d4..8690ce13c4 100644 --- a/application/src/main/resources/db/V17__Add_Metric_Dimensions.sql +++ b/application/src/main/resources/db/V17__Add_Metric_Dimensions.sql @@ -1 +1,26 @@ ALTER TABLE metric_events ADD COLUMN dimensions TEXT; + +UPDATE metric_events +SET event = 'code_action', + dimensions = json_object('name', SUBSTR(event, LENGTH('code_action-') + 1)) +WHERE event LIKE 'code_action-%'; + +UPDATE metric_events +SET event = 'autoprune_helper', + dimensions = json_object('role', SUBSTR(event, LENGTH('autoprune_helper-') + 1)) +WHERE event LIKE 'autoprune_helper-%'; + +UPDATE metric_events +SET event = 'help-category', + dimensions = json_object('category', SUBSTR(event, LENGTH('help-category-') + 1)) +WHERE event LIKE 'help-category-%'; + +UPDATE metric_events +SET event = 'tag', + dimensions = json_object('id', SUBSTR(event, LENGTH('tag-') + 1)) +WHERE event LIKE 'tag-%'; + +UPDATE metric_events +SET event = 'top_helper', + dimensions = json_object('userId', CAST(SUBSTR(event, LENGTH('top_helper-') + 1) AS INTEGER)) +WHERE event LIKE 'top_helper-%'; \ No newline at end of file From 30fd2b0a881a13e2a3aca0096fed0cb203bd06ee Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Mon, 23 Mar 2026 21:13:39 +0000 Subject: [PATCH 07/16] chore: sonar linting --- .../org/togetherjava/tjbot/features/help/HelpThreadCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCommand.java b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCommand.java index 6c1450e308..d3b335bdec 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCommand.java @@ -162,7 +162,7 @@ private void changeCategory(SlashCommandInteractionEvent event, ThreadChannel he event.deferReply().queue(); refreshCooldownFor(Subcommand.CHANGE_CATEGORY, helpThread); - metrics.count("help-category", Map.of("category", category)); + metrics.count(COMMAND_NAME, Map.of("category", category)); helper.changeChannelCategory(helpThread, category) .flatMap(_ -> sendCategoryChangedMessage(helpThread.getGuild(), event.getHook(), helpThread, category)) From 8a737ed9e8fab9a9b2632ec481e8c5a774558831 Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Mon, 23 Mar 2026 21:18:55 +0000 Subject: [PATCH 08/16] feat: update slash commands --- .../tjbot/features/system/BotCore.java | 9 ++++++--- .../resources/db/V17__Add_Metric_Dimensions.sql | 17 ++++++++++++++++- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/system/BotCore.java b/application/src/main/java/org/togetherjava/tjbot/features/system/BotCore.java index 5dcdc0a81a..10a505bd48 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/system/BotCore.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/system/BotCore.java @@ -385,11 +385,14 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { SlashCommand interactor = requireUserInteractor( UserInteractionType.SLASH_COMMAND.getPrefixedName(name), SlashCommand.class); - String eventName = "slash-" + name; + Map dimensions = new HashMap<>(); + dimensions.put("name", name); + if (event.getSubcommandName() != null) { - eventName += "_" + event.getSubcommandName(); + dimensions.put("subCommandName", event.getSubcommandName()); } - metrics.count(eventName); + + metrics.count("slash", dimensions); interactor.onSlashCommand(event); }); diff --git a/application/src/main/resources/db/V17__Add_Metric_Dimensions.sql b/application/src/main/resources/db/V17__Add_Metric_Dimensions.sql index 8690ce13c4..01685ad953 100644 --- a/application/src/main/resources/db/V17__Add_Metric_Dimensions.sql +++ b/application/src/main/resources/db/V17__Add_Metric_Dimensions.sql @@ -23,4 +23,19 @@ WHERE event LIKE 'tag-%'; UPDATE metric_events SET event = 'top_helper', dimensions = json_object('userId', CAST(SUBSTR(event, LENGTH('top_helper-') + 1) AS INTEGER)) -WHERE event LIKE 'top_helper-%'; \ No newline at end of file +WHERE event LIKE 'top_helper-%'; + +UPDATE metric_events +SET event = 'slash', + dimensions = json_object( + 'name', SUBSTR(event, LENGTH('slash-') + 1, INSTR(SUBSTR(event, LENGTH('slash-') + 1), '_') - 1), + 'subCommandName', SUBSTR(event, LENGTH('slash-') + 1 + INSTR(SUBSTR(event, LENGTH('slash-') + 1), '_')) + ) +WHERE event LIKE 'slash-%' + AND INSTR(SUBSTR(event, LENGTH('slash-') + 1), '_') > 0; + +UPDATE metric_events +SET event = 'slash', + dimensions = json_object('name', SUBSTR(event, LENGTH('slash-') + 1)) +WHERE event LIKE 'slash-%' + AND INSTR(SUBSTR(event, LENGTH('slash-') + 1), '_') = 0; \ No newline at end of file From b0bba150d5e024c5a1446c7e263b08cffc3db9fd Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Mon, 23 Mar 2026 21:31:32 +0000 Subject: [PATCH 09/16] chore: sonar --- .../org/togetherjava/tjbot/features/help/HelpThreadCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCommand.java b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCommand.java index d3b335bdec..e89e52aea1 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCommand.java @@ -162,7 +162,7 @@ private void changeCategory(SlashCommandInteractionEvent event, ThreadChannel he event.deferReply().queue(); refreshCooldownFor(Subcommand.CHANGE_CATEGORY, helpThread); - metrics.count(COMMAND_NAME, Map.of("category", category)); + metrics.count(COMMAND_NAME, Map.of(CHANGE_CATEGORY_SUBCOMMAND, category)); helper.changeChannelCategory(helpThread, category) .flatMap(_ -> sendCategoryChangedMessage(helpThread.getGuild(), event.getHook(), helpThread, category)) From a857e92d2cacfb48d1092e1b63cdd91bd59c8b73 Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Tue, 24 Mar 2026 11:15:25 +0000 Subject: [PATCH 10/16] feat: add user to slash command dimensions so that we know who's invoking commands --- .../java/org/togetherjava/tjbot/features/system/BotCore.java | 1 + 1 file changed, 1 insertion(+) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/system/BotCore.java b/application/src/main/java/org/togetherjava/tjbot/features/system/BotCore.java index 10a505bd48..f06413ec58 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/system/BotCore.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/system/BotCore.java @@ -387,6 +387,7 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { Map dimensions = new HashMap<>(); dimensions.put("name", name); + dimensions.put("user", event.getUser().getName()); if (event.getSubcommandName() != null) { dimensions.put("subCommandName", event.getSubcommandName()); From 0297a049eb72a0ea235df720014fa3476788c4b6 Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Tue, 24 Mar 2026 11:20:55 +0000 Subject: [PATCH 11/16] feat: add user to /tag --- .../java/org/togetherjava/tjbot/features/tags/TagCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/tags/TagCommand.java b/application/src/main/java/org/togetherjava/tjbot/features/tags/TagCommand.java index b578239e73..eb54f7375d 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/tags/TagCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/tags/TagCommand.java @@ -92,7 +92,7 @@ public void onSlashCommand(SlashCommandInteractionEvent event) { if (tagSystem.handleIsUnknownTag(id, event)) { return; } - metrics.count("tag", Map.of("id", id)); + metrics.count("tag", Map.of("id", id, "user", event.getUser().getName())); String tagContent = tagSystem.getTag(id).orElseThrow(); MessageEmbed contentEmbed = new EmbedBuilder().setDescription(tagContent) From 044fac8f54fea1b6912abf2275563b7f248790fc Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Wed, 25 Mar 2026 11:36:13 +0000 Subject: [PATCH 12/16] docs: update PP.md to include collection of user_name and dimensions inclusion --- PP.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/PP.md b/PP.md index 31544ac609..144f5c848c 100644 --- a/PP.md +++ b/PP.md @@ -44,6 +44,7 @@ In certain circumstances, you have the following data protection rights: The databases may store * `user_id` of users (the unique id of a Discord account), +* `user_name` of users (the username of a Discord account), stored as part of metric event dimensions when tracking command usage (e.g. slash commands, tag lookups), * `timestamp`s of actions (for example when a command has been used), * `guild_id` of guilds the **bot** is member of (the unique id of a Discord guild), * `channel_id` of channels belonging to guilds the **bot** is member of (the unique id of a Discord channel), @@ -51,7 +52,8 @@ The databases may store * `participant_count` of no of people who participated in help thread discussions, * `tags` aka categories to which these help threads belong to, * `timestamp`s for both when thread was created and closed, -* `message_count` the no of messages that were sent in lifecycle of any help thread +* `message_count` the no of messages that were sent in lifecycle of any help thread, +* `dimensions` optional JSON metadata attached to metric events, which may include the `user_name` of the user who triggered the event and contextual details such as the command name or tag id _Note: Help threads are just threads that are created via forum channels, used for anyone to ask questions and get help in certain problems._ From bf494c27b0c13a0f43a166a93df312ecd60f69e1 Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Thu, 26 Mar 2026 12:02:57 +0000 Subject: [PATCH 13/16] revert: help-category --- .../org/togetherjava/tjbot/features/help/HelpThreadCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCommand.java b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCommand.java index e89e52aea1..b20799c1f5 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/help/HelpThreadCommand.java @@ -162,7 +162,7 @@ private void changeCategory(SlashCommandInteractionEvent event, ThreadChannel he event.deferReply().queue(); refreshCooldownFor(Subcommand.CHANGE_CATEGORY, helpThread); - metrics.count(COMMAND_NAME, Map.of(CHANGE_CATEGORY_SUBCOMMAND, category)); + metrics.count("help-category", Map.of(CHANGE_CATEGORY_SUBCOMMAND, category)); helper.changeChannelCategory(helpThread, category) .flatMap(_ -> sendCategoryChangedMessage(helpThread.getGuild(), event.getHook(), helpThread, category)) From d951c7d440d5591d9fa154a0017cae83ea6bf009 Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Thu, 26 Mar 2026 12:23:20 +0000 Subject: [PATCH 14/16] feat: use dimensions in EmojiTrackerListener --- .../analytics/EmojiTrackerListener.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/analytics/EmojiTrackerListener.java b/application/src/main/java/org/togetherjava/tjbot/features/analytics/EmojiTrackerListener.java index f90b11b68b..b41dabe911 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/analytics/EmojiTrackerListener.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/analytics/EmojiTrackerListener.java @@ -8,6 +8,8 @@ import org.togetherjava.tjbot.features.MessageReceiverAdapter; +import java.util.Map; + /** * Listener that tracks custom emoji usage across all channels for analytics purposes. *

@@ -18,6 +20,7 @@ * custom emojis are tracked separately (e.g. {@code emoji-custom-animated-123456789}). */ public final class EmojiTrackerListener extends MessageReceiverAdapter { + private static final String METRIC_NAME = "emoji"; private final Metrics metrics; /** @@ -37,7 +40,11 @@ public void onMessageReceived(MessageReceivedEvent event) { return; } - event.getMessage().getMentions().getCustomEmojis().forEach(this::trackCustomEmoji); + event.getMessage() + .getMentions() + .getCustomEmojis() + .forEach(customEmoji -> metrics.count(METRIC_NAME, Map.of("type", "message", "id", + customEmoji.getIdLong(), "animated", customEmoji.isAnimated()))); } @Override @@ -47,11 +54,12 @@ public void onMessageReactionAdd(MessageReactionAddEvent event) { return; } - trackCustomEmoji(emoji.asCustom()); + CustomEmoji customEmoji = emoji.asCustom(); + + trackCustomEmoji("reaction", customEmoji.getIdLong(), customEmoji.isAnimated()); } - private void trackCustomEmoji(CustomEmoji emoji) { - String prefix = emoji.isAnimated() ? "emoji-custom-animated-" : "emoji-custom-"; - metrics.count(prefix + emoji.getIdLong()); + private void trackCustomEmoji(String type, long id, boolean isAnimated) { + metrics.count(METRIC_NAME, Map.of("type", type, "id", id, "animated", isAnimated)); } } From 3e52e490b1c7a8e58fc5c2c908a1ab74a5b455a7 Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Thu, 26 Mar 2026 13:01:20 +0000 Subject: [PATCH 15/16] feat: add userId to dimensions for slash command and tag --- .../java/org/togetherjava/tjbot/features/system/BotCore.java | 1 + .../java/org/togetherjava/tjbot/features/tags/TagCommand.java | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/system/BotCore.java b/application/src/main/java/org/togetherjava/tjbot/features/system/BotCore.java index f06413ec58..eaef464b5d 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/system/BotCore.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/system/BotCore.java @@ -388,6 +388,7 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { Map dimensions = new HashMap<>(); dimensions.put("name", name); dimensions.put("user", event.getUser().getName()); + dimensions.put("userId", event.getUser().getIdLong()); if (event.getSubcommandName() != null) { dimensions.put("subCommandName", event.getSubcommandName()); diff --git a/application/src/main/java/org/togetherjava/tjbot/features/tags/TagCommand.java b/application/src/main/java/org/togetherjava/tjbot/features/tags/TagCommand.java index eb54f7375d..ac0386338f 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/tags/TagCommand.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/tags/TagCommand.java @@ -92,7 +92,8 @@ public void onSlashCommand(SlashCommandInteractionEvent event) { if (tagSystem.handleIsUnknownTag(id, event)) { return; } - metrics.count("tag", Map.of("id", id, "user", event.getUser().getName())); + metrics.count("tag", Map.of("id", id, "user", event.getUser().getName(), "userId", + event.getUser().getIdLong())); String tagContent = tagSystem.getTag(id).orElseThrow(); MessageEmbed contentEmbed = new EmbedBuilder().setDescription(tagContent) From c0ea5c58c7ef0ada836e88f2850825a54ca004f1 Mon Sep 17 00:00:00 2001 From: Suraj Kumar Date: Thu, 26 Mar 2026 15:26:24 +0000 Subject: [PATCH 16/16] customEmoji --- .../tjbot/features/analytics/EmojiTrackerListener.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/org/togetherjava/tjbot/features/analytics/EmojiTrackerListener.java b/application/src/main/java/org/togetherjava/tjbot/features/analytics/EmojiTrackerListener.java index b41dabe911..a5c054bee9 100644 --- a/application/src/main/java/org/togetherjava/tjbot/features/analytics/EmojiTrackerListener.java +++ b/application/src/main/java/org/togetherjava/tjbot/features/analytics/EmojiTrackerListener.java @@ -43,8 +43,8 @@ public void onMessageReceived(MessageReceivedEvent event) { event.getMessage() .getMentions() .getCustomEmojis() - .forEach(customEmoji -> metrics.count(METRIC_NAME, Map.of("type", "message", "id", - customEmoji.getIdLong(), "animated", customEmoji.isAnimated()))); + .forEach(customEmoji -> trackCustomEmoji("message", customEmoji.getIdLong(), + customEmoji.isAnimated())); } @Override