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

عکس توسط دانیل کورپای در Unssplash
چرا نظارت بر برنامه؟
تام ویلکی این روش را معرفی کرد استفاده کردن (استفادهبا اشباعبا خطا) برای اندازه گیری استفاده از سخت افزار مانند سرعت خواندن توسط گرده (I/O) ، استفاده از حافظه و شبکه. اما این روشها عملکرد برنامه و نحوه تعامل کاربران با برنامه ها را نشان نمی دهند. بنابراین ، او این روش را معرفی کرد قرمز (نرخبا خطابا مدت). با استفاده از روش شناسی قرمز، توسعه دهنده می تواند دریابد که مدت زمان بالا نشان می دهد که برنامه به آرامی اجرا می شود یا وقتی جواب می دهد درخواست بیشتر آنها در یک بازه زمانی خاص رخ می دهد.
درباره پرومتئوس
Prometheus یک نرم افزار است که توسط SoundCloud ساخته شده است. از پرومتئوس برای نظارت استفاده می شود (نظارت) عملکرد برنامه و هشدارها (هشدار دهنده) در صورت وجود موانعی در برنامه. پرومتئوس داده های متریک را جمع آوری و ذخیره می کند (معیارها) در قالب سری زمانی (سری زمانی). معیارها با استفاده از یک نشانگر زمان ذخیره می شوند (زمان سنج) همراه با یک برچسب به شکل یک جفت کلید و مقدار (جفت های ارزش کلیدی). پرومتئوس داده های متریک را از برنامه به طور مداوم یا معمولاً به عنوان شناخته می کند مکانیزم کشیدنبشر
موارد زیر یک معماری پرومتئوس است.
پرومتئوس با انجام داده های متریک می گیرد کشیدن یا خراش از هدف پرومتئوس، جایی که این هدف می تواند یک برنامه باشد HTTP یا مجموعه پایگاه دادهبشر پرومتئوس اهداف برنامه را می داند که خواهد بودخراش از طریق کشف خدماتی که می تواند به طور خودکار توسط Kubernetes انجام شود یا هدف خود را با استفاده از آن تعریف می کنیم پرونده پیکربندیبشر معیارهای موفق خراش توسط پرومتئوس می توانیم استفاده کنیم رفیقبشر
متریک پرومتئوس
پرومتئوس 4 معیار دارد که به طور خاص برای اندازه گیری عملکرد برنامه استفاده می شود
-
پیشرو
Counter یک متریک با افزایش ماهیت یکنواخت است ، اما مقدار می تواند به 0 تغییر کند. پیشخوان می تواند برای نظارت درخواست که با موفقیت پردازش شد و تعداد خطاها (خطا). -
سنج
سنج معیار است که فقط می تواند بالا یا پایین برود. از سنج می توان برای نظارت بر مصرف حافظه ، مصرف CPU و مقدار استفاده کرد درخواست که همزمان اتفاق می افتد. -
بافت نگار
هیستوگرام یک متریک است که برخی از مشاهدات را در یک محدوده خاص جمع می کند که می تواند پیکربندی شود. هیستوگرام می تواند برای نظارت بر زمان لازم برای تکمیل درخواست در یک بازه زمانی خاص یا اندازه را کنترل کنید درخواست در یک بازه زمانی خاص -
خلاصه
ابزار برنامه با استفاده از پرومتئوس
موارد زیر یک ساختار است پوشه که ما برای انجام ابزار دقیق با استفاده از یک نقش و داکر استفاده خواهیم کرد.
قبل از دویدن 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]))
بشر اگر اجرا کنیم ، در پرومتئوس نتایج کم و بیش به دست خواهیم آورد پرسش روی
مرجع