Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Задачи
- Сбор метрик с работающего приложения
- количество резидентной и виртуальной память процесса
- открытые файловые дескрипторы
- количество процессорного времени
- количество потоков и goroutines
- время запуска процесса
- количество HTTP ответов по кодам
- гистограммы задержек HTTP ответов
- Графики
- Мониторинг (в работе)
- Полезные ссылки
- https://prometheus.io/docs/concepts/data_model/
- https://prometheus.io/docs/instrumenting/exposition_formats/
- https://scot.coffee/2018/12/monitoring-go-applications-with-prometheus/
- https://habr.com/company/otus/blog/358588/
- https://www.digitalocean.com/community/tutorials/how-to-query-prometheus-on-ubuntu-14-04-part-1
- Сбор метрик
- Клиентская библиотека Prometheus для Go уже предоставляет нам почти все метрики, что нам нужны. Остается добавить только HTTP метрики.
- Для сбора метрик напишем простое приложение с 2 HTTP ручками для запросов и одной ручкой под экспортирование метрик для Prometheus:
- GET / - возвращает 200 OK
- GET /error - возвращает 500 Internal Server Error
- GET /metrics - возвращает 200 OK и метрики
- package main
- import (
- "fmt"
- "log"
- "net/http"
- "github.com/felixge/httpsnoop"
- "github.com/gorilla/mux"
- "github.com/prometheus/client_golang/prometheus"
- "github.com/prometheus/client_golang/prometheus/promhttp"
- )
- var (
- // Counter for calculate HTTP responses by status code and by method
- // app_http_requests_total{"code": "200", "method": "GET"}
- // https://godoc.org/github.com/prometheus/client_golang/prometheus
- httpReqs = prometheus.NewCounterVec(
- prometheus.CounterOpts{
- Name: "app_http_requests_total",
- Help: "How many HTTP requests processed, partitioned by status code and method.",
- },
- []string{"code", "method"},
- )
- // requestDuration collects sets of histograms for measure HTTP request latencies,
- // partitioned by method, URI and status code.
- requestDuration = prometheus.NewHistogramVec(
- prometheus.HistogramOpts{
- Name: "app_http_reuests_duration_seconds",
- Help: "Time in seconds spent serving HTTP requests.",
- Buckets: prometheus.DefBuckets,
- },
- []string{"method", "uri", "status_code"},
- )
- )
- func init() {
- // Register the collectors with Prometheus's default registry.
- prometheus.MustRegister(httpReqs)
- prometheus.MustRegister(requestDuration)
- }
- func main() {
- r := mux.NewRouter()
- r.HandleFunc("/", metricsMiddleware(indexHandler)).Methods(http.MethodGet)
- r.HandleFunc("/error", metricsMiddleware(errorHandler)).Methods(http.MethodGet)
- r.Handle("/metrics", promhttp.Handler())
- log.Fatal(http.ListenAndServe(":8080", r))
- }
- func metricsMiddleware(h http.HandlerFunc) http.HandlerFunc {
- return func(w http.ResponseWriter, r *http.Request) {
- m := httpsnoop.CaptureMetrics(h, w, r)
- // Increase total counter.
- httpReqs.WithLabelValues(strconv.Itoa(m.Code), r.Method).Inc()
- // Measures histograms.
- requestDuration.WithLabelValues(r.Method, r.URL.Path,
- strconv.Itoa(m.Code)).Observe(m.Duration.Seconds())
- }
- }
- func indexHandler(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(http.StatusOK)
- }
- func errorHandler(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(http.StatusInternalServerError)
- }
- После запуска приложения проверяем его работу:
- curl -s -i http://localhost:8080
- HTTP/1.1 200 OK
- Date: Mon, 10 Dec 2018 09:20:56 GMT
- Content-Length: 0
- curl -s -i http://localhost:8080/error
- HTTP/1.1 500 Internal Server Error
- Date: Mon, 10 Dec 2018 09:21:14 GMT
- Content-Length: 0
- и переходим к метрикам.
- количество резидентной и виртуальной память процесса
- curl -s -i http://localhost:8080/metrics | fgrep -e process_resident_memory_bytes -e process_virtual_memory_bytes
- # HELP process_resident_memory_bytes Resident memory size in bytes.
- # TYPE process_resident_memory_bytes gauge
- process_resident_memory_bytes 1.2439552e+07
- # HELP process_virtual_memory_bytes Virtual memory size in bytes.
- # TYPE process_virtual_memory_bytes gauge
- process_virtual_memory_bytes 5.4728704e+08
- открытые файловые дескрипторы
- curl -s -i http://localhost:8080/metrics | fgrep -e process_max_fds -e process_open_fds
- # HELP process_max_fds Maximum number of open file descriptors.
- # TYPE process_max_fds gauge
- process_max_fds 1024
- # HELP process_open_fds Number of open file descriptors.
- # TYPE process_open_fds gauge
- process_open_fds 8
- количество процессорного времени
- curl -s -i http://localhost:8080/metrics | fgrep -e process_cpu_seconds_total
- # HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
- # TYPE process_cpu_seconds_total counter
- process_cpu_seconds_total 0.38
- количество потоков и goroutines
- curl -s -i http://localhost:8080/metrics | fgrep -e go_threads -e go_goroutines
- # HELP go_goroutines Number of goroutines that currently exist.
- # TYPE go_goroutines gauge
- go_goroutines 7
- # HELP go_threads Number of OS threads created.
- # TYPE go_threads gauge
- go_threads 9
- время запуска процесса
- curl -s -i http://localhost:8080/metrics | fgrep -e process_start_time_seconds
- # HELP process_start_time_seconds Start time of the process since unix epoch in seconds.
- # TYPE process_start_time_seconds gauge
- process_start_time_seconds 1.54443302963e+09
- количество HTTP ответов по кодам
- curl -s -i http://localhost:8080/metrics | fgrep -e app_http_requests_total
- # HELP app_http_requests_total How many HTTP requests processed, partitioned by status code.
- # TYPE app_http_requests_total counter
- app_http_requests_total{code="200",method="GET"} 643
- app_http_requests_total{code="500",method="GET"} 1
- гистограммы задержек HTTP ответов по методу, URI и коду ответа
- curl -s -i http://localhost:8080/metrics | fgrep -e app_http_reuests_duration_seconds
- # HELP app_http_reuests_duration_seconds Time in seconds spent serving HTTP requests.
- # TYPE app_http_reuests_duration_seconds histogram
- app_http_reuests_duration_seconds_bucket{method="GET",status_code="200",uri="/",le="0.005"} 1
- app_http_reuests_duration_seconds_bucket{method="GET",status_code="200",uri="/",le="0.01"} 1
- app_http_reuests_duration_seconds_bucket{method="GET",status_code="200",uri="/",le="0.025"} 1
- app_http_reuests_duration_seconds_bucket{method="GET",status_code="200",uri="/",le="0.05"} 1
- app_http_reuests_duration_seconds_bucket{method="GET",status_code="200",uri="/",le="0.1"} 1
- app_http_reuests_duration_seconds_bucket{method="GET",status_code="200",uri="/",le="0.25"} 1
- app_http_reuests_duration_seconds_bucket{method="GET",status_code="200",uri="/",le="0.5"} 1
- app_http_reuests_duration_seconds_bucket{method="GET",status_code="200",uri="/",le="1"} 1
- app_http_reuests_duration_seconds_bucket{method="GET",status_code="200",uri="/",le="2.5"} 1
- app_http_reuests_duration_seconds_bucket{method="GET",status_code="200",uri="/",le="5"} 1
- app_http_reuests_duration_seconds_bucket{method="GET",status_code="200",uri="/",le="10"} 1
- app_http_reuests_duration_seconds_bucket{method="GET",status_code="200",uri="/",le="+Inf"} 1
- app_http_reuests_duration_seconds_sum{method="GET",status_code="200",uri="/"} 1.9163e-05
- app_http_reuests_duration_seconds_count{method="GET",status_code="200",uri="/"} 1
- Графики
- Можно рисовать графики в консоли самого Prometheus, но гораздо удобнее использовать Grafana (admin:password, но лучше завести своего пользователя).
- Я создал Dashboard Go HTTP Testing с примерами графиков по нашим метрикам.
- Для наглядности используем hey для подачи нагрузки
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement