#metrics phoenix 웹 프레임워크로 만든 프로젝트 지표를 prometheus와 grafana로 모니터링

2 minute read

수집하고 분석할 지표(metric)를 phoenix 웹 프레임워크로 만든 프로젝트에서 노출한다. 프로메테우스(prometheus)는 주기적으로 노출한 지표 정보를 긁어서 저장한다. 이 데이터를 그라파나(grafana)가 보기 좋게 가공해서 보여준다.

간단하게 구성해 테스트해봤다. 전체 코드는 ohyecloudy/phoenix_prometheus_grafana에서 볼 수 있다.

ppg(phoenix, prometheus, grafana) 프로젝트 생성, commit 65c6fb57ca

$ mix archive.install hex phx_new 1.4.12
$ mix phx.new ppg --no-ecto

프로젝트를 만든다. phoenix_prometheus_grafana. 프로젝트 이름으로는 너무 길다. 그래서 ppg 프로젝트를 만들었다.

$ cd ppg
$ mix deps.get
$ mix phx.server

의존 패키지를 설치하고 웹서버를 실행한다. nil 주소를 방문하면 피닉스 프레임워크가 만든 index 페이지를 볼 수 있다.

dockerize, commit 1ab1552f4f

$ script/server

스크립트를 실행하면 docker 컨테이너로 ppg 웹서버를 실행한다. 프로메테우스와 그라파나도 docker 컨테이너로 실행할 예정이라 ppg 프로젝트도 일찌감치 docker 컨테이너로 실행하게 세팅했다.

ppg 프로젝트 지표를 내보내기(export), commit 7ce838fb8f

# mix.exs
defmodule Ppg.MixProject do
  # ...
  defp deps do
    [
      # ...
      {:prometheus_ex, "~> 3.0"},
      {:prometheus_plugs, "~> 1.1"}
    ]
  end

deps 함수에 패키지를 추가한다.

# metrics_exporter.ex
defmodule PpgWeb.MetricsExporter do
  use Prometheus.PlugExporter
end

# endpoint.ex
defmodule PpgWeb.Endpoint do
  # ...
  plug PpgWeb.MetricsExporter

  plug PpgWeb.Router
end

Prometheus.PlugExporter 플러그(plug)를 PpgWeb.Router 플러그 이전에 추가한다. 추가한 플러그는 HTTP 요청이 들어올 때, 항상 실행한다. Prometheus.PlugExporter 플러그는 지표를 프로메테우스에서 긁어갈 수 있는 포맷으로 /metrics 페이지를 만든다.

# setup.ex
defmodule Ppg.Metrics.Setup do
  def setup do
    PpgWeb.MetricsExporter.setup()
  end
end

# application.ex
defmodule Ppg.Application do
  # ...
  def start(_type, _args) do
    Ppg.Metrics.Setup.setup()
    # ...

애플리케이션 시작 전에 초기화 함수를 호출한다.

$ script/server

웹서버를 실행 후 nil 방문하면 지표를 볼 수 있다.

nil

docker compose로 ppg를 실행, commit 2282f52130

docker compose를 쓰면 ppg, 프로메테우스, 그라파나를 쉽게 실행할 수 있다. 사전 작업으로 ppg만 적용한다.

프로메테우스 추가, commit d988d92676

$ cat script/prometheus.yml
global:
  scrape_interval: 15s
  scrape_timeout: 10s
  evaluation_interval: 15s
alerting:
  alertmanagers:
  - static_configs:
    - targets: []
    scheme: http
    timeout: 10s
    api_version: v1
scrape_configs:
- job_name: prometheus
  honor_timestamps: true
  scrape_interval: 15s
  scrape_timeout: 10s
  metrics_path: /metrics
  scheme: http
  static_configs:
  - targets:
    - phoenix:4000

docker compose는 서비스 이름을 host 이름으로 노출한다. ppg 프로젝트 서비스 이름을 phoenix로 정의했다. 그래서 타겟 url이 phoenix:4000 이다.

$ script/server

실행 후 nil 페이지를 방문해본다.

nil

프로메테우스에서 ppg 지표를 확인할 수 있다.

그라파나 추가, commit 16ca0af7fc

데이터 소스와 대시보드 프로비저닝을 지원한다. 프로메테우스를 데이터 소스로 정의하고 deadtrickster/beam-dashboards에서 대시보드를 가져왔다. 프로비저닝 디렉터리를 착각해서 한참 삽질했다. /etc/grafana/provisioning 디렉터리에 복사해야 한다.

$ script/server

실행 후 nil 페이지를 방문해본다. HOME을 클릭하면 대시보드를 선택할 수 있다. elixir > BEAM 을 선택한다.

nil

그럴듯한 게 보인다. uptime, os process memory, native threads & cpu 정보가 안 보여 그럴듯함을 해치고 있다. 이 정보를 지표에 추가하자.

프로세스 콜렉터 추가, commit eb30565317

# mix.exs
defmodule Ppg.MixProject do
  # ...
  defp deps do
    [
      # ...
      {:prometheus_process_collector, "~> 1.4"}
    ]
  end
end

deps 함수에 패키지를 추가한다.

defmodule Ppg.Application do
  # ...
  require Prometheus.Registry

  def start(_type, _args) do
    Prometheus.Registry.register_collector(:prometheus_process_collector)

지표를 수집할 때, 프로세스 콜렉터를 호출할 수 있게 등록한다.

nil

이제 그럴듯하다.

참고