Monitoramento na era DevOps

Uma introdução ao Prometheus

(Repositório do hands-on em https://github.com/andreyev/prometheus_hands-on)

whoami

história

Can we skip to the good part?

Observabilidade

  • logs
  • rastreabilidade
  • métricas

Observabilidade (analogia)

  • logs: variação no pedal do acelerador, pista em declive, troca de marcha
  • rastreabilidade: variação no consumo de combustível, consumo por quilômetro
  • métricas: leitura do velocimetro

Observabilidade

  • logs
  • rastreabilidade
  • métricas

Métricas e amostras

up{instance="demo.do.prometheus.io:9090", job="prometheus"} 1

Métricas e amostras

nome da métrica up
labels { instance="demo.do.prometheus.io:9090", job="prometheus" }
valor 1

Filosofia Unix

“This is the Unix philosophy: write programs that do one thing and do it well. Write programs to work together. Write programs that handle text streams, because that is a universal interface.” —Douglas McIlroy.

Filosofia Unix

$ ps -ef  | grep xyz

Filosofia Unix

Arquitetura básica

Filosofia Unix

  • alertmanager
  • pushgateway
  • exporters (blackbox exporter, node-exporter etc)
  • thanos
  • grafana?!
  • curl

Filosofia Unix

Arquitetura completa

Pilares

PromQL

"One ringquery to rule them all"

Pilares

PromQL

"One ringquery to rule them all"

  • queries
  • API
  • grafana
  • alert rules expr

Pilares

PromQL

node_filesystem_device_error == 1

Pilares

PromQL

Notação matemática convencional

((node_filesystem_avail_bytes * 100) / node_filesystem_size_bytes < 10 and
ON (instance, device, mountpoint) predict_linear(node_filesystem_avail_bytes{fstype!~"tmpfs"}[1h], 24 * 3600) < 0 and
ON (instance, device, mountpoint) node_filesystem_readonly == 0) * on(instance) group_left (nodename) node_uname_info{nodename=~".+"}

Pilares

PromQL: regex ⚠️

RE2 vs PCRE

Pilares

PromQL

API

$ curl -s 'http://localhost:9090/api/v1/query?query=up' | jq '.data.result[] | {instance: .metric.instance, status: .value[1]}'
{
  "instance": "node-exporter:9100",
  "status": "1"
}
{
  "instance": "https://www.google.com",
  "status": "1"
}
{
  "instance": "demo:8001",
  "status": "1"
}
{
  "instance": "prometheus:9090",
  "status": "1"
}
{
  "instance": "pushgateway:9091",
  "status": "1"
}
{
  "instance": "alertmanager:9093",
  "status": "1"
}

Pilares

PromQL

Bibliotecas e exemplos: https://samber.github.io/awesome-prometheus-alerts

Pilares

Fontes de dados

Pilares

Fontes de dados

  • Exporters
  • Targets
  • Jobs
  • Clientes e bibliotecas

Pilares

Fontes de dados

  • Exporters: apps que colhem e servem dados de outros apps. Mysql-exporter, por exemplo.
  • Targets: alvo (geralmente URL) de uma fonte de dados (aka uma app instrumentada ou um exporter).
  • Jobs: Agrupadores de tipos de targets pelas suas características semelhantes (path, porta, tipo de app etc)
  • Clientes e bibliotecas: next

Pilares

Exporters

  • Node exporter: info(RAM, disco CPU etc) do computador em que ele está sendo executado
  • Blackbox exporter: HTTP, HTTPS, DNS, TCP, ICMP etc.
  • Cadvisor: "node exporter" para containeres.
  • Pushgateway: cache para métricas assíncronas, curtas ou temporárias, como cronjobs, scripts ou pipelines de CI/CD.
  • mysql, postgres, elastic search, RDS, cloudwatch, JIRA, kafka, RabbitMQ, Varnish etc ( ~200 "oficiais/suportados" em https://prometheus.io/docs/instrumenting/exporters/)

Pilares

Clientes e bibliotecas - Métricas

$ curl -s http://localhost:8001/metrics | head
# HELP python_gc_objects_collected_total Objects collected during gc
# TYPE python_gc_objects_collected_total counter
python_gc_objects_collected_total{generation="0"} 249.0
python_gc_objects_collected_total{generation="1"} 12.0
python_gc_objects_collected_total{generation="2"} 0.0
# HELP python_gc_objects_uncollectable_total Uncollectable objects found during GC
# TYPE python_gc_objects_uncollectable_total counter
python_gc_objects_uncollectable_total{generation="0"} 0.0
python_gc_objects_uncollectable_total{generation="1"} 0.0
python_gc_objects_uncollectable_total{generation="2"} 0.0

Pilares

Clientes e bibliotecas - Instrumentação

from flask import Flask, jsonify, request
from prometheus_client import make_wsgi_app, Counter, Histogram
from werkzeug.middleware.dispatcher import DispatcherMiddleware
import time
app = Flask(__name__)
app.wsgi_app = DispatcherMiddleware(app.wsgi_app, {
    '/metrics': make_wsgi_app()
})
REQUEST_LATENCY = Histogram(
    'app_request_latency_seconds',
    'Application Request Latency',
    ['method', 'endpoint']
)
@app.route('/')
def hello():
    start_time = time.time()
response = jsonify(message='Hello, world!')
    REQUEST_LATENCY.labels('GET', '/').observe(time.time() - start_time)
    return response
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Pilares

SD (Service Discovery)

  • Arquivo
  • Consul
  • Nuvem (EC2 etc)
  • Estático
  • etc

Pilares

TSDB (Time Series Data Base)

Pilares

TSDB (Time Series Data Base)

Alertmanager (sneak peek): integração

Alertmanager (sneak peek): rotas

Obrigado!!!!!1

Repositório desta apresentação https://github.com/andreyev/monitoring_in_devops_age-prometheus