Skip to content

Commit 7d5fc5c

Browse files
committed
Extract logging logic to record
1 parent b467d64 commit 7d5fc5c

File tree

4 files changed

+62
-36
lines changed

4 files changed

+62
-36
lines changed

src/main/java/com/github/stickerifier/stickerify/bot/Stickerify.java

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.github.stickerifier.stickerify.bot;
22

3+
import static com.github.stickerifier.stickerify.logger.StructuredLogger.USER_ID;
34
import static com.github.stickerifier.stickerify.telegram.Answer.CORRUPTED;
45
import static com.github.stickerifier.stickerify.telegram.Answer.ERROR;
56
import static com.github.stickerifier.stickerify.telegram.Answer.FILE_ALREADY_VALID;
@@ -14,6 +15,7 @@
1415
import com.github.stickerifier.stickerify.exception.FileOperationException;
1516
import com.github.stickerifier.stickerify.exception.MediaException;
1617
import com.github.stickerifier.stickerify.exception.TelegramApiException;
18+
import com.github.stickerifier.stickerify.logger.StructuredLogger;
1719
import com.github.stickerifier.stickerify.media.MediaHelper;
1820
import com.github.stickerifier.stickerify.telegram.Answer;
1921
import com.github.stickerifier.stickerify.telegram.model.TelegramFile;
@@ -31,10 +33,7 @@
3133
import com.pengrad.telegrambot.request.SendDocument;
3234
import com.pengrad.telegrambot.request.SendMessage;
3335
import com.pengrad.telegrambot.response.BaseResponse;
34-
import org.slf4j.Logger;
35-
import org.slf4j.LoggerFactory;
3636
import org.slf4j.event.Level;
37-
import org.slf4j.spi.LoggingEventBuilder;
3837

