diff --git a/.github/workflows/deploy-prod.yml b/.github/workflows/deploy-prod.yml index 663ba77..3c4ae4f 100644 --- a/.github/workflows/deploy-prod.yml +++ b/.github/workflows/deploy-prod.yml @@ -36,6 +36,15 @@ jobs: id: get_version run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT" + - name: JDK 21 설정 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'corretto' + + - name: JAR 빌드 + run: ./gradlew bootJar --no-daemon + - name: Docker Hub 로그인 run: echo "${{ secrets.DOCKER_ACCESS_TOKEN }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin diff --git a/Dockerfile b/Dockerfile index ea2cc0d..0f38e7c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,18 +1,3 @@ -# Build stage -FROM amazoncorretto:21-alpine3.19-jdk AS builder - -WORKDIR /app - -COPY gradlew . -COPY gradle gradle -COPY build.gradle . -COPY settings.gradle . -COPY src src - -RUN chmod +x ./gradlew -RUN ./gradlew bootJar --no-daemon - -# Runtime stage FROM amazoncorretto:21-alpine3.19 WORKDIR /app @@ -25,7 +10,7 @@ RUN apk add --no-cache curl tzdata && \ RUN addgroup -g 1001 appgroup && adduser -u 1001 -G appgroup -D appuser RUN mkdir -p /app/log && chown -R appuser:appgroup /app -COPY --from=builder --chown=appuser:appgroup /app/build/libs/*.jar app.jar +COPY --chown=appuser:appgroup build/libs/*.jar app.jar USER appuser diff --git a/alloy/config.alloy b/alloy/config.alloy new file mode 100644 index 0000000..db20ad8 --- /dev/null +++ b/alloy/config.alloy @@ -0,0 +1,90 @@ +prometheus.scrape "spring" { + targets = [ + { + __address__ = "recycle-study-server:8080", + app = "recycle-study-server", + }, + ] + + metrics_path = "/actuator/prometheus" + scrape_interval = "15s" + scrape_timeout = "10s" + + forward_to = [prometheus.remote_write.to_prom.receiver] +} + +prometheus.remote_write "to_prom" { + endpoint { + url = sys.env("PROMETHEUS_HOST") + "/api/v1/write" + } +} + +prometheus.scrape "node" { + targets = [ + { + __address__ = "node-exporter:9100", + app = "recycle-study-server", + }, + ] + + scrape_interval = "15s" + scrape_timeout = "10s" + + forward_to = [prometheus.remote_write.to_prom.receiver] +} + +local.file_match "local_files" { + path_targets = [ + { + __path__ = "/var/log/app/*.json", + env = "dev", + app = "recycle-study-server", + }, + ] + sync_period = "5s" +} + +loki.source.file "log_scrape" { + targets = local.file_match.local_files.targets + forward_to = [loki.process.filter_logs.receiver] + tail_from_end = true +} + +loki.process "filter_logs" { + stage.drop { + source = "" + expression = ".*Connection closed by authenticating user root" + drop_counter_reason = "noisy" + } + forward_to = [loki.write.grafana_loki.receiver] +} + +loki.write "grafana_loki" { + endpoint { + url = sys.env("LOKI_HOST") + "/loki/api/v1/push" + } +} + +otelcol.receiver.otlp "default" { + grpc { endpoint = "0.0.0.0:4317" } + + output { + traces = [otelcol.processor.memory_limiter.default.input] + } +} + +otelcol.processor.memory_limiter "default" { + check_interval = "1s" + limit_percentage = 90 + spike_limit_percentage = 95 + + output { + traces = [otelcol.exporter.otlphttp.default.input] + } +} + +otelcol.exporter.otlphttp "default" { + client { + endpoint = sys.env("TEMPO_HOST") + "/v1/traces" + } +} diff --git a/alloy/docker-compose.yml b/alloy/docker-compose.yml new file mode 100644 index 0000000..48e7720 --- /dev/null +++ b/alloy/docker-compose.yml @@ -0,0 +1,31 @@ +services: + alloy: + image: grafana/alloy:latest + container_name: alloy + restart: unless-stopped + env_file: + - ../.env + volumes: + - ./config.alloy:/etc/alloy/config.alloy + - /app/logs:/var/log/app + command: + - "run" + - "--server.http.listen-addr=0.0.0.0:12345" + - "--storage.path=/var/lib/alloy" + - "--stability.level=experimental" + - "/etc/alloy/config.alloy" + ports: + - "12345:12345" # Alloy UI + - "4317:4317" # OTLP gRPC + networks: + - observability + + node-exporter: + image: quay.io/prometheus/node-exporter:latest + container_name: node-exporter + restart: unless-stopped + networks: + - observability + +networks: + observability: diff --git a/build.gradle b/build.gradle index 6f8bce6..6541378 100644 --- a/build.gradle +++ b/build.gradle @@ -41,6 +41,8 @@ dependencies { // monitoring implementation 'org.springframework.boot:spring-boot-starter-actuator' runtimeOnly 'io.micrometer:micrometer-registry-prometheus' + implementation 'io.micrometer:micrometer-tracing-bridge-otel' + implementation 'io.opentelemetry:opentelemetry-exporter-otlp' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'io.rest-assured:rest-assured' diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 189e82a..5f3472a 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -41,5 +41,14 @@ management: exposure: include: prometheus, health + tracing: + sampling: + probability: 1.0 + + otlp: + tracing: + endpoint: ${ALLOY_URL} + transport: grpc + auth: base-url: ${BASE_URL}