
مرحبا بالجميع!
أريد أن أطلعك على مدى سهولة كتابة مصدرك لـ Prometheus على Golang وإظهار كيف يمكن القيام بذلك باستخدام مثال لبرنامج صغير يراقب المكان الذي تم تثبيت اتصالات TCP الحالية منه جغرافيًا.
0. إخلاء المسؤولية
أود أن أوضح على الفور ، في البداية ، الخطوط العريضة ، إذا جاز التعبير ، لنطاق هذا المنشور وأقول أنه لا يخبر ، حتى لا تكون هناك أسئلة فيما بعد:
- نعم ، هذا ليس تصورا للعملاء . هذا تصور الاتصالات البعيدة . أي أنه لا يقسم الاتصالات إلى تلك التي بدأ فيها الخادم البعيد الاتصال وتلك التي بدأها هذا الجهاز ، وسيعرض كل شيء على الخريطة - على سبيل المثال ، الخادم الذي يحتوي على المستودع ، حيث يتم تنزيل التحديثات إلى جهازك من الآن.
- نعم ، أفهم أن هناك أدوات إخفاء الهوية على الشبكة تخفي عنوان IP الحقيقي للعميل. الغرض من هذه الأداة ليس تحديد إحداثيات GPS الدقيقة لأي عميل ، ولكن على الأقل الحصول على فكرة عامة عن جغرافيتهم.
- توفر whois معلومات أكثر دقة من بلد عنوان IP ، ولكن هنا تم الاتصال بي عن طريق حد المكوّن الإضافي لـ Grafan ، والذي يجعل البلدان فقط ، وليس المدن.
1. نكتب "نهاية": المصدر على الذهاب
لذا ، فإن أول شيء يتعين علينا القيام به هو كتابة مصدر يقوم بالفعل بجمع البيانات من خادمنا وإرسالها إلى Prometheus. يعد اختيار اللغات أمرًا رائعًا: تمتلك Prometheus مكتبات عملاء لكتابة المصدرين بالعديد من اللغات الشائعة ، لكنني اخترت Go ، أولاً ، لأنها "أصلية" (بما أن Prometheus مكتوب عليها) ، وثانيًا لأنها نفسها أستخدمها في ممارسة DevOps.
حسنًا كلمات الأغاني ، دعنا نبدأ في الترميز. لنبدأ في كتابة "من أسفل إلى أعلى": أولاً ، وظائف تحديد البلد عن طريق IP وقائمة عناوين IP البعيدة ، ثم إرسال كل هذا إلى Prometheus.
1.1. نحدد البلد عن طريق عنوان IP
حسنًا ، هناك كل شيء في الجبهة تمامًا ، لم أتفلسف واستخدمت للتو خدمة freegeoip.net ، التي أصبحت واجهة برمجة التطبيقات الخاصة بها حتى وقت كتابة هذا المقال موقوفة بالفعل ، والآن يعرضون التسجيل مجانًا ويكون بإمكانهم تقديم 10000 طلب في الشهر (وهو ما يكفي لأغراضنا) ) كل شيء بسيط هنا: هناك نقطة نهاية للنموذج http://api.ipstack.com/<IP>?access_key=<API_KEY>
، والتي http://api.ipstack.com/<IP>?access_key=<API_KEY>
ببساطة إلى json مع حقل country_code
الذي نحتاجه - هذا كل ما نحتاجه للتصور.
لذا ، دعنا نكتب حزمة لسحب البلاد عن طريق IP.
نحن نستورد الليبس الضرورية وننشئ هيكلًا يتم فيه فك كائن json الناتج. ... والوظيفة نفسها ، والتي ستعيد لنا رمز البلد. انتبه إلى المعلمة legacy=1
، لا بد لي من استخدامها للتوافق مع الإصدارات السابقة ؛ بالطبع ، إذا كنت تستخدم واجهة برمجة التطبيقات الخاصة بهم ، فاستخدم أحدث إصدار.
سنستخدم هنا حزمة github.com/shirou/gopsutil/net
وفلترة الاتصالات بالحالة ESTABLISHED
، باستثناء عناوين IP المحلية والعناوين من قائمة سوداء مخصصة يمكن تمريرها إلى المصدر عند بدء التشغيل (على سبيل المثال ، لاستبعاد جميع عناوين IP العامة الخاصة بك)
حزمة مع خريطة إرجاع دالة [سلسلة] int: عدد الاتصالات من البلد. 1.3. وأخيرًا ، أرسل كل شيء إلى بروميثيوس
بتعبير أدق ، هو نفسه سيأخذ كل شيء. سنستمع فقط إلى المنفذ ونعطيه المقاييس التي تم جمعها.
باستخدام github.com/prometheus/client_golang/prometheus
بإنشاء مقياس من النوع Gauge
. في الواقع ، يمكنك إنشاء Counter
، عندها فقط سنستخدم rate
عند الاستعلام عن قاعدة البيانات. ربما يكون هذا الأخير أكثر فعالية من وجهة نظر بروميثيوس ، ولكن بينما كنت أكتب هذا المصدر (قبل ستة أشهر) ، كنت قد بدأت للتو في التعرف على بروميثيوس وكان Gauge
كافياً بالنسبة لي:
location = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "job_location", Help: "Location connections number", }, []string{"location"}, )
بعد جمع المقاييس باستخدام الفقرات السابقة ، نقوم بتحديث ناقلنا:
for code, number := range c.ConnectionsByCode { location.With(prometheus.Labels{"location": code}).Set(float64(number)) }
نبدأ كل هذا بحلقة لا نهاية لها في غوروتين منفصل ، ونربط المنفذ في المنفذ الرئيسي وننتظر حتى يأخذ بروميثيوس مقاييسنا:
prometheus.MustRegister(location) http.Handle("/metrics", prometheus.Handler()) log.Fatal(http.ListenAndServe(*addr, nil))
في الواقع ، يمكن عرض جميع التعليمات البرمجية في المستودع على GitHub ، ولا أريد نسخ كل شيء هنا على التوالي.
2. "الواجهة الأمامية": Grafana
لكن أولاً ، بالطبع ، عليك إخبار Prometheus بجمع مقاييسنا:
- job_name: 'GeoIPExporter' scrape_interval: 10s static_configs: - targets: ['127.0.0.1:9300']
(أو استخدام اكتشاف الخدمة ، إذا كان لديك ، على سبيل المثال ، Kubernetes). يمكن إجراء Prometheus لإعادة قراءة التكوين عن طريق إرسال إشارة HUP
:
$ pgrep "^prometheus$" | xargs -i kill -HUP {}
ننتقل إليها في واجهة المستخدم ونتحقق من جمع المقاييس:

