Skip to content

Commit

Permalink
Add support for Sentry monitoring
Browse files Browse the repository at this point in the history
  • Loading branch information
pvannierop committed Dec 7, 2024
1 parent 3a93a69 commit 3d21e22
Show file tree
Hide file tree
Showing 15 changed files with 256 additions and 159 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,3 +216,22 @@ Configuring radar-upload-frontend requires configuring the right environment var
</tbody></table>



## Sentry monitoring

To enable Sentry monitoring for the kafka-connect-upload-source and radar-upload-backend services:

1. Set a `SENTRY_DSN` environment variable that points to the desired Sentry DSN.
2. (Optional) Set the `SENTRY_LOG_LEVEL` environment variable to control the minimum log level of
events sent to Sentry.
The default log level for Sentry is `WARN`. Possible values are `TRACE`, `DEBUG`, `INFO`, `WARN`,
and `ERROR`.

For further configuration of Sentry via environmental variables see [here](https://docs.sentry.io/platforms/java/configuration/#configuration-via-the-runtime-environment). For instance:

```
SENTRY_LOG_LEVEL: 'ERROR'
SENTRY_DSN: 'https://000000000000.ingest.de.sentry.io/000000000000'
SENTRY_ATTACHSTACKTRACE: true
SENTRY_STACKTRACE_APP_PACKAGES: io.confluent.connect,org.radarbase.connect.rest
```
27 changes: 0 additions & 27 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,42 +1,15 @@
import org.radarbase.gradle.plugin.radarKotlin

plugins {
id("org.radarbase.radar-root-project") version Versions.radarCommons
id("org.radarbase.radar-dependency-management") version Versions.radarCommons
id("org.radarbase.radar-kotlin") version Versions.radarCommons apply false

id("org.jetbrains.kotlin.plugin.noarg") version Versions.kotlin apply false
id("org.jetbrains.kotlin.plugin.jpa") version Versions.kotlin apply false
id("org.jetbrains.kotlin.plugin.allopen") version Versions.kotlin apply false
id("com.avast.gradle.docker-compose") version Versions.dockerCompose apply false
}

allprojects {
group = "org.radarbase"
version = "0.5.14"
}


radarRootProject {
projectVersion.set(Versions.project)
gradleVersion.set(Versions.wrapper)
}


subprojects {
apply(plugin = "org.radarbase.radar-kotlin")

radarKotlin {
javaVersion.set(Versions.java)
kotlinVersion.set(Versions.kotlin)
slf4jVersion.set(Versions.slf4j)
log4j2Version.set(Versions.log4j2)
junitVersion.set(Versions.junit)
}
}

project(":kafka-connect-upload-source") {
radarKotlin {
javaVersion.set(17)
}
}
2 changes: 1 addition & 1 deletion buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
plugins {
kotlin("jvm") version "1.9.10"
id("org.radarbase.radar-kotlin") version "1.1.3"
}

repositories {
Expand Down
4 changes: 2 additions & 2 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ object Versions {
const val wrapper = "8.4"
const val dockerCompose = "0.17.5"

const val radarCommons = "1.1.1"
const val radarCommons = "1.1.3"
const val confluent = "7.5.1"
const val kafka = "$confluent-ce"

Expand All @@ -16,7 +16,7 @@ object Versions {
const val ktor = "2.3.5"

const val log4j2 = "2.21.1"
const val slf4j = "2.0.9"
const val sentryLog4j = "1.7.30"

const val okhttp = "4.12.0"

Expand Down
48 changes: 27 additions & 21 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ services:
build:
context: .
dockerfile: kafka-connect-upload-source/Dockerfile
image: radarbase/radar-connect-upload-source:0.5.1
image: radarbase/radar-connect-upload-source:latest
restart: on-failure
volumes:
- ./etc/source-upload.properties:/etc/kafka-connect/source-upload.properties
Expand All @@ -194,7 +194,7 @@ services:
- kafka-2
- kafka-3
- schema-registry-1
- radar-upload-backend
#- radar-upload-backend
environment:
CONNECT_BOOTSTRAP_SERVERS: PLAINTEXT://kafka-1:9092,PLAINTEXT://kafka-2:9092,PLAINTEXT://kafka-3:9092
CONNECT_REST_PORT: 8083
Expand All @@ -216,31 +216,37 @@ services:
KAFKA_HEAP_OPTS: "-Xms256m -Xmx768m"
KAFKA_BROKERS: 3
CONNECT_LOG4J_LOGGERS: "org.reflections=ERROR"
# SENTRY_LOG_LEVEL: 'ERROR'
# SENTRY_DSN: 'https://000000000000.ingest.de.sentry.io/000000000000'
# SENTRY_ATTACHSTACKTRACE: true
# SENTRY_STACKTRACE_APP_PACKAGES: io.confluent.connect,org.radarbase.connect.rest

radar-upload-backend:
build:
context: .
dockerfile: radar-upload-backend/Dockerfile
image: radarbase/radar-upload-connect-backend:0.5.1
ports:
- "8085:8085"
depends_on:
- managementportal-app
- radarbase-postgresql
volumes:
- ./etc/upload.yml:/etc/upload-backend/upload.yml
- ./etc/logback.xml:/etc/upload-backend/logback.xml
environment:
JAVA_OPTS: "-Dlogback.configurationFile=/etc/upload-backend/logback.xml"
command: ["radar-upload-backend", "/etc/upload-backend/upload.yml"]
# radar-upload-backend:
# build:
# context: .
# dockerfile: radar-upload-backend/Dockerfile
# image: radarbase/radar-upload-connect-backend:latest
# ports:
# - "8085:8085"
# depends_on:
# - managementportal-app
# - radarbase-postgresql
# volumes:
# - ./etc/upload.yml:/etc/upload-backend/upload.yml
# command: ["radar-upload-backend", "/etc/upload-backend/upload.yml"]
# environment:
# SENTRY_LOG_LEVEL: 'ERROR'
# SENTRY_DSN: 'https://000000000000.ingest.de.sentry.io/000000000000'
# SENTRY_ATTACHSTACKTRACE: true
# SENTRY_STACKTRACE_APP_PACKAGES: io.confluent.connect,org.radarbase.upload

radar-upload-frontend:
build:
context: radar-upload-frontend
dockerfile: Dockerfile
image: radarbase/radar-upload-connect-frontend:0.5.1
image: radarbase/radar-upload-connect-frontend:latest
depends_on:
- radar-upload-backend
#- radar-upload-backend
- managementportal-app
environment:
VUE_APP_BASE_URL: "/upload"
Expand All @@ -260,7 +266,7 @@ services:
ports:
- "8080:8080"
depends_on:
- radar-upload-backend
#- radar-upload-backend
- managementportal-app
- radar-upload-frontend
volumes:
Expand Down
17 changes: 0 additions & 17 deletions etc/logback.xml

This file was deleted.

11 changes: 7 additions & 4 deletions integration-test/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import org.jetbrains.kotlin.cli.common.toBooleanLenient
import java.time.Duration

plugins {
kotlin("jvm")
id("com.avast.gradle.docker-compose")
id("com.avast.gradle.docker-compose") version Versions.dockerCompose
id("org.radarbase.radar-kotlin")
}

sourceSets {
Expand All @@ -16,8 +16,6 @@ sourceSets {
}

dependencies {
implementation(kotlin("stdlib-jdk8"))

testImplementation("io.confluent:kafka-connect-avro-converter:${Versions.confluent}")
testImplementation(platform("com.fasterxml.jackson:jackson-bom:${Versions.jackson}"))
testImplementation("com.squareup.okhttp3:okhttp:${Versions.okhttp}")
Expand Down Expand Up @@ -50,3 +48,8 @@ dockerCompose {
environment.put("SERVICES_HOST", "localhost")
isRequiredBy(tasks["integrationTest"])
}

radarKotlin {
// TODO remove after using new release of radar-kotlin plugin
javaVersion.set(Versions.java)
}
9 changes: 7 additions & 2 deletions kafka-connect-upload-source/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ RUN gradle jar

FROM confluentinc/cp-kafka-connect-base:7.7.1

MAINTAINER @nivemaham @blootsvoets
MAINTAINER @pvannierop

LABEL description="Kafka Data Upload Source connector"

Expand All @@ -28,11 +28,16 @@ COPY --from=builder /code/kafka-connect-upload-source/build/third-party/*.jar ${
COPY --from=builder /code/kafka-connect-upload-source/build/libs/kafka-connect-upload-source-*.jar ${CONNECT_PLUGIN_PATH}/kafka-connect-upload-source/

# Load topics validator
COPY ./kafka-connect-upload-source/src/main/docker/kafka-wait /usr/bin/kafka-wait
COPY ./kafka-connect-upload-source/src/main/docker/ensure /etc/confluent/docker/ensure

# Load modified launcher
COPY ./kafka-connect-upload-source/src/main/docker/launch /etc/confluent/docker/launch

# Overwrite the log4j configuration to include Sentry monitoring.
COPY ./kafka-connect-upload-source/src/main/docker/log4j.properties.template /etc/confluent/docker/log4j.properties.template
# Copy Sentry monitoring jars.
COPY --from=builder /code/kafka-connect-upload-source/build/third-party/sentry-* /etc/kafka-connect/jars

USER "root"
# create parent directory for storing offsets in standalone mode
RUN mkdir -p /var/lib/kafka-connect-upload-source/logs \
Expand Down
16 changes: 13 additions & 3 deletions kafka-connect-upload-source/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
plugins {
java
kotlin("jvm")
id("org.radarbase.radar-kotlin")
}

sourceSets {
Expand Down Expand Up @@ -32,14 +31,21 @@ dependencies {

// Included in connector runtime
compileOnly("org.apache.kafka:connect-api:${Versions.kafka}")
implementation(kotlin("stdlib-jdk8"))
implementation(kotlin("reflect"))

testImplementation("io.confluent:kafka-connect-avro-converter:${Versions.confluent}")

testImplementation("org.hamcrest:hamcrest:${Versions.hamcrest}")
testImplementation("org.apache.kafka:connect-api:${Versions.kafka}")
testImplementation("org.mockito.kotlin:mockito-kotlin:${Versions.mockitoKotlin}")

// Application monitoring
// This dependency is not used by the upload connector, but copied into the Docker image (Dockerfile)
compileOnly("io.sentry:sentry-log4j:${Versions.sentryLog4j}") {
// Exclude log4j with security vulnerability (safe version is provided by docker image).
exclude(group = "log4j", module = "log4j")
}

}

task<Test>("integrationTest") {
Expand All @@ -49,3 +55,7 @@ task<Test>("integrationTest") {
classpath = sourceSets["integrationTest"].runtimeClasspath
mustRunAfter(tasks["test"])
}

radarKotlin {
javaVersion.set(Versions.java)
}
88 changes: 88 additions & 0 deletions kafka-connect-upload-source/src/main/docker/ensure
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/bin/bash

if [ "$WAIT_FOR_KAFKA" != "1" ]; then
echo "Starting without checking for Kafka availability"
exit 0
fi

max_timeout=32

IS_TEMP=0

echo "===> Wait for infrastructure ..."

if [ -z "$COMMAND_CONFIG_FILE_PATH" ]; then
COMMAND_CONFIG_FILE_PATH="$(mktemp)"
IS_TEMP=1
fi

if [ ! -f "$COMMAND_CONFIG_FILE_PATH" ] || [ $IS_TEMP = 1 ]; then
while IFS='=' read -r -d '' n v; do
if [[ "$n" == "CONNECT_"* ]]; then
name="${n/CONNECT_/""}" # remove first "CONNECT_"
name="${name,,}" # lower case
name="${name//_/"."}" # replace all '_' with '.'
echo "$name=$v" >> ${COMMAND_CONFIG_FILE_PATH}
fi
done < <(env -0)
fi

# Check if variables exist
if [ -z "$CONNECT_BOOTSTRAP_SERVERS" ]; then
echo "CONNECT_BOOTSTRAP_SERVERS is not defined"
else
KAFKA_BROKERS=${KAFKA_BROKERS:-3}

tries=10
timeout=1
while true; do
KAFKA_CHECK=$(kafka-broker-api-versions --bootstrap-server "$CONNECT_BOOTSTRAP_SERVERS" --command-config "${COMMAND_CONFIG_FILE_PATH}" | grep "(id: " | wc -l)

if [ "$KAFKA_CHECK" -ge "$KAFKA_BROKERS" ]; then
echo "Kafka brokers available."
break
fi

tries=$((tries - 1))
if [ ${tries} -eq 0 ]; then
echo "FAILED: KAFKA BROKERs NOT READY."
exit 5
fi
echo "Expected $KAFKA_BROKERS brokers but found only $KAFKA_CHECK. Waiting $timeout second before retrying ..."
sleep ${timeout}
if [ ${timeout} -lt ${max_timeout} ]; then
timeout=$((timeout * 2))
fi
done

echo "Kafka is available."
fi

if [ -z "$CONNECT_KEY_CONVERTER_SCHEMA_REGISTRY_URL" ]; then
echo "CONNECT_KEY_CONVERTER_SCHEMA_REGISTRY_URL is not defined"
else
tries=10
timeout=1
while true; do
if wget --spider -q "${CONNECT_KEY_CONVERTER_SCHEMA_REGISTRY_URL}/subjects" 2>/dev/null; then
echo "Schema registry available."
break
fi
tries=$((tries - 1))
if [ $tries -eq 0 ]; then
echo "FAILED TO REACH SCHEMA REGISTRY."
exit 6
fi
echo "Failed to reach schema registry. Retrying in ${timeout} seconds."
sleep ${timeout}
if [ ${timeout} -lt ${max_timeout} ]; then
timeout=$((timeout * 2))
fi
done

echo "Schema registry is available."
fi

if [ $IS_TEMP = 1 ]; then
/bin/rm -f "$COMMAND_CONFIG_FILE_PATH"
fi
Loading

0 comments on commit 3d21e22

Please sign in to comment.