Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
username: ${{ secrets.REMOTE_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: ./deployment/
target: /home/ubuntu/deployment
target: /home/ubuntu/dearbelly

deploy:
name: Deploy
Expand Down
3 changes: 3 additions & 0 deletions app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from app.core.lifespan import lifespan
from app.api.endpoints import predictions
from app.core.logging_config import setup_logging
from prometheus_fastapi_instrumentator import Instrumentator

setup_logging()
app = FastAPI(
Expand All @@ -11,6 +12,8 @@
lifespan=lifespan
)

instrumentator = Instrumentator().instrument(app)
instrumentator.expose(app, include_in_schema=False, endpoint="/actuator/prometheus")
app.include_router(predictions.router, prefix="/api/v1", tags=["Prediction"])

@app.get("/health")
Expand Down
4 changes: 2 additions & 2 deletions deployment/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ fi

echo "Pulling new image"
# docker pull
docker compose pull app-${AFTER_COMPOSE_COLOR}
docker compose up -d --no-deps --force-recreate app-${AFTER_COMPOSE_COLOR}
docker compose -f docker-compose.yml pull app-${AFTER_COMPOSE_COLOR}
docker compose -f docker-compose.yml up -d --no-deps --force-recreate app-${AFTER_COMPOSE_COLOR}


# 새 컨테이너가 running 될 때까지 대기
Expand Down
33 changes: 33 additions & 0 deletions deployment/docker-compose.monitoring.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
services:
prometheus:
user: ${PROMETHEUS_USER}
image: prom/prometheus:latest

Choose a reason for hiding this comment

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

high

Docker 이미지에 :latest 태그를 사용하는 것은 예기치 않은 버전 업데이트로 인한 장애를 유발할 수 있습니다. 프로덕션 환경에서는 특정 버전을 명시하여 안정성을 확보하는 것이 좋습니다. 예를 들어 prom/prometheus:v2.51.2와 같이 구체적인 버전을 사용해주세요.

container_name: prometheus
volumes:
- /home/ubuntu/dearbelly/deployment/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- /home/ubuntu/prometheus/volume:/prometheus/data
Comment on lines +7 to +8

Choose a reason for hiding this comment

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

high

볼륨 경로에 /home/ubuntu와 같은 하드코딩된 절대 경로를 사용하면 다른 환경으로 이식하기가 매우 어렵습니다. 설정 파일은 상대 경로를 사용하고, 데이터 볼륨은 Docker의 named volume을 사용하는 것을 강력히 권장합니다. 이렇게 하면 다른 개발자나 서버 환경에서도 쉽게 컨테이너를 실행할 수 있습니다.

      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prometheus-data:/prometheus/data

ports:
- 9090:9090
command:
- '--web.enable-lifecycle'
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.retention.time=15d'
restart: always
networks:
- mynetwork

grafana:
user: ${GRAFANA_USER}
image: grafana/grafana:latest

Choose a reason for hiding this comment

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

high

Docker 이미지에 :latest 태그를 사용하는 것은 예기치 않은 버전 업데이트로 인한 장애를 유발할 수 있습니다. 프로덕션 환경에서는 특정 버전을 명시하여 안정성을 확보하는 것이 좋습니다. 예를 들어 grafana/grafana:10.4.2와 같이 구체적인 버전을 사용해주세요.

container_name: grafana
ports:
- 3000:3000
volumes:
- /home/ubuntu/grafana/volume:/var/lib/grafana

Choose a reason for hiding this comment

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

high

Grafana 데이터 볼륨 경로가 하드코딩되어 있습니다. 이식성을 높이기 위해 Docker named volume을 사용하는 것이 좋습니다. 파일 최상단 services와 같은 레벨에 volumes 섹션을 추가하고 grafana-data:를 정의해야 합니다.

      - grafana-data:/var/lib/grafana

restart: always
networks:
- mynetwork

networks:
mynetwork:
driver: bridge

Choose a reason for hiding this comment

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

medium

파일 끝에 개행 문자가 없습니다. POSIX 표준에 따르면 텍스트 파일은 개행 문자로 끝나야 합니다. 또한, 제안드린 named volume을 사용하기 위해서는 파일 하단에 volumes 섹션을 추가해야 합니다.

networks:
  mynetwork:
    driver: bridge

volumes:
  prometheus-data:
  grafana-data:

17 changes: 17 additions & 0 deletions deployment/prometheus-rule.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
groups:
- name: example

Choose a reason for hiding this comment

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

medium

규칙 그룹 이름이 example로 되어 있습니다. fastapi-rules와 같이 좀 더 의미 있는 이름으로 변경하면 향후 규칙을 관리하기가 더 수월해집니다.

  - name: fastapi-rules

rules:
- alert: InstanceDown
expr: up == 0
for: 5m
labels:
severity: page
annotations:
summary: "Instance {{ $labels.instance }} down"
description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."
- alert: APIHighRequestLatency
expr: api_http_request_latencies_second{quantile="0.5"} > 1

Choose a reason for hiding this comment

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

critical

prometheus-fastapi-instrumentator 라이브러리는 기본적으로 Histogram 타입의 http_requests_latency_seconds 메트릭을 생성합니다. 현재 사용된 api_http_request_latencies_second{quantile="0.5"} 표현식은 Summary 타입의 메트릭을 위한 것이므로, 이 경고 규칙은 동작하지 않습니다. Histogram 메트릭에서 분위수(quantile)를 계산하려면 histogram_quantile 함수를 사용해야 합니다. 또한 메트릭 이름도 http_requests_latency_seconds로 수정이 필요해 보입니다.

        expr: histogram_quantile(0.5, sum(rate(http_requests_latency_seconds_bucket[5m])) by (le, job, instance)) > 1

for: 10m
annotations:
summary: "High request latency on {{ $labels.instance }}"
description: "{{ $labels.instance }} has a median request latency above 1s (current value: {{ $value }}s)"

Choose a reason for hiding this comment

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

medium

파일 끝에 개행 문자가 없습니다. POSIX 표준에 따라 텍스트 파일은 개행 문자로 끝나야 합니다.

34 changes: 34 additions & 0 deletions deployment/prometheus.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
global:
scrape_interval: 15s
scrape_timeout: 15s
evaluation_interval: 2m
external_labels:
monitor: 'codelab-monitor'
query_log_file: query_log_file.log

Choose a reason for hiding this comment

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

medium

query_log_file을 설정하면 컨테이너 내부에 로그 파일이 생성됩니다. 컨테이너가 재시작되면 이 로그는 사라집니다. 로그를 영속적으로 보관하거나 중앙에서 관리하려면, 이 설정을 제거하고 stdout/stderr로 로그를 출력하여 Docker의 로깅 드라이버를 사용하는 것을 고려해보세요.

rule_files:
- "prometheus-rule.yml"

Choose a reason for hiding this comment

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

critical

prometheus-rule.yml 파일을 규칙 파일로 참조하고 있지만, docker-compose.monitoring.yml 파일에서 해당 파일을 컨테이너로 마운트하는 설정이 누락되었습니다. 이로 인해 Prometheus가 경고 규칙을 로드하지 못하여 알림이 동작하지 않습니다. docker-compose.monitoring.ymlprometheus 서비스 volumes에 다음을 추가해야 합니다:

- ./prometheus-rule.yml:/etc/prometheus/prometheus-rule.yml:ro

scrape_configs:
- job_name: 'prometheus'
scrape_interval: 10s
scrape_timeout: 10s
metrics_path: '/metrics'
honor_labels: false
honor_timestamps: false
scheme: 'http'
static_configs:
- targets: ['${REMOTE_HOST}:9090']
labels:
service: 'monitor-1'
- job_name: 'node'
static_configs:
- targets: ['${REMOTE_HOST}:9090']
Comment on lines +22 to +24

Choose a reason for hiding this comment

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

high

job_namenode이지만, 수집 대상(target)이 Prometheus 자신(port 9090)으로 설정되어 있습니다. 일반적으로 node 잡은 node-exporter(보통 9100 포트)를 대상으로 하여 호스트 시스템의 메트릭을 수집합니다. 이 잡이 의도된 것이 아니라면 삭제하거나, node-exporter를 수집하도록 설정을 수정해야 합니다.

- job_name: 'fastapi-actuator-blue'
metrics_path: '/actuator/prometheus'
scrape_interval: 1m
static_configs:
- targets: [ 'app-blue:8000' ]
- job_name: 'fastapi-actuator-green'
metrics_path: '/actuator/prometheus'
scrape_interval: 1m
static_configs:
- targets: [ 'app-green:8001' ]

Choose a reason for hiding this comment

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

critical

app-green 서비스의 수집 대상 포트가 8001로 잘못 설정되어 있습니다. docker-compose.yml을 보면 app-green 컨테이너는 내부적으로 8000 포트를 사용하고, 이를 호스트의 8001 포트로 매핑합니다. Docker 브릿지 네트워크 내에서 서비스 간 통신은 내부 포트를 사용해야 하므로, app-green:8000으로 수정해야 합니다.

      - targets: [ 'app-green:8000' ]

Choose a reason for hiding this comment

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

medium

파일 끝에 개행 문자가 없습니다. POSIX 표준에 따라 텍스트 파일은 개행 문자로 끝나야 합니다.

4 changes: 3 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ Pillow==11.3.0
dotenv
openai
timm
logging
logging
prometheus-client==0.19.0
prometheus-fastapi-instrumentator==6.1.0

Choose a reason for hiding this comment

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

medium

파일 끝에 개행 문자가 없습니다. POSIX 표준에 따라 텍스트 파일은 개행 문자로 끝나야 합니다.