3938
import java.io.File;
4039
import java.io.IOException;
@@ -53,10 +52,9 @@
5352
*/
5453
public record Stickerify(TelegramBot bot, Executor executor) implements UpdatesListener, ExceptionHandler, AutoCloseable {
5554

56-
private static final Logger LOGGER = LoggerFactory.getLogger(Stickerify.class);
55+
private static final StructuredLogger LOGGER = new StructuredLogger(Stickerify.class);
5756
private static final String BOT_TOKEN = System.getenv("STICKERIFY_TOKEN");
5857
private static final ThreadFactory VIRTUAL_THREAD_FACTORY = Thread.ofVirtual().name("Virtual-", 0).factory();
59-
public final static ScopedValue<Long> USER_ID = ScopedValue.newInstance();
6058

6159
/**
6260
* Instantiate the bot processing requests with virtual threads.
@@ -90,7 +88,7 @@ public int process(List<Update> updates) {
9088

9189
@Override
9290
public void onException(TelegramException e) {
93-
logger(Level.ERROR).addKeyValue("exception_message", e.getMessage()).log("There was an unexpected failure");
91+
LOGGER.at(Level.ERROR).addKeyValue("exception_message", e.getMessage()).log("There was an unexpected failure");
9492
}
9593

9694
@Override
@@ -105,7 +103,7 @@ public void close() {
105103
}
106104

107105
private void answer(TelegramRequest request) {
108-
logger(Level.INFO).log("Received request");
106+
LOGGER.at(Level.INFO).log("Received request");
109107

110108
var file = request.getFile();
111109

@@ -116,17 +114,13 @@ private void answer(TelegramRequest request) {
116114
}
117115
}
118116

119-
private static LoggingEventBuilder logger(Level level) {
120-
return LOGGER.atLevel(level).addKeyValue("user_id", USER_ID.get());
121-
}
122-
123117
private void answerFile(TelegramRequest request, TelegramFile file) {
124118
if (file == TelegramFile.NOT_SUPPORTED) {
125119
answerText(ERROR, request);
126120
} else if (file.canBeDownloaded()) {
127121
answerFile(request, file.id());
128122
} else {
129-
logger(Level.INFO).log("Passed-in file is too large");
123+
LOGGER.at(Level.INFO).log("Passed-in file is too large");
130124

131125
answerText(FILE_TOO_LARGE, request);
132126
}
@@ -183,21 +177,21 @@ private void processFailure(TelegramRequest request, BaseException e, String fil
183177
}
184178

185179
if (e instanceof CorruptedFileException) {
186-
logger(Level.INFO).log("Unable to reply to the request: the file is corrupted");
180+
LOGGER.at(Level.INFO).log("Unable to reply to the request: the file is corrupted");
187181
answerText(CORRUPTED, request);
188182
} else {
189-
logger(Level.WARN).setCause(e).addKeyValue("file_id", fileId).log("Unable to process file");
183+
LOGGER.at(Level.WARN).setCause(e).addKeyValue("file_id", fileId).log("Unable to process file");
190184
answerText(ERROR, request);
191185
}
192186
}
193187

194188
private void processTelegramFailure(TelegramApiException e, boolean logUnmatchedFailure) {
195189
switch (e.getDescription()) {
196-
case "Bad Request: message to be replied not found" -> logger(Level.INFO).log("Unable to reply to the request: the message sent has been deleted");
197-
case "Forbidden: bot was blocked by the user" -> logger(Level.INFO).log("Unable to reply to the request: the user blocked the bot");
190+
case "Bad Request: message to be replied not found" -> LOGGER.at(Level.INFO).log("Unable to reply to the request: the message sent has been deleted");
191+
case "Forbidden: bot was blocked by the user" -> LOGGER.at(Level.INFO).log("Unable to reply to the request: the user blocked the bot");
198192
default -> {
199193
if (logUnmatchedFailure) {
200-
logger(Level.ERROR).setCause(e).log("Unable to reply to the request");
194+
LOGGER.at(Level.ERROR).setCause(e).log("Unable to reply to the request");
201195
}
202196
}
203197
}
@@ -206,7 +200,7 @@ private void processTelegramFailure(TelegramApiException e, boolean logUnmatched
206200
private void answerText(TelegramRequest request) {
207201
var message = request.message();
208202
if (message.text() == null) {
209-
logger(Level.INFO).log("An unhandled message type has been received");
203+
LOGGER.at(Level.INFO).log("An unhandled message type has been received");
210204
}
211205

212206
answerText(request.getAnswerMessage(), request);
@@ -241,10 +235,10 @@ private static void deleteTempFiles(Set<Path> pathsToDelete) {
241235
for (var path : pathsToDelete) {
242236
try {
243237
if (!Files.deleteIfExists(path)) {
244-
logger(Level.INFO).addKeyValue("file_path", path).log("Unable to delete temp file");
238+
LOGGER.at(Level.INFO).addKeyValue("file_path", path).log("Unable to delete temp file");
245239
}
246240
} catch (IOException e) {
247-
logger(Level.ERROR).setCause(e).addKeyValue("file_path", path).log("An error occurred trying to delete temp file");
241+
LOGGER.at(Level.ERROR).setCause(e).addKeyValue("file_path", path).log("An error occurred trying to delete temp file");
248242
}
249243
}
250244
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.github.stickerifier.stickerify.logger;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
import org.slf4j.event.Level;
6+
import org.slf4j.spi.LoggingEventBuilder;
7+
8+
public record StructuredLogger(Logger logger) {
9+
public final static ScopedValue<Long> USER_ID = ScopedValue.newInstance();
10+
public final static ScopedValue<String> MIME_TYPE = ScopedValue.newInstance();
11+
12+
public StructuredLogger(Class<?> clazz) {
13+
this(LoggerFactory.getLogger(clazz));
14+
}
15+
16+
public LoggingEventBuilder at(Level level) {
17+
var logBuilder = logger.atLevel(level);
18+
19+
if (USER_ID.isBound()) {
20+
logBuilder = logBuilder.addKeyValue("user_id", USER_ID.get());
21+
}
22+
if (MIME_TYPE.isBound()) {
23+
logBuilder = logBuilder.addKeyValue("mime_type", MIME_TYPE.get());
24+
}
25+
26+
return logBuilder;
27+
}
28+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@NullMarked
2+
package com.github.stickerifier.stickerify.logger;
3+
4+
import org.jspecify.annotations.NullMarked;

src/main/java/com/github/stickerifier/stickerify/media/MediaHelper.java

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@
1717
import com.github.stickerifier.stickerify.exception.FileOperationException;
1818
import com.github.stickerifier.stickerify.exception.MediaException;
1919
import com.github.stickerifier.stickerify.exception.ProcessException;
20+
import com.github.stickerifier.stickerify.logger.StructuredLogger;
2021
import com.github.stickerifier.stickerify.process.OsConstants;
2122
import com.github.stickerifier.stickerify.process.ProcessHelper;
2223
import com.google.gson.Gson;
2324
import com.google.gson.JsonSyntaxException;
2425
import com.google.gson.annotations.SerializedName;
2526
import org.apache.tika.Tika;
2627
import org.jspecify.annotations.Nullable;
27-
import org.slf4j.Logger;
28-
import org.slf4j.LoggerFactory;
28+
import org.slf4j.event.Level;
2929

3030
import java.io.File;
3131
import java.io.FileInputStream;
@@ -37,7 +37,7 @@
3737

3838
public final class MediaHelper {
3939

40-
private static final Logger LOGGER = LoggerFactory.getLogger(MediaHelper.class);
40+
private static final StructuredLogger LOGGER = new StructuredLogger(MediaHelper.class);
4141

4242
private static final Tika TIKA = new Tika();
4343
private static final Gson GSON = new Gson();
@@ -69,28 +69,28 @@ public final class MediaHelper {
6969
try {
7070
if (isSupportedVideo(mimeType)) {
7171
if (isVideoCompliant(inputFile)) {
72-
LOGGER.atInfo().log("The video doesn't need conversion");
72+
LOGGER.at(Level.INFO).log("The video doesn't need conversion");
7373
return null;
7474
}
7575

7676
return convertToWebm(inputFile);
7777
}
7878

7979
if (isAnimatedStickerCompliant(inputFile, mimeType)) {
80-
LOGGER.atInfo().log("The animated sticker doesn't need conversion");
80+
LOGGER.at(Level.INFO).log("The animated sticker doesn't need conversion");
8181
return null;
8282
}
8383

8484
if (isSupportedImage(inputFile, mimeType)) {
8585
if (isImageCompliant(inputFile, mimeType)) {
86-
LOGGER.atInfo().log("The image doesn't need conversion");
86+
LOGGER.at(Level.INFO).log("The image doesn't need conversion");
8787
return null;
8888
}
8989

9090
return convertToWebp(inputFile);
9191
}
9292
} catch (MediaException e) {
93-
LOGGER.atWarn().setCause(e).addKeyValue("mime_type", mimeType).log("The file with {} MIME type could not be converted", mimeType);
93+
LOGGER.at(Level.WARN).setCause(e).addKeyValue("mime_type", mimeType).log("The file with {} MIME type could not be converted", mimeType);
9494
throw e;
9595
}
9696

@@ -107,11 +107,11 @@ public final class MediaHelper {
107107
private static String detectMimeType(File file) throws MediaException {
108108
try {
109109
var mimeType = TIKA.detect(file);
110-
LOGGER.atDebug().addKeyValue("mime_type", mimeType).log("MIME type successfully detected");
110+
LOGGER.at(Level.DEBUG).addKeyValue("mime_type", mimeType).log("MIME type successfully detected");
111111

112112
return mimeType;
113113
} catch (IOException e) {
114-
LOGGER.atError().addKeyValue("file_name", file.getName()).log("Unable to retrieve MIME type");
114+
LOGGER.at(Level.ERROR).addKeyValue("file_name", file.getName()).log("Unable to retrieve MIME type");
115115
throw new MediaException(e);
116116
}
117117
}
@@ -241,7 +241,7 @@ private static boolean isAnimatedStickerCompliant(File file, String mimeType) th
241241
try (var gzipInputStream = new GZIPInputStream(new FileInputStream(file))) {
242242
uncompressedContent = new String(gzipInputStream.readAllBytes(), UTF_8);
243243
} catch (IOException _) {
244-
LOGGER.atError().addKeyValue("file_name", file.getName()).log("Unable to retrieve gzip content");
244+
LOGGER.at(Level.ERROR).addKeyValue("file_name", file.getName()).log("Unable to retrieve gzip content");
245245
}
246246

247247
try {
@@ -255,9 +255,9 @@ private static boolean isAnimatedStickerCompliant(File file, String mimeType) th
255255
}
256256
}
257257

258-
LOGGER.atWarn().addKeyValue("sticker", sticker).log("The animated sticker doesn't meet Telegram's requirements");
258+
LOGGER.at(Level.WARN).addKeyValue("sticker", sticker).log("The animated sticker doesn't meet Telegram's requirements");
259259
} catch (JsonSyntaxException _) {
260-
LOGGER.atInfo().log("The archive isn't an animated sticker");
260+
LOGGER.at(Level.INFO).log("The archive isn't an animated sticker");
261261
}
262262
}
263263

@@ -305,7 +305,7 @@ private static boolean isAnimationCompliant(@Nullable AnimationDetails animation
305305
*/
306306
private static boolean isSupportedImage(File image, String mimeType) {
307307
if ("image/webp".equals(mimeType) && isAnimatedWebp(image)) {
308-
LOGGER.atInfo().log("The image is an animated WebP");
308+
LOGGER.at(Level.INFO).log("The image is an animated WebP");
309309
return false;
310310
}
311311

@@ -331,7 +331,7 @@ private static boolean isAnimatedWebp(File file) {
331331

332332
return isExtendedFormat && hasAnimationFlag;
333333
} catch (IOException e) {
334-
LOGGER.atWarn().setCause(e).log("An error occurred checking if the file is an animated WebP");
334+
LOGGER.at(Level.WARN).setCause(e).log("An error occurred checking if the file is an animated WebP");
335335
return false;
336336
}
337337
}
@@ -436,7 +436,7 @@ private static File createTempFile(String fileExtension) throws FileOperationExc
436436
private static void deleteFile(File file) throws FileOperationException {
437437
try {
438438
if (!Files.deleteIfExists(file.toPath())) {
439-
LOGGER.atInfo().addKeyValue("file_path", file.toPath()).log("Unable to delete file");
439+
LOGGER.at(Level.INFO).addKeyValue("file_path", file.toPath()).log("Unable to delete file");
440440
}
441441
} catch (IOException e) {
442442
throw new FileOperationException("An error occurred deleting the file", e);
@@ -485,7 +485,7 @@ private static File convertToWebm(File file) throws MediaException, InterruptedE
485485
try {
486486
deleteFile(new File(logFileName));
487487
} catch (FileOperationException e) {
488-
LOGGER.atWarn().setCause(e).addKeyValue("file_name", logFileName).log("Could not delete log file");
488+
LOGGER.at(Level.WARN).setCause(e).addKeyValue("file_name", logFileName).log("Could not delete log file");
489489
}
490490
}
491491

0 commit comments

Comments
 (0)