برنامه نویسی

ابزار برنامه Golang با استفاده از پرومتئوس

عکس توسط دانیل کورپای در Unssplash

چرا نظارت بر برنامه؟

تام ویلکی این روش را معرفی کرد استفاده کردن (استفادهبا اشباعبا خطا) برای اندازه گیری استفاده از سخت افزار مانند سرعت خواندن توسط گرده (I/O) ، استفاده از حافظه و شبکه. اما این روشها عملکرد برنامه و نحوه تعامل کاربران با برنامه ها را نشان نمی دهند. بنابراین ، او این روش را معرفی کرد قرمز (نرخبا خطابا مدت). با استفاده از روش شناسی قرمز، توسعه دهنده می تواند دریابد که مدت زمان بالا نشان می دهد که برنامه به آرامی اجرا می شود یا وقتی جواب می دهد درخواست بیشتر آنها در یک بازه زمانی خاص رخ می دهد.

درباره پرومتئوس

Prometheus یک نرم افزار است که توسط SoundCloud ساخته شده است. از پرومتئوس برای نظارت استفاده می شود (نظارت) عملکرد برنامه و هشدارها (هشدار دهنده) در صورت وجود موانعی در برنامه. پرومتئوس داده های متریک را جمع آوری و ذخیره می کند (معیارها) در قالب سری زمانی (سری زمانی). معیارها با استفاده از یک نشانگر زمان ذخیره می شوند (زمان سنج) همراه با یک برچسب به شکل یک جفت کلید و مقدار (جفت های ارزش کلیدی). پرومتئوس داده های متریک را از برنامه به طور مداوم یا معمولاً به عنوان شناخته می کند مکانیزم کشیدنبشر

موارد زیر یک معماری پرومتئوس است.

معماری پرومتئوس

پرومتئوس با انجام داده های متریک می گیرد کشیدن یا خراش از هدف پرومتئوس، جایی که این هدف می تواند یک برنامه باشد HTTP یا مجموعه پایگاه دادهبشر پرومتئوس اهداف برنامه را می داند که خواهد بودخراش از طریق کشف خدماتی که می تواند به طور خودکار توسط Kubernetes انجام شود یا هدف خود را با استفاده از آن تعریف می کنیم پرونده پیکربندیبشر معیارهای موفق خراش توسط پرومتئوس می توانیم استفاده کنیم رفیقبشر

متریک پرومتئوس

پرومتئوس 4 معیار دارد که به طور خاص برای اندازه گیری عملکرد برنامه استفاده می شود

  1. پیشرو
    Counter یک متریک با افزایش ماهیت یکنواخت است ، اما مقدار می تواند به 0 تغییر کند. پیشخوان می تواند برای نظارت درخواست که با موفقیت پردازش شد و تعداد خطاها (خطا).

  2. سنج
    سنج معیار است که فقط می تواند بالا یا پایین برود. از سنج می توان برای نظارت بر مصرف حافظه ، مصرف CPU و مقدار استفاده کرد درخواست که همزمان اتفاق می افتد.

  3. بافت نگار
    هیستوگرام یک متریک است که برخی از مشاهدات را در یک محدوده خاص جمع می کند که می تواند پیکربندی شود. هیستوگرام می تواند برای نظارت بر زمان لازم برای تکمیل درخواست در یک بازه زمانی خاص یا اندازه را کنترل کنید درخواست در یک بازه زمانی خاص

  4. خلاصه

ابزار برنامه با استفاده از پرومتئوس

موارد زیر یک ساختار است پوشه که ما برای انجام ابزار دقیق با استفاده از یک نقش و داکر استفاده خواهیم کرد.

قبل از دویدن docker compose up -d، مطمئن شوید که ساختار پوشه مثل این

|   docker-compose.yml
|   Dockerfile
|   go.mod
|   go.sum
|   main.go
|   prometheus.yml
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

قبل از انجام ابزار دقیق ، برخی از آنها را نصب می کنیم بسته بندی کردن که با استفاده از آن مورد نیاز است

go get github.com/prometheus/client_golang/prometheus/promauto /
github.com/prometheus/client_golang/prometheus /
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

به عنوان مثال ما HTTP داریم کنترل کننده به عنوان زیر

http.HandleFunc("https://dev.to/", func(w http.ResponseWriter, r *http.Request) {
        err := serviceA()
    })
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

