Skip to content
Draft
Show file tree
Hide file tree
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
9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,17 @@ RUN --mount=type=cache,target=/root/.gradle ./gradlew check installDist --no-dae

FROM alpine:3.24.2

# bump: OpenTelemetry /opentelemetry-java-instrumentation\/releases\/download\/v([\d.]+)/ git:https://github.com/open-telemetry/opentelemetry-java-instrumentation.git|/\d+\./|*
ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v2.31.1/opentelemetry-javaagent.jar \
/app/opentelemetry-agent.jar

COPY --from=builder /usr/bin/ff* /usr/bin/
COPY --from=builder /app/build/install/Stickerify/ .

ENV OTEL_SDK_DISABLED=true
ENV OTEL_METRICS_EXPORTER=none
ENV OTEL_LOGS_EXPORTER=none
ENV OTEL_JAVAAGENT_LOGGING=none
ENV JAVA_TOOL_OPTIONS=-javaagent:/app/opentelemetry-agent.jar
ENV CONCURRENT_PROCESSES=5
CMD ["./bin/Stickerify"]
3 changes: 2 additions & 1 deletion Railway.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ ARG LOG_LEVEL
ARG CONCURRENT_PROCESSES
ENV STICKERIFY_TOKEN=$STICKERIFY_TOKEN \
LOG_LEVEL=$LOG_LEVEL \
CONCURRENT_PROCESSES=$CONCURRENT_PROCESSES
CONCURRENT_PROCESSES=$CONCURRENT_PROCESSES \
OTEL_SDK_DISABLED=false
10 changes: 6 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ dependencies {
implementation(libs.jspecify)
implementation(libs.logback.classic)
implementation(libs.logstash.logback.encoder)
implementation(libs.opentelemetry.instrumentation.annotations)
implementation(libs.telegram.bot.api)
implementation(libs.tika)

Expand Down Expand Up @@ -52,10 +53,11 @@ val jlink = tasks.register<JlinkTask>("jlink") {

options = listOf("--strip-debug", "--no-header-files", "--no-man-pages", "--ignore-modified-runtime")
modules = listOf(
"java.instrument", // for junit
"java.naming", // for logback
"java.sql", // for tika
"jdk.unsupported" // for gson
"java.instrument", // for JUnit
"java.naming", // for Logback
"java.management", // for OpenTelemetry
"java.sql", // for Tika
"jdk.unsupported" // for Gson
)
includeModulePath = false
javaCompiler = javaToolchains.compilerFor(java.toolchain)
Expand Down
1 change: 1 addition & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ junit-platform = { module = "org.junit.platform:junit-platform-launcher", versio
logback-classic = "ch.qos.logback:logback-classic:1.6.4"
logstash-logback-encoder = "net.logstash.logback:logstash-logback-encoder:9.0"
mockwebserver = "com.squareup.okhttp3:mockwebserver3-junit5:5.5.0"
opentelemetry-instrumentation-annotations = "io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations:2.31.1"
telegram-bot-api = "com.github.pengrad:java-telegram-bot-api:10.1.0"
tika = "org.apache.tika:tika-core:4.0.0"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.pengrad.telegrambot.request.richmessages.SendRichMessage;
import com.pengrad.telegrambot.request.richmessages.SendRichMessageDraft;
import com.pengrad.telegrambot.response.BaseResponse;
import io.opentelemetry.instrumentation.annotations.WithSpan;
import org.jspecify.annotations.Nullable;
import org.slf4j.event.Level;

Expand Down Expand Up @@ -106,6 +107,7 @@ public void close() {
bot.shutdown();
}

@WithSpan("bot.answer")
private void answer(TelegramRequest request) {
LOGGER.at(Level.INFO).log("Received request");

Expand All @@ -118,6 +120,7 @@ private void answer(TelegramRequest request) {
}
}

@WithSpan("bot.answer_file")
private void answerFile(TelegramRequest request, TelegramFile file) {
if (file == TelegramFile.NOT_SUPPORTED) {
answerText(ERROR, request);
Expand Down Expand Up @@ -163,6 +166,7 @@ private void answerFile(TelegramRequest request, String fileId) {
}
}

@WithSpan("bot.download_file")
private File retrieveFile(String fileId) throws TelegramApiException, FileOperationException {
var file = execute(new GetFile(fileId)).file();

Expand Down Expand Up @@ -206,6 +210,7 @@ private boolean processTelegramFailure(TelegramApiException e, boolean logUnmatc
return replyToUser;
}

@WithSpan("bot.answer_text")
private void answerText(TelegramRequest request) {
var message = request.message();
if (message.text() == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.annotations.SerializedName;
import io.opentelemetry.instrumentation.annotations.SpanAttribute;
import io.opentelemetry.instrumentation.annotations.WithSpan;
import org.apache.tika.Tika;
import org.jspecify.annotations.Nullable;
import org.slf4j.event.Level;
Expand Down Expand Up @@ -96,7 +98,8 @@ private static String detectMimeType(File file) throws MediaException {
* @throws InterruptedException if the current thread is interrupted while converting a video file
* @see MediaHelper#convert(File)
*/
private static @Nullable File performConversion(File inputFile, String mimeType) throws MediaException, InterruptedException {
@WithSpan("media.convert")
private static @Nullable File performConversion(File inputFile, @SpanAttribute("mime_type") String mimeType) throws MediaException, InterruptedException {
LOGGER.at(Level.DEBUG).log("MIME type successfully detected");

try {
Expand Down Expand Up @@ -179,6 +182,7 @@ private static boolean isAnimatedWebp(File file, String mimeType) {
* @throws MediaException if an error occurred retrieving video information
* @throws InterruptedException if the current thread is interrupted while retrieving file info
*/
@WithSpan("media.check_video_compliance")
private static boolean isVideoCompliant(File file) throws MediaException, InterruptedException {
var mediaInfo = retrieveMultimediaInfo(file);

Expand Down Expand Up @@ -278,6 +282,7 @@ record FormatInfo(@SerializedName("format_name") String format, @Nullable Float
* @return {@code true} if the file is compliant
* @throws FileOperationException if an error occurred retrieving the size of the file
*/
@WithSpan("media.check_animation_compliance")
private static boolean isAnimatedStickerCompliant(File file, String mimeType) throws FileOperationException {
if ("application/gzip".equals(mimeType)) {
var uncompressedContent = "";
Expand Down Expand Up @@ -358,6 +363,7 @@ private static boolean isSupportedImage(String mimeType) {
* @throws MediaException if an error occurred retrieving image information
* @throws InterruptedException if the current thread is interrupted while retrieving file info
*/
@WithSpan("media.check_image_compliance")
private static boolean isImageCompliant(File image, String mimeType) throws MediaException, InterruptedException {
var mediaInfo = retrieveMultimediaInfo(image);

Expand All @@ -384,6 +390,7 @@ && isSizeCompliant(imageInfo.width(), imageInfo.height())
* @throws MediaException if an error occurred processing passed-in image
* @throws InterruptedException if the current thread is interrupted while converting the file
*/
@WithSpan("media.convert_image")
private static File convertToWebp(File file) throws MediaException, InterruptedException {
var webpImage = createTempFile("webp");
var command = List.of(
Expand Down Expand Up @@ -465,6 +472,7 @@ private static void deleteFile(File file) throws FileOperationException {
* @throws MediaException if file conversion is not successful
* @throws InterruptedException if the current thread is interrupted while converting the video file
*/
@WithSpan("media.convert_video")
private static File convertToWebm(File file) throws MediaException, InterruptedException {
var webmVideo = createTempFile("webm");
var logPrefix = webmVideo.getAbsolutePath() + "-passlog";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import com.github.stickerifier.stickerify.exception.ProcessException;
import com.github.stickerifier.stickerify.logger.StructuredLogger;
import io.opentelemetry.instrumentation.annotations.SpanAttribute;
import io.opentelemetry.instrumentation.annotations.WithSpan;
import org.slf4j.event.Level;

import java.io.IOException;
Expand Down Expand Up @@ -34,7 +36,8 @@ public final class ProcessHelper {
* </ul>
* @throws InterruptedException if the current thread is interrupted while waiting for the command to finish
*/
public static String executeCommand(final List<String> command) throws ProcessException, InterruptedException {
@WithSpan("process.execute")
public static String executeCommand(@SpanAttribute("command") final List<String> command) throws ProcessException, InterruptedException {
SEMAPHORE.acquire();

try (var process = new ProcessBuilder(command).start()) {
Expand Down
Loading