Skip to content

Commit f56996b

Browse files
committed
Analytics: applies changes for zabuzard 1st CR;
1 parent 071c1dc commit f56996b

File tree

6 files changed

+71
-123
lines changed

6 files changed

+71
-123
lines changed

application/src/main/java/org/togetherjava/tjbot/features/analytics/AnalyticsService.java

Lines changed: 0 additions & 88 deletions
This file was deleted.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package org.togetherjava.tjbot.features.analytics;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
6+
import org.togetherjava.tjbot.db.Database;
7+
import org.togetherjava.tjbot.db.generated.tables.Analytics;
8+
9+
import java.time.Instant;
10+
import java.util.concurrent.ExecutorService;
11+
import java.util.concurrent.Executors;
12+
13+
/**
14+
* Service for tracking and recording events for analytics purposes.
15+
*/
16+
public final class Metrics {
17+
private static final Logger logger = LoggerFactory.getLogger(Metrics.class);
18+
19+
private final Database database;
20+
21+
private final ExecutorService service = Executors.newSingleThreadExecutor();
22+
23+
/**
24+
* Creates a new instance.
25+
*
26+
* @param database the database to use for storing and retrieving analytics data
27+
*/
28+
public Metrics(Database database) {
29+
this.database = database;
30+
}
31+
32+
/**
33+
* Track an event execution.
34+
*
35+
* @param event the event to save
36+
*/
37+
public void count(String event) {
38+
logger.debug("Counting new record for event: {}", event);
39+
Instant moment = Instant.now();
40+
service.submit(() -> persist(event, moment));
41+
42+
logger.debug("Event {} new record saved successfully", event);
43+
}
44+
45+
/**
46+
*
47+
* @param event the event to save
48+
* @param moment the moment when the event is dispatched
49+
*/
50+
private void persist(String event, Instant moment) {
51+
logger.debug("Persisting event: {}, at {}", event, moment);
52+
database.write(context -> context.newRecord(Analytics.ANALYTICS)
53+
.setEvent(event)
54+
.setHappenedAt(moment)
55+
.insert());
56+
logger.debug("Event {} persisted successfully", event);
57+
}
58+
59+
}

application/src/main/java/org/togetherjava/tjbot/features/analytics/package-info.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Analytics system for collecting and persisting bot activity metrics.
33
* <p>
44
* This package provides services and components that record events for later analysis and reporting
5-
* across multiple feature areas, not limited to commands.
5+
* across multiple feature areas.
66
*/
77
@MethodsReturnNonnullByDefault
88
@ParametersAreNonnullByDefault

application/src/main/java/org/togetherjava/tjbot/features/basic/PingCommand.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.togetherjava.tjbot.features.basic;
22

3-
import net.dv8tion.jda.api.entities.Guild;
43
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
54

65
import org.togetherjava.tjbot.features.CommandVisibility;
@@ -12,7 +11,6 @@
1211
* The implemented command is {@code /ping}, upon which the bot will respond with {@code Pong!}.
1312
*/
1413
public final class PingCommand extends SlashCommandAdapter {
15-
1614
/**
1715
* Creates an instance of the ping pong command.
1816
*/
@@ -27,12 +25,6 @@ public PingCommand() {
2725
*/
2826
@Override
2927
public void onSlashCommand(SlashCommandInteractionEvent event) {
30-
Guild guild = event.getGuild();
31-
if (guild == null) {
32-
event.reply("This command can only be used in a server!").setEphemeral(true).queue();
33-
return;
34-
}
35-
3628
event.reply("Pong!").queue();
3729
}
3830
}

application/src/main/java/org/togetherjava/tjbot/features/system/BotCore.java

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
import org.togetherjava.tjbot.features.UserInteractionType;
4242
import org.togetherjava.tjbot.features.UserInteractor;
4343
import org.togetherjava.tjbot.features.VoiceReceiver;
44-
import org.togetherjava.tjbot.features.analytics.AnalyticsService;
44+
import org.togetherjava.tjbot.features.analytics.Metrics;
4545
import org.togetherjava.tjbot.features.componentids.ComponentId;
4646
import org.togetherjava.tjbot.features.componentids.ComponentIdParser;
4747
import org.togetherjava.tjbot.features.componentids.ComponentIdStore;
@@ -85,7 +85,7 @@ public final class BotCore extends ListenerAdapter implements CommandProvider {
8585
private final ComponentIdStore componentIdStore;
8686
private final Map<Pattern, MessageReceiver> channelNameToMessageReceiver = new HashMap<>();
8787
private final Map<Pattern, VoiceReceiver> channelNameToVoiceReceiver = new HashMap<>();
88-
private final AnalyticsService analyticsService;
88+
private final Metrics metrics;
8989

9090
/**
9191
* Creates a new command system which uses the given database to allow commands to persist data.
@@ -100,7 +100,7 @@ public BotCore(JDA jda, Database database, Config config) {
100100
Collection<Feature> features = Features.createFeatures(jda, database, config);
101101

102102
// Initialize analytics service
103-
analyticsService = new AnalyticsService(database);
103+
metrics = new Metrics(database);
104104

105105
// Message receivers
106106
features.stream()
@@ -383,22 +383,14 @@ public void onSlashCommandInteraction(SlashCommandInteractionEvent event) {
383383
logger.debug("Received slash command '{}' (#{}) on guild '{}'", name, event.getId(),
384384
event.getGuild());
385385
COMMAND_SERVICE.execute(() -> {
386-
try {
387-
requireUserInteractor(UserInteractionType.SLASH_COMMAND.getPrefixedName(name),
388-
SlashCommand.class)
389-
.onSlashCommand(event);
390386

387+
SlashCommand interactor = requireUserInteractor(
388+
UserInteractionType.SLASH_COMMAND.getPrefixedName(name), SlashCommand.class);
391389

392-
analyticsService.recordCommandSuccess(event.getChannel().getIdLong(), name,
393-
event.getUser().getIdLong());
394-
} catch (Exception ex) {
390+
metrics.count("slash-" + name);
395391

396-
analyticsService.recordCommandFailure(event.getChannel().getIdLong(), name,
397-
event.getUser().getIdLong(),
398-
ex.getMessage() != null ? ex.getMessage() : ex.getClass().getSimpleName());
392+
interactor.onSlashCommand(event);
399393

400-
throw ex;
401-
}
402394
});
403395
}
404396

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
1-
CREATE TABLE command_usage
1+
CREATE TABLE analytics
22
(
3-
id INTEGER PRIMARY KEY AUTOINCREMENT,
4-
channel_id BIGINT NOT NULL,
5-
command_name TEXT NOT NULL,
6-
user_id BIGINT NOT NULL,
7-
executed_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
8-
success BOOLEAN NOT NULL DEFAULT TRUE,
9-
error_message TEXT
3+
id INTEGER PRIMARY KEY AUTOINCREMENT,
4+
event TEXT NOT NULL,
5+
happened_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
106
);
11-
12-
CREATE INDEX idx_command_usage_channel ON command_usage(channel_id);
13-
CREATE INDEX idx_command_usage_command_name ON command_usage(command_name);

0 commit comments

Comments
 (0)