django-prometheus 使い方 prometheus を理解してみた


django-prometheus の記事があんまり見当たらなかったので やってみた。
prometheus を触ったことがないので、一緒に勉強してみた

概要

  • django-prometheusが、暗号にしか見えない web endpoint ↓ を公開してくれる
  • prometheus が、それを polling する
    • django-prometheus がデータを prometheus に送るわけではない! ただ html ひとつ出すだけです。
  • grafana が prometheus のデータを visualize する

悩んだ

django-prometheus が agent だと思ってたので全然理解できなくてしばらく悩んだ。
django-prometheus はただapiを提供するだけで。prometheusが向こうからそれを取りに来る。

django-prometheusを動かしてみる

Tutorial
https://docs.timescale.com/latest/tutorials/tutorial-howto-monitor-django-prometheus

mkdir django-prometheus
cd django-prometheus
python -m pip install Django
django-admin startproject mysite
cd mysite
python manage.py runserver
# ctrl + c
python -m pip install django-prometheus

settings.py を編集する。middlewareのところが既存の設定を挟み込むようにする。最初と最後じゃないといけない。注意。

mysite/settings.py
INSTALLED_APPS = [
   ...
   'django_prometheus',
   ...
]

MIDDLEWARE = [
    'django_prometheus.middleware.PrometheusBeforeMiddleware',
    # All your other middlewares go here, including the default
    # middlewares like SessionMiddleware, CommonMiddleware,
    # CsrfViewmiddleware, SecurityMiddleware, etc.
    'django_prometheus.middleware.PrometheusAfterMiddleware',
]
mysite/urls.py
from django.conf.urls import url, include

urlpatterns = [
    ...
    url('', include('django_prometheus.urls')),
]

django 起動する

python manage.py runserver 0.0.0.0:8000
curl localhost:8000/metrics

ブラウザで /metrics が見えればok

prometheus / grafana を起動する

素晴らしいcomposeがあるのでまんま使います。関係ないコンテナも起動するけど、勉強のためそのまま起動。

Refer to
https://github.com/vegasbrianc/prometheus/blob/master/docker-compose.yml

まずvolumeを外して起動する

docker-compose.yml
#https://github.com/vegasbrianc/prometheus/blob/master/docker-compose.yml
version: '3.7'

volumes:
    prometheus_data: {}
    grafana_data: {}

networks:
  front-tier:
  back-tier:

services:

  prometheus:
    image: prom/prometheus:v2.1.0
#    volumes:
#      - ./prometheus/:/etc/prometheus/
#      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/usr/share/prometheus/console_libraries'
      - '--web.console.templates=/usr/share/prometheus/consoles'
    ports:
      - 9090:9090
    links:
      - cadvisor:cadvisor
      - alertmanager:alertmanager
#      - pushgateway:pushgateway
    depends_on:
      - cadvisor
#      - pushgateway
    networks:
      - back-tier
    restart: always
#    deploy:
#      placement:
#        constraints:
#          - node.hostname == ${HOSTNAME}

  node-exporter:
    image: prom/node-exporter
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - --collector.filesystem.ignored-mount-points
      - "^/(sys|proc|dev|host|etc|rootfs/var/lib/docker/containers|rootfs/var/lib/docker/overlay2|rootfs/run/docker/netns|rootfs/var/lib/docker/aufs)($$|/)"
    ports:
      - 9100:9100
    networks:
      - back-tier
    restart: always
    deploy:
      mode: global

  alertmanager:
    image: prom/alertmanager
    ports:
      - 9093:9093
#    volumes:
#      - ./alertmanager/:/etc/alertmanager/
    networks:
      - back-tier
    restart: always
    command:
      - '--config.file=/etc/alertmanager/config.yml'
      - '--storage.path=/alertmanager'
#    deploy:
#      placement:
#        constraints:
#          - node.hostname == ${HOSTNAME}
  cadvisor:
    image: google/cadvisor
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
    ports:
      - 8080:8080
    networks:
      - back-tier
    restart: always
    deploy:
      mode: global

  grafana:
    image: grafana/grafana
    user: "472"
    depends_on:
      - prometheus
    ports:
      - 3000:3000
#    volumes:
#      - grafana_data:/var/lib/grafana
#      - ./grafana/provisioning/:/etc/grafana/provisioning/
#    env_file:
#      - ./grafana/config.monitoring
    networks:
      - back-tier
      - front-tier
    restart: always

#  pushgateway:
#    image: prom/pushgateway
#    restart: always
#    expose:
#      - 9091
#    ports:
#      - "9091:9091"
#    networks:
#      - back-tier

起動したら prometheus の config を変更するために、既存ファイルをcopyする

docker cp prometheus_prometheus_1:/etc/prometheus .
vim prometheus/prometheus.yml

最終行の targets に、 django-prometheus が動いているendpoint を入れる。
/metrics は不要(全員デフォルトでそこ取るよ、って書いてある)

prometheus/prometheus.yml
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: 'prometheus'

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
      - targets: ['localhost:9090', '192.168.1.2:8000']    <------ ここにdjango-prometheusが動いてるサーバを足す

そしたら、その prometheus.yml を読み込むようにvolumesを変えて、recreateする。

services:

  prometheus:
    image: prom/prometheus:v2.1.0
   volumes:                                 <------------- ここだけ
     - ./prometheus/:/etc/prometheus/        <------------- 変える
#      - prometheus_data:/prometheus

prometheus 動作確認

ブラウザで prometheus を開く

menuから Status > Targets を開く

http://localhost:9090/targets
*prometheusがlocalにある場合はこれで開けるはず

djangoのendpointがきちんと認識されていることを確認する

ここに出る endpoint が prometheus コンテナの中から見えれば ok.

Topに戻り、 - insert metric at cursor - の select menu を開き、適当に1つ選ぶ

Executeを押す → value が出ればok

例えば django_http_requests_total_by_method_total の場合

grafanaで見てみる

grafana に login する

id/pwは両方admin

configuration > Data sources を選ぶ

Add Data Source ボタンを押し、Prometheus を select
URL に docker network でアクセスできる prometheus の URL を入れて、 Save & Test するだけ

http://prometheus_prometheus_1:9090


*Grafana コンテナから Prometheus コンテナにアクセスするのでこうしてます。(同じdocker networkにいれば、コンテナ名でアクセスできる)

query 叩いてみる

graphがでたら成功!

django の項目をもっと取ってみる

manual
https://github.com/korfuri/django-prometheus

基本簡単です。

DBの状態取る場合

こういうのが欲しい場合

mysqlでもなんでも django.django_prometheus. にするだけ

settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },
}

↓↓↓↓↓↓↓↓↓↓↓↓↓↓

DATABASES = {
    'default': {
        'ENGINE': 'django_prometheus.db.backends.sqlite3',       <-------
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },
}

Modelを取る場合

こういうのが欲しい場合

models.Model の前に一個足すだけ

models/foovar.py
class Dog(models.Model):

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

from django_prometheus.models import ExportModelOperationsMixin
class Dog(ExportModelOperationsMixin('dog'), models.Model):

modelごとに動きが見えます。すごい。

おわり!