@@ -39,14 +39,32 @@ final class DiscordLogForwarder {
3939 private static final Logger logger = LoggerFactory .getLogger (DiscordLogForwarder .class );
4040
4141 private static final int MAX_PENDING_LOGS = 10_000 ;
42- private static final int MAX_BATCH_SIZE = WebhookMessage .MAX_EMBEDS ;
42+ private static final int MAX_PENDING_LOGS_WARNING_THRESHOLD = 8_000 ;
43+
4344 private static final ScheduledExecutorService SERVICE =
4445 Executors .newSingleThreadScheduledExecutor ();
46+
47+ private static final int MAX_BATCH_SIZE = WebhookMessage .MAX_EMBEDS ;
48+ /**
49+ * The max total length of all descriptions contained in a batch of embeds sent to Discord.
50+ */
51+ private static final int MAX_BATCH_DESCRIPTION_TOTAL = 6_000 ;
4552 /**
46- * Has to be small enough for fitting all {@value MAX_BATCH_SIZE} embeds contained in a batch
47- * into the total character length of ~6000.
53+ * Has to be small enough for fitting most {@value MAX_BATCH_SIZE} embeds contained in a batch
54+ * into the total character length of {@value MAX_BATCH_DESCRIPTION_TOTAL}.
55+ * <p>
56+ * This limit is preferred to {@link #MAX_EMBED_DESCRIPTION_SHORT}, as usually only a few
57+ * messages are too large and need to be limited.
4858 */
4959 private static final int MAX_EMBED_DESCRIPTION = 1_000 ;
60+ /**
61+ * Small enough for fitting all {@value MAX_BATCH_SIZE} embeds contained in a batch into the
62+ * total character length of {@value MAX_BATCH_DESCRIPTION_TOTAL}.
63+ * <p>
64+ * Used when {@link #MAX_EMBED_DESCRIPTION} lead to exceeding the limit.
65+ */
66+ private static final int MAX_EMBED_DESCRIPTION_SHORT = 400 ;
67+
5068 private static final Map <Level , Integer > LEVEL_TO_AMBIENT_COLOR =
5169 Map .of (Level .TRACE , 0x00B362 , Level .DEBUG , 0x00A5CE , Level .INFO , 0xAC59FF , Level .WARN ,
5270 0xDFDF00 , Level .ERROR , 0xBF2200 , Level .FATAL , 0xFF8484 );
@@ -84,6 +102,13 @@ void forwardLogEvent(LogEvent event) {
84102 Logs are forwarded to Discord slower than they pile up. Discarding the latest log...""" );
85103 return ;
86104 }
105+ if (pendingLogs .size () >= MAX_PENDING_LOGS_WARNING_THRESHOLD ) {
106+ logger .warn ("""
107+ Nearing the max amount of logs that can be buffered. \
108+ Logs are forwarded to Discord slower than they pile up. \
109+ Look into the issue, logs will soon be discarded otherwise...
110+ """ );
111+ }
87112
88113 LogMessage log = LogMessage .ofEvent (event );
89114
@@ -99,6 +124,7 @@ private void processPendingLogs() {
99124 if (logsToProcess .isEmpty ()) {
100125 return ;
101126 }
127+ logsToProcess = validateBatch (logsToProcess );
102128
103129 List <WebhookEmbed > logBatch = logsToProcess .stream ().map (LogMessage ::embed ).toList ();
104130
@@ -116,6 +142,21 @@ private List<LogMessage> pollLogsToProcessBatch() {
116142 }
117143 }
118144
145+ private List <LogMessage > validateBatch (List <LogMessage > logBatch ) {
146+ int totalDescriptionLength = logBatch .stream ()
147+ .map (LogMessage ::embed )
148+ .map (WebhookEmbed ::getDescription )
149+ .mapToInt (description -> description == null ? 0 : description .length ())
150+ .sum ();
151+
152+ if (totalDescriptionLength >= MAX_BATCH_DESCRIPTION_TOTAL ) {
153+ // Shorten logs further to go below limit
154+ return logBatch .stream ().map (LogMessage ::shortened ).toList ();
155+ }
156+
157+ return new ArrayList <>(logBatch );
158+ }
159+
119160 private record LogMessage (WebhookEmbed embed ,
120161 Instant timestamp ) implements Comparable <LogMessage > {
121162
@@ -152,6 +193,15 @@ private static String describeLogEvent(LogEvent event) {
152193 return logMessage + "\n " + exceptionWriter .toString ().replace ("\t " , "> " );
153194 }
154195
196+ private LogMessage shortened () {
197+ String shortDescription =
198+ abbreviate (embed .getDescription (), MAX_EMBED_DESCRIPTION_SHORT );
199+ WebhookEmbed shortEmbed =
200+ new WebhookEmbedBuilder (embed ).setDescription (shortDescription ).build ();
201+
202+ return new LogMessage (shortEmbed , timestamp );
203+ }
204+
155205 @ Override
156206 public int compareTo (@ NotNull LogMessage o ) {
157207 return timestamp .compareTo (o .timestamp );
0 commit comments