-
[Monitoring] Prometheus + google chat 으로 알림받기Infra/devOps 2024. 11. 6. 05:42
Prometheus는 SoundCloud사에서 만든 오픈소스 시스템 모니터링 및 경고 툴킷이다.
지금은 독립형 오픈소스 프로젝트이며 많은 회사들이 사용 하고 있고, 또한 kubernetes에서도 Prometheus를 사용하여 매트릭 수집 및 대시보드 구축하는 방식을 장려하고 있다.
저기 보이는 exporter 들은 값을 수집하는 프로세스라고 보면 된다.
이 exporter가 매트릭을 수집하고 HTTP 통신을 통해 매트릭 데이터를 가져갈 수 있게 /metrics 라는 HTTP 엔드포인트를 제공한다.
그러면 프로메테우스가 Get 요청으로 받아온다고 한다.필자는 도커로 프로메테우스를 설정하였다.
먼저 prometheus.yml 설정을 확인해보자.
global: scrape_interval: 15s evaluation_interval: 15s alerting: alertmanagers: - static_configs: - targets: ["alertmanager:9093"] rule_files: - "alert.rules.yml" scrape_configs: - job_name: "mysql_exporters" static_configs: - targets: - "mysql_exporter-prod:9104" - "mysql_exporter-qa:9104" - "mysql_exporter-dev:9104" - job_name: "node_exporters" static_configs: - targets: - "1.2.3.4:9100" - "1.2.3.5:9100" - "1.2.3.6:9100"
내가 사용한 코드는 다음과 같다.
scrape_interval: Prometheus가 정의된 모든 scrape_configs에서 메트릭 데이터를 수집하는 주기이다.
evaluation_interval: Prometheus가 정의된 규칙을 평가하는 주기라고 하는데 Alerting이나 Recording 규칙이라고 한다.AlertManager 설정
alerting 이 있는 부분은
경고를 발생시킬 때 경고를 전송할 alertmanager를 정의한 것이다.
필자는 google chat 으로 요청을 받고 싶은데 그냥 웹훅을 설정하면
Invalid JSON payload received. Unknown name
라는 에러로 Json 형식의 에러가 난다.
alertmanager 에서는 이런 설정을 해줄 수 없다.
그래서 내가 설정한 방법은 파이썬 컨테이너를 동작시켜 그 서버에서 처리를 하여
내 alertmanager 에게 요청을 전달하는 것이다.
from flask import Flask, request, jsonify import requests app = Flask(__name__) GOOGLE_CHAT_WEBHOOK_URL = "https://chat.googleapis.com/v1/spaces/{SPACE}/messages?key={KEY}&token={TOKEN}" @app.route('/alert', methods=['POST']) def alert(): data = request.json google_chat_message = { "text": f"Alerts from Alertmanager:\n\n{data.get('alerts', [])}" } response = requests.post(GOOGLE_CHAT_WEBHOOK_URL, json=google_chat_message) return jsonify({"status": response.status_code}) if __name__ == '__main__': app.run(host="0.0.0.0", port=5000)
이 스크립트를 도커라이제이션할 수 있도록 Dockerfile 을 작성한다.
FROM python:3.10-slim WORKDIR /app COPY . . RUN pip install --no-cache-dir flask requests CMD ["python", "scipt.py"]
이를 이제 image 로 build 하고 run 하면 된다.
docker build -t {imageName} . docker run -d --name {containerName} -p 5000:5000 {imageName}
이제 컨테이너가 동작한다.
잘 돌아가는지 확인하기 위해서는
curl -X POST http://localhost:5000/alert -H "Content-Type: application/json" -d '{"alerts": [{"status": "firing", "labels": {"alertname": "HighMemoryUsage", "severity": "critical"}, "annotations": {"description": "Memory usage is above 90%!"}}]}'
를 통해 쏘면
이와 같이 동작하는 것을 볼 수 있다.
alert manager 의 설정은 다음과 같다.
global: resolve_timeout: 5m route: receiver: "google_chat" group_wait: 30s group_interval: 5m repeat_interval: 3h receivers: - name: "google_chat" webhook_configs: - url: "http://relay:5000/alert" send_resolved: true
도커 실행 명령어
docker run -d --name alertmanager -p 9093:9093 -v /path/to/alertmanager.yml:/etc/alertmanager/alertmanager.yml prom/alertmanager
이후 실제 동작 메세지
Rules
groups: - name: node_exporter_alerts rules: - alert: LowStorageSpace expr: node_filesystem_avail_bytes < 500 * 1024 * 1024 for: 1m labels: severity: warning annotations: summary: "Low storage space on {{ $labels.instance }}" description: "Storage space is below 500MB on instance {{ $labels.instance }}." - alert: HighMemoryUsage expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes > 0.9 for: 1m labels: severity: warning annotations: summary: "High memory usage on {{ $labels.instance }}" description: "Memory usage is above 90% on instance {{ $labels.instance }}." - alert: InstanceDown expr: up == 0 for: 1m labels: severity: critical annotations: summary: "Instance {{ $labels.instance }} is down" description: "The instance {{ $labels.instance }} is not reachable."
이렇게 언제 알림을 보낼지에 대한 규칙을 추가해준다.
exporter
mysql_exporter
docker run -d --name {containerName} -p {port}:9104 prom/mysqld-exporter --mysqld.address={host}:{port} --mysqld.username={id}:{pw}
-e DATA_SOURCE_NAME 이런 방식으로 전달하려 했는데
에러가 발생했다.
나는 mysqld 를 활용해서 전달하였더니 잘 가져왔다.
node_exporter
docker run -d --name {containerName} -p {port}:9100 prom/node-exporter
필자는 node_exporter 는 대상 인스턴스에,
나머지는 외부 인스턴스에 두어서 설치하였다.
최종 컨테이너 상태는 다음과 같다.
그라파나로 대시보드 구성하였는데
이는 다음에 더 정리해보려 한다.
'Infra > devOps' 카테고리의 다른 글
[웹 사이트 성능 향상시키기] gzip 을 적용해보자. (0) 2024.10.22 [Ubuntu22.04] 우분투 22.04 원격 튕김 오류 해결 (0) 2024.06.24 [GitLab] 한 ec2 인스턴스로 여러 서비스 배포하기 - 1 (ec2 인스턴스에 gitlab-runner 설정하기까지) (1) 2024.05.05