حسنًا ، حان دور جرافان الآن. نستخدم المكوّن الإضافي grafana-worldmap-panel
، والذي يجب تثبيته مسبقًا:
$ grafana-cli plugins install grafana-worldmap-panel
بعد ذلك ، انتقل إليها في واجهة المستخدم وانقر على إضافة لوحة -> لوحة Worldmap. في علامة التبويب المقاييس ، أدخل الاستعلام التالي:
sum(job_location) by (location)
وحدد تنسيق وسيلة الإيضاح: {{location}}
. يجب أن يبدو كل شيء مثل هذا:

بعد ذلك ، انتقل إلى علامة التبويب Worldmap وقم بتكوين كل شيء كما في لقطة الشاشة:

هذا كل ما في الأمر! استمتع بخريطتنا.
بهذه الطريقة البسيطة ، يمكنك إنشاء خريطة جميلة للاتصالات في Grafan.
شكرا لاهتمامكم ونتطلع لتعليقاتكم.
تودو
بالطبع ، من أجل استخدام الأداة للغرض المقصود ، تحتاج إلى إكمالها: تصفية عناوين الشبكات الفرعية المحلية وأكثر من ذلك بكثير. بالمناسبة ، إذا كان أي شخص مهتمًا ويريد تطوير هذا المصدر - مرحبًا بك في المستودع على GitHub!
الروابط