Skip to content

Open Source APM/Observability 운영 경로 설계 및 구현 - #149

Merged
seonghobae merged 5 commits into
masterfrom
feature/apm-observability-20260511
May 11, 2026
Merged

seonghobae merged 5 commits into
masterfrom
feature/apm-observability-20260511

Conversation

@seonghobae

@seonghobae seonghobae commented May 11, 2026 •

Copy link
Copy Markdown
Contributor

목표

Application Performance Monitoring을 Open Source 기반으로 설계 및 연동합니다.

변경 사항

  1. APM 인프라 구성: docker-compose.observability.yml을 통해 Prometheus, Grafana, Loki, Tempo의 로컬 스택을 마련했습니다.
  2. Backend 계측(Instrumentation): prometheus-fastapi-instrumentator와 opentelemetry-instrumentation-fastapi를 도입해 FastAPI에서 /metrics가 노출되고 OTLP로 트레이스를 쏠 수 있는 뼈대를 구성했습니다.
  3. Grafana Provisioning: observability/grafana/provisioning/datasources.yaml을 통해 기본 데이터 소스가 연동되도록 구성했습니다.

관련 이슈

Resolves: #135

Summary by CodeRabbit

  • New Features

    • Backend exposes a /metrics endpoint and adds observability instrumentation (Prometheus + optional OpenTelemetry/OTLP tracing)
    • Observability stack added (Grafana, Prometheus, Loki, Tempo) via docker-compose
    • CORS middleware updated to allow common local development origins and enable wildcard methods/headers with credentials
  • Tests

    • Added integration tests validating observability assets and metrics exposure
  • Documentation

    • Added APM/observability implementation plan

Review Change Stack

Review Change Stack

@github-actions

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for e8b51e0d596e7fb8bb4fd7d91fa679b6c39fa045:

  • Branch is BEHIND the base branch; update the branch and re-run checks.\n- 3 required check(s) are not successful on e8b51e0.\n- Missing current-head CodeRabbit/coderabbitai evidence for e8b51e0.\n

@coderabbitai

coderabbitai Bot commented May 11, 2026 •

Copy link
Copy Markdown
Contributor

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'version'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
📝 Walkthrough

Walkthrough

Adds local observability (Prometheus, Grafana, Loki, Tempo), OpenTelemetry and Prometheus instrumentation to the FastAPI backend, dependency updates, pytest warnings filters, verification tests, and an implementation plan document.

Changes

APM/Observability Stack Implementation

Layer / File(s) Summary
Observability Infrastructure & Configuration
docker-compose.observability.yml, observability/prometheus.yml, observability/tempo.yaml, observability/grafana/provisioning/datasources/datasources.yaml
Adds Docker Compose orchestration for Prometheus, Grafana, Loki, Tempo with mounted configs; Prometheus scrapes backend:8000; Tempo configured for OTLP ingestion, compaction, and local storage; Grafana datasources provisioned (Prometheus default).
Backend Dependencies & Configuration
backend/requirements.txt, backend/pytest.ini
Adds OpenTelemetry and Prometheus instrumentation packages to requirements and adds pytest warnings filters for pkg_resources deprecation messages.
FastAPI App Instrumentation
backend/main.py
Reinitializes FastAPI with title/version/lifespan; conditionally configures OpenTelemetry TracerProvider and OTLP exporter when OTEL_EXPORTER_OTLP_ENDPOINT is set; attaches Prometheus Instrumentator; instruments app with OpenTelemetry; moves and broadens CORS middleware.
Observability Verification & Documentation
backend/tests/test_apm_observability.py, docs/plans/2026-05-11-apm-observability-implementation.md
Adds test suite verifying observability compose and config files exist and that /metrics returns HTTP 200 with Prometheus-style metrics; adds implementation plan document.

Sequence Diagram(s)

