Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,32 @@ final class DiscordLogForwarder {
private static final Logger logger = LoggerFactory.getLogger(DiscordLogForwarder.class);

private static final int MAX_PENDING_LOGS = 10_000;
private static final int MAX_BATCH_SIZE = WebhookMessage.MAX_EMBEDS;
private static final int MAX_PENDING_LOGS_WARNING_THRESHOLD = 8_000;

private static final ScheduledExecutorService SERVICE =
Executors.newSingleThreadScheduledExecutor();

private static final int MAX_BATCH_SIZE = WebhookMessage.MAX_EMBEDS;
/**
* The max total length of all descriptions contained in a batch of embeds sent to Discord.
*/
private static final int MAX_BATCH_DESCRIPTION_TOTAL = 6_000;
/**
* Has to be small enough for fitting all {@value MAX_BATCH_SIZE} embeds contained in a batch
* into the total character length of ~6000.
* Has to be small enough for fitting most {@value MAX_BATCH_SIZE} embeds contained in a batch
* into the total character length of {@value MAX_BATCH_DESCRIPTION_TOTAL}.
* <p>
* This limit is preferred to {@link #MAX_EMBED_DESCRIPTION_SHORT}, as usually only a few
* messages are too large and need to be limited.
*/
private static final int MAX_EMBED_DESCRIPTION = 1_000;
/**
* Small enough for fitting all {@value MAX_BATCH_SIZE} embeds contained in a batch into the
* total character length of {@value MAX_BATCH_DESCRIPTION_TOTAL}.
* <p>
* Used when {@link #MAX_EMBED_DESCRIPTION} lead to exceeding the limit.
*/
private static final int MAX_EMBED_DESCRIPTION_SHORT = 400;

private static final Map<Level, Integer> LEVEL_TO_AMBIENT_COLOR =
Map.of(Level.TRACE, 0x00B362, Level.DEBUG, 0x00A5CE, Level.INFO, 0xAC59FF, Level.WARN,
0xDFDF00, Level.ERROR, 0xBF2200, Level.FATAL, 0xFF8484);
Expand Down Expand Up @@ -80,6 +98,13 @@ void forwardLogEvent(LogEvent event) {
Logs are forwarded to Discord slower than they pile up. Discarding the latest log...""");
return;
}
if (pendingLogs.size() >= MAX_PENDING_LOGS_WARNING_THRESHOLD) {
logger.warn("""
Nearing the max amount of logs that can be buffered. \
Logs are forwarded to Discord slower than they pile up. \
Look into the issue, logs will soon be discarded otherwise...
""");
}

LogMessage log = LogMessage.ofEvent(event);

Expand All @@ -95,6 +120,7 @@ private void processPendingLogs() {
if (logsToProcess.isEmpty()) {
return;
}
logsToProcess = validateBatch(logsToProcess);

List<WebhookEmbed> logBatch = logsToProcess.stream().map(LogMessage::embed).toList();

Expand All @@ -112,6 +138,21 @@ private List<LogMessage> pollLogsToProcessBatch() {
}
}

private List<LogMessage> validateBatch(List<LogMessage> logBatch) {
int totalDescriptionLength = logBatch.stream()
.map(LogMessage::embed)
.map(WebhookEmbed::getDescription)
.mapToInt(description -> description == null ? 0 : description.length())
.sum();

if (totalDescriptionLength >= MAX_BATCH_DESCRIPTION_TOTAL) {
// Shorten logs further to go below limit
return logBatch.stream().map(LogMessage::shortened).toList();
}

return new ArrayList<>(logBatch);
}

private record LogMessage(WebhookEmbed embed,
Instant timestamp) implements Comparable<LogMessage> {

Expand Down Expand Up @@ -146,6 +187,15 @@ private static String abbreviate(String text, int maxLength) {
return text.substring(0, maxLength - 3) + "...";
}

private LogMessage shortened() {
String shortDescription =
abbreviate(embed.getDescription(), MAX_EMBED_DESCRIPTION_SHORT);
WebhookEmbed shortEmbed =
new WebhookEmbedBuilder(embed).setDescription(shortDescription).build();

return new LogMessage(shortEmbed, timestamp);
}

@Override
public int compareTo(@NotNull LogMessage o) {
return timestamp.compareTo(o.timestamp);
Expand Down