واٹرمیل کی ریل ٹائم نگرانی کا استعمال پرومیتھیس کے ذریعے
میٹرکس
واٹرمیل کو پبلشر/سبسکرائبر کے لیے ڈیکوریٹرز اور ہینڈلر کے لیے میڈل ویئر کا استعمال کرکے نگرانی کیا جا سکتا ہے۔ ہم آفیشل Go کی پرومیتھیس کلائنٹ کا استعمال کرتے ہوئے ایک ڈیفالٹ ترتیب فراہم کرتے ہیں۔
components/metrics
پیکیج PrometheusMetricsBuilder
کو بیرونی اشیاء کو اپ ڈیٹ کرنے کیلئے نیک قدرتی ترتیبات فراہم کرتا ہے:
مکمل سورس کوڈ: github.com/ThreeDotsLabs/watermill/components/metrics/builder.go
// ...
// PrometheusMetricsBuilder پبلشرز، سبسکرائبرز، اور ہینڈلرز کو ڈیکوریٹ کرنے کے لیے ترتیبات فراہم کرتا ہے۔
type PrometheusMetricsBuilder struct {
// PrometheusRegistryموجودہ پرومیتھیس رجسٹری میں خالی ہو یا ڈیفالٹ رجسٹری استعمال کرنے کیلئے بھر سکتا ہے۔
PrometheusRegistry prometheus.Registerer
Namespace string
Subsystem string
}
// AddPrometheusRouterMetrics پیغام راولر پر میٹرک میڈل ویئر کو تمام ہینڈلرز میں شامل کرنے کا ایک نیک قدرتی ترتیب ہے۔ یہ ہینڈلرز کے پبلشرز اور سبسکرائبرز کو بھی ڈیکوریٹ کرتا ہے۔
func (b PrometheusMetricsBuilder) AddPrometheusRouterMetrics(r *message.Router) {
// ...
پبلشرز، سبسکرائبرز، اور ہینڈلرز کو ڈیکوریٹ کرنا
اگر آپ واٹرمیل کے راولر کا استعمال کر رہے ہیں (جو زیادہ تر معاملات میں مشورہ کیا جاتا ہے) تو آپ AddPrometheusRouterMetrics
کا موزوں فعل استعمال کر سکتے ہیں تاکہ یہی راولر میں شامل ہونے والے تمام ہینڈلرز کو یہ یقینی بنائے کہ پرومیتھیس رجسٹری کو اپ ڈیٹ کرنے کے لیے ڈیکوریٹ کیا جائے، ان کے پبلشرز اور سبسکرائبرز بھی:
مکمل سورس کوڈ: github.com/ThreeDotsLabs/watermill/components/metrics/builder.go
// ...
// AddPrometheusRouterMetrics پیغام راولر پر میٹرک میڈل ویئر کو تمام ہینڈلرز میں شامل کرنے کا ایک نیک قدرتی ترتیب ہے۔ یہ ہینڈلرز کے پبلشرز اور سبسکرائبرز کو بھی ڈیکوریٹ کرتا ہے۔
func (b PrometheusMetricsBuilder) AddPrometheusRouterMetrics(r *message.Router) {
r.AddPublisherDecorators(b.DecoratePublisher)
r.AddSubscriberDecorators(b.DecorateSubscriber)
r.AddMiddleware(b.NewRouterMiddleware().Middleware)
}
// ...
AddPrometheusRouterMetrics
کا استعمال کا مثال:
مکمل سورس کوڈ: github.com/ThreeDotsLabs/watermill/_examples/basic/4-metrics/main.go
// ...
// ہم نیم اسپیس اور سبسسٹیم خالی چھوڑ دیتے ہیں
metricsBuilder := metrics.NewPrometheusMetricsBuilder(prometheusRegistry, "", "")
metricsBuilder.AddPrometheusRouterMetrics(router)
// ...
اوپر دی گئی کوڈ سنیپٹ میں ہم نے namespace
اور subsystem
پیرامیٹر خالی چھوڑ دیئے ہیں۔ پرومیتھیس کلائنٹ لائبریری ان پیرامیٹرز کا استعمال کرتی ہے تاکہ میٹرک ناموں کو سابق بنائے۔ آپ کو نیم اسپیس یا سبسسٹیم کا استعمال کرنا چاہیے لیکن براہ کرم نوٹ کریں کہ یہ میٹرک ناموں کو متاثر کرے گا، لہذا آپ کو گرافانا ڈیش بورڈ کو مطابقتی طور پر ترتیب دینا ہوگا۔
انفرادی پبلشرز اور سبسکرائبرز بھی PrometheusMetricsBuilder
کے مخصوص ترتیبات کا استعمال کرکے ڈیکوریٹ کیے جا سکتے ہیں:
مکمل سورس کوڈ: github.com/ThreeDotsLabs/watermill/_examples/basic/4-metrics/main.go
// ...
subWithMetrics, err := metricsBuilder.DecorateSubscriber(pubSub)
if err != nil {
panic(err)
}
pubWithMetrics, err := metricsBuilder.DecoratePublisher(pub)
if err != nil {
panic(err)
}
// ...
/میٹرکس Endpoint ناقابل کشف کریں
پرومیتھیوس کے کام کرنے کے اصول کے مطابق، ایک سروس کو ڈیٹا اسکریپ کرنے کے لئے ایک ایچ ٹی ٹی پی اینڈ پوائنٹ کو بیان کرنا ضروری ہوتا ہے۔ عام طور پر، یہ ایک GET اینڈ پوائنٹ ہوتا ہے، اور راستے عموماً /metrics
ہوتے ہیں۔
اس اینڈ پوئنٹ کو فراہم کرنے کے لئے دو آسان فعالیتیں دستیاب ہیں، ایک PPP Prometheus رجسٹری کا استعمال کرتے ہوئے اور دوسرا ایک نیا رجسٹری بھنتیا ہوا ایک رجسٹری کا استعمال کرتے ہوئے:
کامل سورس کوڈ: github.com/ThreeDotsLabs/watermill/components/metrics/http.go
// ...
// CreateRegistryAndServeHTTP دی گئی پتہ پر ایک ایچ ٹی ٹی پی سرور قائم کرتا ہے تاکہ /metrics اینڈ پوائنٹ پر Prometheus کو ظاہر کیا جا سکے۔
// یہ ایک نیا پرومیتھیوس رجسٹری (براۓ میٹرک رجسٹریشن) اور سرور کو بند کرنے کے لئے ایک منسوخ کرنے کی فعالیت دیتا ہے۔
func CreateRegistryAndServeHTTP(addr string) (registry *prometheus.Registry, cancel func()) {
registry = prometheus.NewRegistry()
return registry, ServeHTTP(addr, registry)
}
// ServeHTTP دی گئی پتہ پر ایک ایچ ٹی ٹی پی سرور قائم کرتا ہے تاکہ /metrics اینڈ پوائنٹ پر Prometheus کو ظاہر کیا جا سکے۔
// یہ ایک موجودہ پرومیتھیوس رجسٹری قبول کرتا ہے اور سرور کو بند کرنے کے لئے ایک منسوخ فعالیت دیتا ہے۔
func ServeHTTP(addr string, registry *prometheus.Registry) (cancel func()) {
// ...
یہاں استعمال کرنے کا ایک مثال ہے:
کامل سورس کوڈ: github.com/ThreeDotsLabs/watermill/_examples/basic/4-metrics/main.go
// ...
prometheusRegistry, closeMetricsServer := metrics.CreateRegistryAndServeHTTP(*metricsAddr)
defer closeMetricsServer()
// ہم نام و فرعی قلم خالی چھوڑ دیتے ہیں
metricsBuilder := metrics.NewPrometheusMetricsBuilder(prometheusRegistry, "", "")
metricsBuilder.AddPrometheusRouterMetrics(router)
// ...
مثال ایپلیکیشن
ڈیش بورڈ کی عمل کاری کو سمجھنے کے لئے، آپ میٹرکس مثال پر رجوع کر سکتے ہیں۔
مثال کے README میں دی گئی ہدایات کا مطابقت کریں تاکہ آپ اسے چلائیں اور Grafana میں Prometheus ڈیٹا سورس شامل کر سکیں۔
گرافانہ ڈیش بورڈ
ہم نے Grafana dashboard تیار کی ہے جو مذکورہ بالا میٹرکس نفاذ کو استعمال کرنے کے لئے ہے۔ یہ اندراج، ناکامی کی شرح، اور شائبہ/پروسیسنگ کی دورانیہ کے بارے میں بنیادی معلومات فراہم کرتا ہے۔
اگر آپ یہ ڈیش بورڈ مقامی طور پر دیکھنا چاہتے ہیں، تو آپ مثال ایپلیکیشن استعمال کر سکتے ہیں۔
مزید معلومات کے لئے جو میٹرکس کو Prometheus کو منتقل کیا گیا ہے، وہاں Exported metrics کی تشہیر کریں۔
ڈیش بورڈ درآمد
گرافانہ ڈیش بورڈ درآمد کرنے کے لئے، بائیں مینو سے ڈیش بورڈ/مینج منتخب کریں، پھر +Import
پر کلک کریں۔
ڈیش بورڈ کا یو آر ایل داخل کریں https://grafana.com/dashboards/9777 (یا صرف ایڈی، 9777)، پھر لوڈ کرنے کے لئے کلک کریں۔
پھر ڈیٹا سورس منتخب کریں جو /metrics
اینڈ پوائنٹ کو اسکریپ کرنے کے لئے استعمال ہوا ہو۔ Import
پر کلک کریں اور آپ کا کام ہوگیا!
نکالے گئے میٹرک
نیچے PrometheusMetricsBuilder
کے ذریعہ پرومیتھیوس رجسٹری میں رجسٹرڈ ہونے والے تمام میٹرکس کی فہرست ہے۔
پرومیتھیوس میٹرک کی اقسام کے مزید معلومات کے لئے براہ کرم پرومیتھیوس دستاویز پر رجوع کریں۔
اشیاء | میٹرک | تفصیل | لیبلز/قیمتیں |
---|---|---|---|
سبسکرائبر | subscriber_messages_received_total |
ایک پرومیتھیوس کاؤنٹر۔ سبسکرائبر کون کی گئی پیغاموں کی تعداد شمار کرتا ہے۔ | acked "acked" یا "nacked" ہے۔ |
اگر سبسکرائبر ہینڈلر کے اندر چلتا ہے تو handler_name مقرر کریں؛ ورنہ، " |
|||
subscriber_name سبسکرائبر کی شناخت کرتا ہے۔ اگر یہ fmt.Stringer انٹرفیس پر عمل کرتا ہے تو یہ String() کا نتیجہ ہوگا؛ ورنہ یہ package.structName ہوگا۔ |
|||
ہینڈلر | handler_execution_time_seconds |
ایک پرومیتھیوس ہسٹوگرام۔ مینڈویئر وہ ہینڈلر فنکشن کے انجام ٹائم کو ریکارڈ کرتا ہے جو میڈلوئیر سے گھیرا ہوا ہے۔ | handler_name ہینڈلر کا نام ہے۔ |
success "true" یا "false" ہے، جو یہ بتاتا ہے کہ کیا گھیرے ہوئے ہینڈلر فنکشن نے کوئی خرابی واپس کی ہے یا نہیں۔ |
|||
پبلشر | publish_time_seconds |
ایک پرومیتھیوس ہسٹوگرام۔ ڈیکوریٹ پبلش فنکشن کا انجام ٹائم ریکارڈ کرتا ہے۔ | success "true" یا "false" ہے، جو یہ بتاتا ہے کہ ڈیکوریٹ پبلشر کیا خرابی واپس کرتا ہے یا نہیں۔ |
اگر پبلشر ہینڈلر کے اندر چلتا ہے، تو handler_name مقرر کریں؛ ورنہ، " |
|||
publisher_name پبلشر کی شناخت کرتا ہے۔ اگر یہ fmt.Stringer انٹرفیس پر عمل کرتا ہے تو یہ String() کا نتیجہ ہوگا؛ ورنہ یہ package.structName ہوگا۔ |
اس کے علاوہ، ہر میٹرک کے پاس پرومیتھیوس کی طرف سے ایک node
لیبل ہوتا ہے، جس کی قیمت اس میٹرک سورس کی عینیت کو ظاہر کرتی ہے، اور ایک job
جو پرومیتھیوس کنفیگریشن فائل میں جاب نام مقرر ہوتا ہے۔
نوٹ: جیسا کہ اوپر ذکر ہوا ہے، غیر خالی namespace
یا subsystem
کا استعمال میٹرک نام پریفکس کے نتائج میں آئے گا۔ آپ کو مطابقتی ترتیبات کرنے کی ضرورت ہوسکتی ہے، مثلاً، گرافانا ڈیش بورڈ کی پینل تعریف میں۔
ترتیب دینا
اگر آپ یقین کرتے ہیں کہ کوئی مخصوص میٹرک نظرانداز ہوگیا ہے، تو آپ اس بنیادی نصاب کو آسانی سے توسیع دے سکتے ہیں۔ بہترین طریقہ پرومیتھیوس رجسٹری کا استعمال ہے جو ServeHTTP
میں استعمال ہوتا ہے اور میٹرکس کو بحسب پرومیتھیوس کلائنٹ کی دستاویزات کے مطابق رجسٹر کرتا ہے یہاں۔
ان میٹرکس کو اپ ڈیٹ کرنے کا مختصر طریقہ ڈیکوریٹرز کا استعمال ہے۔ مکمل سورس کوڈ یہاں دستیاب ہے github.com/ThreeDotsLabs/watermill/message/decorator.go۔
// ...
// MessageTransformSubscriberDecorator ایک سبسکرائبر ڈیکوریٹر بناتا ہے جو ہر سبسکرائبر کے ذریعہ گزرنے والے ہر میسج پر تبدیلی کا فنکشن کال کرتا ہے۔
func MessageTransformSubscriberDecorator(transform func(*Message)) SubscriberDecorator {
if transform == nil {
panic("transform function is nil")
}
return func(sub Subscriber) (Subscriber, error) {
return &messageTransformSubscriberDecorator{
sub: sub,
transform: transform,
}, nil
}
}
// MessageTransformPublisherDecorator ایک پبلشر ڈیکوریٹر بناتا ہے جو ہر پبلشر کے ذریعہ گزرنے والے ہر میسج پر تبدیلی کا فنکشن کال کرتا ہے۔
func MessageTransformPublisherDecorator(transform func(*Message)) PublisherDecorator {
if transform == nil {
panic("transform function is nil")
}
return func(pub Publisher) (Publisher, error) {
return &messageTransformPublisherDecorator{
Publisher: pub,
transform: transform,
}, nil
}
}
type messageTransformSubscriberDecorator struct {
// ...
اور/یا راوٹرز میں مڈل ویئر۔
ایک آسان طریقہ یہ ہے کہ فرض کریں کہ ضروری میٹرکس صرف ہینڈلر فنکشنز میں اپ ڈیٹ کریں۔