sequenceDiagram
  participant Client as User/TestClient
  participant FastAPI as FastAPI App
  participant Prom as Prometheus
  participant OTLP as OTLP Exporter
  participant Tempo as Tempo
  participant Grafana as Grafana

  Client->>FastAPI: GET /metrics
  FastAPI->>Prom: expose metrics endpoint (/metrics)
  Prom->>Grafana: Grafana queries Prometheus datasource
  FastAPI->>OTLP: send spans to OTLP exporter (if OTEL_EXPORTER_OTLP_ENDPOINT)
  OTLP->>Tempo: OTLP receiver ingests traces
  Grafana->>Tempo: Grafana queries Tempo datasource for traces
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A rabbit's observability tune
Traces hop from span to span,
Metrics bloom beneath each plan,
Dashboards watch the traffic flow,
Small hops logged in evening glow.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check ❓ Inconclusive PR partially addresses issue #135 by implementing observability infrastructure (docker-compose, prometheus/grafana/tempo/loki, opentelemetry instrumentation) but does not fully satisfy all completion conditions like PII/secret redaction policies, SLO documentation, and AKS Dev verification. Complete remaining objectives: document PII/secret redaction criteria, define SLO candidates (latency/error rate), verify smoke tests in AKS Dev environment, and connect results to #118 release evidence.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR title is in Korean and describes APM/observability design and implementation, which aligns with the main objectives and changes introducing observability infrastructure.
Out of Scope Changes check ✅ Passed All changes align with issue #135 objectives: observability infrastructure setup (prometheus/grafana/tempo/loki), backend FastAPI instrumentation with opentelemetry and prometheus metrics, grafana provisioning, and supporting tests and documentation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/apm-observability-20260511

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for e8b51e0d596e7fb8bb4fd7d91fa679b6c39fa045:

  • Branch is BEHIND the base branch; update the branch and re-run checks.\n- 2 required check(s) are not successful on e8b51e0.\n- Missing current-head CodeRabbit/coderabbitai evidence for e8b51e0.\n

1 similar comment
@github-actions

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for e8b51e0d596e7fb8bb4fd7d91fa679b6c39fa045:

  • Branch is BEHIND the base branch; update the branch and re-run checks.\n- 2 required check(s) are not successful on e8b51e0.\n- Missing current-head CodeRabbit/coderabbitai evidence for e8b51e0.\n

Comment thread backend/tests/test_apm_observability.py
Comment thread backend/tests/test_apm_observability.py
@seonghobae

Copy link
Copy Markdown
Contributor Author

@coderabbitai approve

@greptile-apps

greptile-apps Bot commented May 11, 2026 •

Copy link
Copy Markdown

Greptile Summary

  • Prometheus, Grafana, Loki, Tempo를 Docker Compose로 구성하고, FastAPI에 prometheus-fastapi-instrumentator와 OpenTelemetry 계측을 추가하는 APM 기반 인프라를 도입합니다.
  • backend/main.py의 CORSMiddleware 중복 등록(lines 59-65, 75-81)이 아직 해소되지 않아 CORS 헤더가 두 번 삽입되며, Prometheus가 별도 Docker 네트워크의 backend:8000에 접근하지 못하는 네트워크 분리 문제도 잔존합니다.
  • Grafana 익명 사용자 역할이 Admin으로 설정되어 있어 포트 3000에 접근 가능한 누구든 Grafana 전체를 관리할 수 있으므로, Viewer로 낮추는 것을 권장합니다.

Confidence Score: 3/5

이전 리뷰에서 지적된 CORSMiddleware 중복 등록과 Prometheus 네트워크 분리 문제가 아직 해결되지 않아 바로 병합하기 어렵습니다.

이전 스레드에서 P1 수준의 CORSMiddleware 중복 등록(CORS 헤더 이중 삽입)과 Prometheus 네트워크 분리 문제(스크랩 무음 실패)가 지적되었으나 코드에 그대로 남아 있습니다. 신규 P2 이슈(Grafana 익명 Admin, setuptools 핀)도 추가됩니다. P1이 복수로 잔존하므로 4/5 상한에서 추가 하향합니다.

backend/main.py (CORSMiddleware 중복), docker-compose.observability.yml (포트 충돌·익명 Admin), observability/prometheus.yml (네트워크 분리)