درون کنترل کننده ما یک تابع داریم serviceA، جایی که این عملکرد منطق کسب و کار را اجرا خواهد کرد ، با اتصالات خارجی مانند فراخوانی ارتباط برقرار کنید gRPC از خدمات یا انجام دهید HTTP call به برنامه های دیگر ، انجام query در databaseبشر برای فهمیدن چقدر request که با موفقیت انجام می شود یا با موفقیت پردازش می شود و چه مدت طول می کشد تا پردازش شود request با کنترل کننده ما با استفاده از توابع ابزار دقیق انجام می دهیم setMeter()بشر

// main.go

var opsProcessed *prometheus.CounterVec

var opsDuration *prometheus.HistogramVec

func setMeter() {
    opsProcessed = promauto.NewCounterVec(
        prometheus.CounterOpts{
            Name: "app_request_total",
            Help: "Number of total request",
        },
        []string{"URL", "status"},
    )

    opsDuration = promauto.NewHistogramVec(
        prometheus.HistogramOpts{
            Name: "app_request_duration",
            Help: "Duration of a request",
        },
        []string{"URL", "status"},
    )

    prometheus.Register(opsProcessed)

    prometheus.Register(opsDuration)
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

در عملکرد بالا ، ما آن را اعلام می کنیم opsProcessed وت opsDuration به عنوان یک متریک که برای آموزش استفاده می شود سرور HTTPبشر opsProcessed برای اندازه گیری میزان استفاده می شود request فرآوری شده و opsDuration برای اندازه گیری مدت زمان لازم برای تکمیل a استفاده می شود درخواستبشر هنگام شروع دو معیار ، یک آرگومان با نوع داده وجود دارد []stringبشر این استدلال به عنوان گفته می شود برچسب که برای تشخیص معیارها مفید است و ما برای انجام آن استفاده خواهیم کرد پرسش بعداً پرومتئوس. ما می توانیم تعریف کنیم برچسب در صورت لزوم ، و در این مثال ما انجام می دهیم برچسب زدن برای مسیر وت کد پاسخ HTTPبشر راهنمای کامل استفاده برچسب در اینجا دیده می شود.

به دنبال کل کد مورد استفاده در main.go

// main.go

package main

var opsProcessed *prometheus.CounterVec

var opsDuration *prometheus.HistogramVec

func setMeter() {
    opsProcessed = promauto.NewCounterVec(
        prometheus.CounterOpts{
            Name: "app_request_total",
            Help: "Number of total request",
        },
        []string{"URL", "status"},
    )

    opsDuration = promauto.NewHistogramVec(
        prometheus.HistogramOpts{
            Name: "app_request_duration",
            Help: "Duration of a request",
        },
        []string{"URL", "status"},
    )

    prometheus.Register(opsProcessed)

    prometheus.Register(opsDuration)
}

func main() {
    setMeter()

    http.HandleFunc("https://dev.to/", func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()

        respCode := 200

        defer func() {
            opsDuration.WithLabelValues("https://dev.to/", fmt.Sprint(respCode)).Observe(time.Since(start).Seconds())
        }()

        failQuery := r.URL.Query().Get("fail")

        if failQuery != "" {
            respCode = 500

            isFail, err := strconv.ParseBool(failQuery)
            if err != nil {
                w.WriteHeader(http.StatusInternalServerError)
                w.Write([]byte("error parse query"))

                log.Println("error parse query")

                opsProcessed.WithLabelValues("https://dev.to/", fmt.Sprint(http.StatusInternalServerError)).Inc()

                return
            }

            if isFail {
                w.WriteHeader(http.StatusInternalServerError)
                w.Write([]byte("encounter fail"))

                log.Println("encounter fail")

                opsProcessed.WithLabelValues("https://dev.to/", fmt.Sprint(http.StatusInternalServerError)).Inc()

                return
            }
        }

        w.Write([]byte("Hello, World!"))

        opsProcessed.WithLabelValues("https://dev.to/", fmt.Sprint(http.StatusOK)).Inc()
    })
    http.Handle("/metrics", promhttp.Handler())

    log.Println("Starting server on :9320")
    if err := http.ListenAndServe(":9320", nil); err != nil {
        log.Fatalf("could not start server: %v\n", err)
    }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

یادداشت کردن روش WithLabelValues() هنگام تماس opsProcessed یا opsDurationبشر ما استدلال را پر می کنیم روش با آن / وت رمز پاسخ، زیرا وقتی شروع می کنیم opsProcessed وت opsDuration، ما برچسب را تعریف می کنیم URL وت statusبشر اگر میزان استدلال باشد روش این کمتر از 2 است ، خطایی رخ خواهد داد (خطا).

دویدن سرور استفاده کردن go run main.go، باز مرورگر، و به سمت http://localhost:9320/ یا http://localhost:9320?fail=true، بعد از آن دسترسی را امتحان کنید http://localhost:9320/metricsبشر از نقطه پایانی metrics ما می توانیم معیارها و برچسب هایی را که در عملکرد تعریف کرده ایم ببینیم setMeter() به شرح زیر

معیارهای نقطه پایانی

ما برای انجام تجسم از Docker و Prometheus استفاده خواهیم کرد پرسش معیارهایی که ما ساخته ایم.

با استفاده از پرومتئوس در Docker

قبل از اینکه انجام دهیم پرسش و با ایجاد تجسم ، Dockerfile را از برنامه GO که ایجاد کرده ایم ، خواهیم ساخت. اینجا Docker است.

# Dockerfile

FROM golang:1.22-alpine AS build
ARG APP_VERSION=latest

WORKDIR /src/

COPY . /src/.

RUN CGO_ENABLED=0 go build -o /bin/go-loki ./main.go

# final - service
FROM alpine as api-service

COPY --from=build /bin/go-loki /bin/go-loki

# HTTP Port
EXPOSE 9320

ENTRYPOINT ["/bin/go-loki"]
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

سپس آن را انجام دهید پرونده پیکربندی برای پرومتئوس با نام prometheus.ymlبشر ما تعریف خواهیم کرد که چه برنامه هایی خواهد بودخراش توسط پرومتئوس استفاده پرونده پیکربندی این مطالب زیر prometheus.ymlبشر

# prometheus.yml

global:
  scrape_interval: 3s

scrape_configs:
  - job_name: prometheus
    static_configs:
      - targets: 
        - "localhost:9090"

  - job_name: app 
    metrics_path: /metrics
    static_configs:
      - targets:
        - host.docker.internal:9320
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

به قسمت توجه کنید scrape_configs.static_configs.targetsبشر در آن بخش ، مقادیر را می نویسیم host.docker.internal:9320، جایی که مقدار به برنامه ای که داریم اشاره دارد داک کردن با استفاده از Dockerfile. از آنجا که ما برای اجرای پرومتئوس و برنامه از یک داکر استفاده خواهیم کرد ، از آن استفاده نمی کنیم localhost:9320 به عنوان یک مقدار در بخش scrape_configs.static_configs.targets، بلکه بیشتر host.docker.internal:9320بشر

بعد ، آن را درست کنید پرونده docker-compose.yml توسط محتوای به شرح زیر است.

# docker-compose.yml

version: "3"

volumes:
  prometheus_data:

networks:
  observability:

services:
  prometheus:
    image: prom/prometheus:v2.24.0
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - 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
    restart: always
    networks:
      - observability

  app:
    container_name: app
    build:
      context: .
      dockerfile: ./Dockerfile
    ports:
      - 9320:9320
    networks:
      - observability
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

دویدن docker compose up -d، سپس دسترسی را امتحان کنید http://localhost:9090/targetsبشر خواهیم دید app به عنوان یکی از هدف همانطور که در بخش تعریف کرده ایم scrape_configs.static_configs.targetsبشر

پرومتئوس هدف

سپس ، دسترسی را امتحان کنید زبانه نمودار که در نوار ناوبری، نمایشگر مانند این را خواهیم دید.

نمودار پرومتئوس

در ستون بیان، محتویات را امتحان کنید app_request_total، ما مانند این نتیجه خواهیم گرفت.

نوار جستجوی پرومتئوس

ما کاملاً خواهیم گرفت درخواست که وارد شد نقطه پایانی localhost:9320 با رمز پاسخ متفاوت رمز پاسخ 500 هنگامی که پرسش fail در نقطه پایانی ارزشمند trueوت 200 وقتی ارزش دارد false یا اصلاً پر نشده است. سپس ، برای به دست آوردن میانگین زمان لازم برای تکمیل درخواست، ما استفاده می کنیم پرسش app_request_duration_sum / app_request_duration_count یا histogram_quantile(0.5, rate(app_request_duration_bucket[10m]))بشر اگر اجرا کنیم ، در پرومتئوس نتایج کم و بیش به دست خواهیم آورد پرسش روی

کمکی

مرجع

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا