
Halo semuanya!
Saya ingin berbagi dengan Anda betapa mudahnya menulis eksportir Anda untuk Prometheus di Golang dan menunjukkan bagaimana ini dapat dilakukan dengan contoh program kecil yang melacak dari mana koneksi TCP saat ini secara geografis diinstal.
0. Penafian
Saya ingin segera, pada awalnya, garis besar, sehingga untuk berbicara, ruang lingkup publikasi ini dan mengatakan bahwa itu tidak memberi tahu, sehingga nanti tidak akan ada pertanyaan:
- Ya, ini bukan visualisasi pelanggan . Ini adalah visualisasi koneksi jarak jauh . Yaitu, itu tidak membagi koneksi menjadi yang di mana server jauh memprakarsai koneksi dan orang-orang yang diprakarsai oleh mesin ini, dan akan menampilkan semua yang ada di peta - misalnya, server dengan repositori, di mana pembaruan sedang diunduh ke mesin Anda dari sekarang.
- Ya, saya mengerti bahwa ada alat anonimisasi pada jaringan yang menyembunyikan IP asli dari klien. Tujuan dari alat ini bukan untuk mengidentifikasi koordinat GPS yang tepat dari klien mana pun, tetapi untuk memiliki setidaknya gambaran umum geografi mereka.
- whois memberikan informasi lebih akurat daripada negara alamat IP, tetapi di sini saya terhubung dengan batas plugin untuk Grafan, yang membuat hanya negara, tetapi bukan kota.
1. Kami menulis "back-end": eksportir di perjalanan
Jadi, hal pertama yang perlu kita lakukan adalah menulis eksportir yang benar-benar akan mengumpulkan data dari server kami dan mengirimkannya ke Prometheus. Pilihan bahasa sangat bagus: Prometheus memiliki perpustakaan klien untuk menulis eksportir dalam banyak bahasa populer, tetapi saya memilih Go, pertama, karena sangat "lebih asli" (karena Prometheus ditulis di atasnya), dan kedua karena itu sendiri Saya gunakan dalam latihan DevOps saya.
Cukup lirik, mari kita turun ke kode. Mari kita mulai menulis "bottom-up": pertama, fungsi untuk menentukan negara berdasarkan IP dan daftar alamat IP jarak jauh, dan kemudian mengirimkan semuanya ke Prometheus.
1.1. Kami menentukan negara berdasarkan alamat IP
Ya, benar-benar semuanya ada di dahi, saya tidak berfilosofi dan hanya menggunakan layanan freegeoip.net , API yang pada saat penulisan artikel ini sudah menjadi usang, dan sekarang mereka menawarkan untuk mendaftar secara gratis dan dapat membuat 10.000 permintaan per bulan (yang cukup untuk tujuan kita) ) Semuanya sederhana di sini: ada titik akhir dari formulir http://api.ipstack.com/<IP>?access_key=<API_KEY>
, yang hanya mengembalikan kita json dengan bidang country_code
yang kita butuhkan - hanya itu yang kita butuhkan untuk visualisasi.
Jadi, mari kita menulis paket untuk menarik negara dengan IP.
Kami mengimpor lib yang diperlukan dan membuat struktur di mana objek json yang dihasilkan akan 'dibongkar'. ... dan fungsinya sendiri, yang akan mengembalikan kode negara kepada kami. Perhatikan legacy=1
parameter legacy=1
, saya harus menggunakannya untuk kompatibilitas mundur; Tentu saja, jika Anda menggunakan API mereka, gunakan versi terbaru.
Di sini kita akan menggunakan paket github.com/shirou/gopsutil/net
dan menyaring koneksi dengan status ESTABLISHED
, tidak termasuk alamat IP lokal dan alamat dari daftar hitam khusus yang dapat diteruskan ke eksportir saat startup (misalnya, untuk mengecualikan semua alamat IP publik Anda sendiri)
Paket dengan fungsi mengembalikan peta [string] int: jumlah koneksi dari negara. 1.3. Dan akhirnya, kirim semuanya ke Prometheus
Lebih tepatnya, dia sendiri yang akan mengambil semuanya. Kami hanya akan mendengarkan port dan memberikannya metrik yang dikumpulkan.
Menggunakan github.com/prometheus/client_golang/prometheus
membuat metrik tipe Gauge
. Sebenarnya, Anda bisa membuat Counter
, saat itu kami akan menggunakan rate
ketika meminta basis data. Mungkin yang terakhir ini lebih efektif dari sudut pandang Prometheus, tetapi ketika saya menulis eksportir ini (enam bulan lalu) saya baru saja mulai berkenalan dengan Prometheus dan Gauge
sudah cukup bagi saya:
location = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "job_location", Help: "Location connections number", }, []string{"location"}, )
Setelah mengumpulkan metrik menggunakan paragraf sebelumnya, kami memperbarui vektor kami:
for code, number := range c.ConnectionsByCode { location.With(prometheus.Labels{"location": code}).Set(float64(number)) }
Kami memulai semua ini dengan loop tanpa akhir di goroutine terpisah, dan hanya mengikat port di yang utama dan menunggu Prometheus untuk mengambil metrik kami:
prometheus.MustRegister(location) http.Handle("/metrics", prometheus.Handler()) log.Fatal(http.ListenAndServe(*addr, nil))
Sebenarnya, semua kode dapat dilihat di repositori di GitHub , saya tidak ingin menyalin semuanya di sini dalam satu baris.
2. "Front-end": Grafana
Tapi pertama-tama, tentu saja, Anda perlu memberi tahu Prometheus untuk mengumpulkan metrik kami:
- job_name: 'GeoIPExporter' scrape_interval: 10s static_configs: - targets: ['127.0.0.1:9300']
(atau menggunakan penemuan layanan, jika Anda memiliki, misalnya, Kubernetes). Prometheus dapat dibuat untuk membaca ulang konfigurasi dengan mengirimkannya sinyal HUP
:
$ pgrep "^prometheus$" | xargs -i kill -HUP {}
Kami melakukannya di UI dan memeriksa apakah metrik telah dikumpulkan:

Oke, sekarang giliran Grafan. Kami menggunakan grafana-worldmap-panel
, yang harus diinstal sebelumnya:
$ grafana-cli plugins install grafana-worldmap-panel
Selanjutnya, buka dia di UI dan klik add panel -> Worldmap Panel. Di tab Metrik, masukkan kueri berikut:
sum(job_location) by (location)
Dan tentukan format legenda: {{location}}
. Semuanya akan terlihat seperti ini:

Selanjutnya, buka tab Worldmap dan konfigurasikan semuanya seperti pada tangkapan layar:

Dan itu saja! Nikmati peta kami.
Sedemikian sederhana, Anda dapat membuat peta koneksi yang indah di Grafan.
Terima kasih atas perhatian Anda dan nantikan komentar Anda.
Todo
Tentu saja, untuk menggunakan alat untuk tujuan yang dimaksudkan, Anda harus melengkapinya: menyaring alamat subnet lokal dan banyak lagi. Ngomong-ngomong, jika ada yang tertarik dan ingin mengembangkan eksportir ini - selamat datang di repositori di GitHub!
Tautan