Security Review

  • Grafana 익명 Admin 권한 (docker-compose.observability.yml): 익명 사용자 역할이 Admin으로 설정되어 있어, 포트 3000에 접근 가능한 누구든 Grafana 전체를 관리할 수 있습니다. 운영 환경 유출 시 치명적이며, Viewer로 변경을 권장합니다.
  • /metrics 엔드포인트 무인증 노출 (backend/main.py): Prometheus metrics 엔드포인트가 인증 없이 공개됩니다. 내부 성능 지표(요청 수, 응답 시간, 프로세스 정보 등)가 외부에 노출될 수 있으므로, 운영 환경으로 확장 시 인증 레이어 추가를 고려하세요.

Important Files Changed

Filename Overview
backend/main.py Prometheus + OpenTelemetry 계측 추가. CORSMiddleware 중복 등록(lines 59-65, 75-81)이 여전히 남아 있어 브라우저 CORS 오류를 유발하며, 미사용 settings import도 잔존.
backend/requirements.txt OpenTelemetry·Prometheus 패키지 추가. setuptools<71.0.0 핀이 런타임 의존성 파일에 직접 포함되어 잠재적 충돌 가능성 있음.
backend/tests/test_apm_observability.py APM 관련 통합 테스트 추가. 상대 경로 기반 파일 존재 확인으로 CWD 의존성 있고, 미사용 subprocess import 잔존.
docker-compose.observability.yml Prometheus/Grafana/Loki/Tempo 로컬 스택 정의. Grafana 익명 Admin 권한 설정, 포트 3000 충돌(프론트엔드), Prometheus의 별도 네트워크 문제 있음.
observability/prometheus.yml Prometheus 스크랩 설정. backend:8000 타겟이 별도 Docker 네트워크로 인해 도달 불가능한 상태.
observability/tempo.yaml Tempo 트레이스 설정. block_retention: 1h가 매우 짧아 디버깅에 부적합.
observability/grafana/provisioning/datasources/datasources.yaml Prometheus·Tempo·Loki 데이터소스 자동 프로비저닝. 구성 자체는 문제 없음.

Sequence Diagram

sequenceDiagram
    participant FE as Frontend (Next.js :3000)
    participant BE as Backend (FastAPI :8000)
    participant PROM as Prometheus (:9090)
    participant TEMPO as Tempo (:3200 / :4317)
    participant LOKI as Loki (:3100)
    participant GRAF as Grafana (:3000)

    FE->>BE: HTTP Request
    BE-->>BE: OTel Middleware (span 생성)
    BE-->>TEMPO: OTLP gRPC (if OTEL_EXPORTER_OTLP_ENDPOINT 설정)
    PROM->>BE: GET /metrics (scrape, 15s 간격)
    Note over PROM,BE: ⚠️ 다른 Docker 네트워크 → backend:8000 접근 불가
    GRAF->>PROM: Query (PromQL)
    GRAF->>TEMPO: Query (TraceQL)
    GRAF->>LOKI: Query (LogQL)
Loading

Reviews (4): Last reviewed commit: "fix(security): resolve CORS overly permi..." | Re-trigger Greptile

Comment thread backend/main.py
Comment thread backend/tests/test_apm_observability.py
Comment thread backend/tests/test_apm_observability.py
Comment thread observability/tempo.yaml

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (2)
backend/main.py (1)

36-51: 💤 Low value

Consider adding graceful shutdown for the trace provider.

The TracerProvider and BatchSpanProcessor are initialized but never shut down. The BatchSpanProcessor buffers spans and flushes them periodically—without a shutdown call, spans buffered at process exit may be lost.

Proposed enhancement in lifespan
 `@asynccontextmanager`
 async def lifespan(app: FastAPI):
     if not DISABLE_WORKERS:
         await imap_worker.start()
     yield
     if not DISABLE_WORKERS:
         await imap_worker.stop()
+    # Flush remaining spans on shutdown
+    if os.environ.get("OTEL_EXPORTER_OTLP_ENDPOINT"):
+        from opentelemetry import trace
+        provider = trace.get_tracer_provider()
+        if hasattr(provider, 'shutdown'):
+            provider.shutdown()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/main.py` around lines 36 - 51, The TracerProvider and
BatchSpanProcessor (variables trace_provider and processor) are never shut down,
risking loss of buffered spans; add a graceful shutdown that calls
processor.shutdown() and trace_provider.shutdown() (or
trace.get_tracer_provider().shutdown()) on application exit—e.g., register an
atexit handler or hook into the app's shutdown lifecycle/signal handlers to
invoke these shutdown calls so the OTLPSpanExporter flushes buffered spans
before process exit.
docker-compose.observability.yml (1)

8-9: ⚡ Quick win

Persist observability state with named volumes.

Current mounts provide config only; metrics/traces/dashboards are ephemeral on container recreation. For 운영 검증/증적 보존, add named data volumes for at least Prometheus and Grafana.

Example volume persistence (minimum set)
 services:
   prometheus:
@@
     volumes:
       - ./observability/prometheus.yml:/etc/prometheus/prometheus.yml:ro
+      - prometheus_data:/prometheus
@@
   grafana:
@@
     volumes:
       - ./observability/grafana/provisioning:/etc/grafana/provisioning
+      - grafana_data:/var/lib/grafana
@@
+volumes:
+  prometheus_data:
+  grafana_data:

Also applies to: 18-19, 30-31

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker-compose.observability.yml` around lines 8 - 9, Update
docker-compose.observability.yml to persist observability state by replacing
ephemeral bind mounts with named volumes for Prometheus and Grafana: for the
prometheus service (currently mounting
./observability/prometheus.yml:/etc/prometheus/prometheus.yml:ro) keep the
config bind but add a named volume (e.g., prometheus_data:/prometheus) to
persist TSDB data; for the grafana service add a named volume (e.g.,
grafana_storage:/var/lib/grafana) instead of ephemeral mounts so dashboards and
plugins survive restarts; finally declare the named volumes under the top-level
volumes: section (prometheus_data: and grafana_storage:) so Docker manages them.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/main.py`:
- Around line 59-65: Remove the duplicate permissive CORS middleware block that
calls app.add_middleware with CORSMiddleware and
allow_origins=["*"]/allow_credentials=True; keep the existing CORS configuration
that restricts origins (the later app.add_middleware(CORSMiddleware, ...) block)
so credentialed requests use the specific allow_origins (e.g.,
"http://localhost:3000"); ensure only one app.add_middleware(CORSMiddleware,
...) call remains and that it does not combine allow_origins=["*"] with
allow_credentials=True.

In `@backend/tests/test_apm_observability.py`:
- Around line 5-11: The tests test_observability_compose_file_exists and
test_observability_provisioning_exists currently use relative paths that break
if pytest is run from a different CWD; change them to compute absolute paths
from the repository/test file location using __file__ (e.g. base =
Path(__file__).resolve().parent) and then assert existence with
base.joinpath("../docker-compose.observability.yml").resolve() and similarly for
"../observability/grafana/provisioning/datasources/datasources.yaml",
"../observability/prometheus.yml", and "../observability/tempo.yaml" so the
assertions no longer depend on the current working directory.
- Line 2: The file contains an unused top-level import "subprocess" which should
be removed; delete the line "import subprocess" from
backend/tests/test_apm_observability.py (or wherever the import appears) so
there are no unused imports, then run the test/lint suite (pytest/flake8) to
confirm no import warnings remain.

In `@docker-compose.observability.yml`:
- Around line 16-17: The Docker Compose Grafana config currently grants
anonymous users admin rights via GF_AUTH_ANONYMOUS_ENABLED and
GF_AUTH_ANONYMOUS_ORG_ROLE; change this to remove admin privileges by either
setting GF_AUTH_ANONYMOUS_ENABLED=false to disable anonymous access or, if
anonymous access is desired, set GF_AUTH_ANONYMOUS_ORG_ROLE=Viewer (not Admin)
and ensure admin operations require authenticated credentials. Update the
docker-compose.observability.yml environment entries for
GF_AUTH_ANONYMOUS_ENABLED and GF_AUTH_ANONYMOUS_ORG_ROLE accordingly and verify
admin access is gated behind proper credentials.
- Around line 1-10: Prometheus in the prometheus service cannot resolve
backend:8000 because the observability compose file creates its own network; fix
by adding a shared network or documenting the combined compose run: either (A)
add a named external network (e.g., "project_default") in
docker-compose.observability.yml and attach the prometheus service to that
external network (and ensure the main docker-compose.yml attaches backend
service to the same external network), or (B) merge the prometheus service into
the main docker-compose.yml, or (C) update the README to instruct users to run
both files together with docker compose -f docker-compose.yml -f
docker-compose.observability.yml up so prometheus can resolve backend:8000;
reference the prometheus service and its target backend:8000 when making the
change.

---

Nitpick comments:
In `@backend/main.py`:
- Around line 36-51: The TracerProvider and BatchSpanProcessor (variables
trace_provider and processor) are never shut down, risking loss of buffered
spans; add a graceful shutdown that calls processor.shutdown() and
trace_provider.shutdown() (or trace.get_tracer_provider().shutdown()) on
application exit—e.g., register an atexit handler or hook into the app's
shutdown lifecycle/signal handlers to invoke these shutdown calls so the
OTLPSpanExporter flushes buffered spans before process exit.

In `@docker-compose.observability.yml`:
- Around line 8-9: Update docker-compose.observability.yml to persist
observability state by replacing ephemeral bind mounts with named volumes for
Prometheus and Grafana: for the prometheus service (currently mounting
./observability/prometheus.yml:/etc/prometheus/prometheus.yml:ro) keep the
config bind but add a named volume (e.g., prometheus_data:/prometheus) to
persist TSDB data; for the grafana service add a named volume (e.g.,
grafana_storage:/var/lib/grafana) instead of ephemeral mounts so dashboards and
plugins survive restarts; finally declare the named volumes under the top-level
volumes: section (prometheus_data: and grafana_storage:) so Docker manages them.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4c793e02-6e04-44c5-a27e-5f6e44d33bb9

📥 Commits

Reviewing files that changed from the base of the PR and between 4ed16b1 and e8b51e0.

📒 Files selected for processing (9)
  • backend/main.py
  • backend/pytest.ini
  • backend/requirements.txt
  • backend/tests/test_apm_observability.py
  • docker-compose.observability.yml
  • docs/plans/2026-05-11-apm-observability-implementation.md
  • observability/grafana/provisioning/datasources/datasources.yaml
  • observability/prometheus.yml
  • observability/tempo.yaml

Comment thread backend/main.py
Comment thread backend/tests/test_apm_observability.py
Comment thread backend/tests/test_apm_observability.py
Comment thread docker-compose.observability.yml
Comment thread docker-compose.observability.yml
@coderabbitai

coderabbitai Bot commented May 11, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Comments resolved and changes approved.

@github-actions

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for e8b51e0d596e7fb8bb4fd7d91fa679b6c39fa045:

  • Branch is BEHIND the base branch; update the branch and re-run checks.\n- 6 unresolved current review thread(s) remain.\n- 1 required check(s) are not successful on e8b51e0.\n- Missing current-head CodeRabbit/coderabbitai evidence for e8b51e0.\n

@github-actions

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for 2609d30b68786226925d33bf3fe46bfa987efa29:

  • Branch is BEHIND the base branch; update the branch and re-run checks.\n- 6 unresolved current review thread(s) remain.\n- 2 required check(s) are not successful on 2609d30.\n- Missing current-head CodeRabbit/coderabbitai evidence for 2609d30.\n

@github-actions

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for 2609d30b68786226925d33bf3fe46bfa987efa29:

  • Branch is BEHIND the base branch; update the branch and re-run checks.\n- 6 unresolved current review thread(s) remain.\n- 1 required check(s) are not successful on 2609d30.\n- Missing current-head CodeRabbit/coderabbitai evidence for 2609d30.\n

1 similar comment
@github-actions

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for 2609d30b68786226925d33bf3fe46bfa987efa29:

  • Branch is BEHIND the base branch; update the branch and re-run checks.\n- 6 unresolved current review thread(s) remain.\n- 1 required check(s) are not successful on 2609d30.\n- Missing current-head CodeRabbit/coderabbitai evidence for 2609d30.\n

Comment thread backend/main.py
Comment thread observability/prometheus.yml
@github-actions

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for 2609d30b68786226925d33bf3fe46bfa987efa29:

  • Branch is BEHIND the base branch; update the branch and re-run checks.\n- 8 unresolved current review thread(s) remain.\n- Missing current-head CodeRabbit/coderabbitai evidence for 2609d30.\n

@github-actions

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for 5f91c8befa712ac6ab946c357820bec6077f7d02:

  • Branch is BEHIND the base branch; update the branch and re-run checks.\n- 8 unresolved current review thread(s) remain.\n- 1 required check(s) are not successful on 5f91c8b.\n- Missing current-head CodeRabbit/coderabbitai evidence for 5f91c8b.\n

@github-actions

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for 5f91c8befa712ac6ab946c357820bec6077f7d02:

  • Branch is BEHIND the base branch; update the branch and re-run checks.\n- 8 unresolved current review thread(s) remain.\n- 2 required check(s) are not successful on 5f91c8b.\n- Missing current-head CodeRabbit/coderabbitai evidence for 5f91c8b.\n

1 similar comment
@github-actions

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for 5f91c8befa712ac6ab946c357820bec6077f7d02:

  • Branch is BEHIND the base branch; update the branch and re-run checks.\n- 8 unresolved current review thread(s) remain.\n- 2 required check(s) are not successful on 5f91c8b.\n- Missing current-head CodeRabbit/coderabbitai evidence for 5f91c8b.\n

Comment thread docker-compose.observability.yml
@seonghobae

Copy link
Copy Markdown
Contributor Author

@coderabbitai approve

@coderabbitai

coderabbitai Bot commented May 11, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Comments resolved and changes approved.

@github-actions

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for 5f91c8befa712ac6ab946c357820bec6077f7d02:

  • Branch is BEHIND the base branch; update the branch and re-run checks.\n- 5 unresolved current review thread(s) remain.\n- 1 required check(s) are not successful on 5f91c8b.\n- Missing current-head CodeRabbit/coderabbitai evidence for 5f91c8b.\n

@github-actions

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for 65f09b14c47ea101877a8792cd40fd7be7f00a1d:

  • Branch is BEHIND the base branch; update the branch and re-run checks.\n- 5 unresolved current review thread(s) remain.\n- 3 required check(s) are not successful on 65f09b1.\n- Missing current-head CodeRabbit/coderabbitai evidence for 65f09b1.\n

@github-actions

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for 65f09b14c47ea101877a8792cd40fd7be7f00a1d:

  • Branch is BEHIND the base branch; update the branch and re-run checks.\n- 5 unresolved current review thread(s) remain.\n- 3 required check(s) are not successful on 65f09b1.\n- Missing current-head CodeRabbit/coderabbitai evidence for 65f09b1.\n

@github-actions

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for 65f09b14c47ea101877a8792cd40fd7be7f00a1d:

  • Branch is BEHIND the base branch; update the branch and re-run checks.\n- 5 unresolved current review thread(s) remain.\n- 2 required check(s) are not successful on 65f09b1.\n- Missing current-head CodeRabbit/coderabbitai evidence for 65f09b1.\n

@seonghobae

Copy link
Copy Markdown
Contributor Author

@coderabbitai approve

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
backend/main.py (1)

59-81: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep only one CORSMiddleware policy.

The second CORS registration at Line 75 still overrides/conflicts with the broader origin list added here, so 127.0.0.1:3000 and :8000 are not reliably allowed in practice. Merge on a single middleware block instead of stacking two policies.

Proposed fix
 app.add_middleware(
     CORSMiddleware,
     allow_origins=["http://localhost:3000", "http://127.0.0.1:3000", "http://localhost:8000", "http://127.0.0.1:8000"],
     allow_credentials=True,
     allow_methods=["*"],
     allow_headers=["*"],
 )
@@
-app.add_middleware(
-    CORSMiddleware,
-    allow_origins=["http://localhost:3000"],
-    allow_credentials=True,
-    allow_methods=["*"],
-    allow_headers=["*"],
-)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/main.py` around lines 59 - 81, There are two
app.add_middleware(CORSMiddleware, ...) registrations which conflict; keep a
single CORSMiddleware call that contains the full allow_origins list (including
"http://localhost:3000", "http://127.0.0.1:3000", "http://localhost:8000",
"http://127.0.0.1:8000"), remove the duplicate block that only allows
"http://localhost:3000", and ensure the remaining
app.add_middleware(CORSMiddleware, ...) uses allow_credentials=True,
allow_methods=["*"], and allow_headers=["*"] so CORS is applied once
consistently.
🧹 Nitpick comments (1)
backend/main.py (1)

53-57: ⚡ Quick win

Exclude /metrics from tracing.

Once Prometheus starts scraping, Line 57 will emit a span for every scrape. That adds steady Tempo noise and makes real request traces harder to inspect.

Proposed fix
 # Instrument Prometheus Metrics
 Instrumentator().instrument(app).expose(app, include_in_schema=False, should_gzip=True)
 
 # Instrument OpenTelemetry
-FastAPIInstrumentor.instrument_app(app)
+FastAPIInstrumentor.instrument_app(app, excluded_urls="/metrics")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/main.py` around lines 53 - 57, The FastAPIInstrumentor.instrument_app
call currently instruments the /metrics scrape; update it to exclude that path
so Prometheus scrapes don't create spans. Replace the current
FastAPIInstrumentor.instrument_app(app) invocation with a call that passes an
excluded_urls list (e.g., FastAPIInstrumentor.instrument_app(app,
excluded_urls=[r"^/metrics$"]) or equivalent regex) so the /metrics endpoint is
not traced; keep the Instrumentator() call for Prometheus unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/main.py`:
- Around line 37-52: The current init block only checks
OTEL_EXPORTER_OTLP_ENDPOINT and will skip tracing when only
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT is set; update the guard to check for either
environment variable (OTEL_EXPORTER_OTLP_ENDPOINT or
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT) before importing and configuring
OpenTelemetry so OTLPSpanExporter() is initialized when either endpoint var is
present; leave the rest of the setup (resource, TracerProvider/trace_provider,
BatchSpanProcessor/processor, trace.set_tracer_provider) unchanged.

---

Duplicate comments:
In `@backend/main.py`:
- Around line 59-81: There are two app.add_middleware(CORSMiddleware, ...)
registrations which conflict; keep a single CORSMiddleware call that contains
the full allow_origins list (including "http://localhost:3000",
"http://127.0.0.1:3000", "http://localhost:8000", "http://127.0.0.1:8000"),
remove the duplicate block that only allows "http://localhost:3000", and ensure
the remaining app.add_middleware(CORSMiddleware, ...) uses
allow_credentials=True, allow_methods=["*"], and allow_headers=["*"] so CORS is
applied once consistently.

---

Nitpick comments:
In `@backend/main.py`:
- Around line 53-57: The FastAPIInstrumentor.instrument_app call currently
instruments the /metrics scrape; update it to exclude that path so Prometheus
scrapes don't create spans. Replace the current
FastAPIInstrumentor.instrument_app(app) invocation with a call that passes an
excluded_urls list (e.g., FastAPIInstrumentor.instrument_app(app,
excluded_urls=[r"^/metrics$"]) or equivalent regex) so the /metrics endpoint is
not traced; keep the Instrumentator() call for Prometheus unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4a941605-e33e-456e-99be-c2aa5cb889fa

📥 Commits

Reviewing files that changed from the base of the PR and between 5f91c8b and 65f09b1.

📒 Files selected for processing (1)
  • backend/main.py

Comment thread backend/main.py
@coderabbitai

coderabbitai Bot commented May 11, 2026

Copy link
Copy Markdown
Contributor
✅ Actions performed

Comments resolved and changes approved.

@github-actions

Copy link
Copy Markdown
Contributor

PR governance metadata gate is not ready for 65f09b14c47ea101877a8792cd40fd7be7f00a1d:

  • Branch is BEHIND the base branch; update the branch and re-run checks.\n- 1 required check(s) are not successful on 65f09b1.\n- Missing current-head CodeRabbit/coderabbitai evidence for 65f09b1.\n

@seonghobae
seonghobae merged commit 6b48b7e into master May 11, 2026
16 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Open Source APM/observability 운영 경로 설계 및 검증

1 participant