監控宿主機器的一些基礎指標,並寫入到 influxdb 用於以後的可視化以及報警服務linux
監控的指標包括:cpu利用率,cpu負載,內存使用,網絡負載,iops,磁盤等git
主要分爲兩大模塊,reporter
,collector
和 scheduler
github
collector
: 負責具體的某些監控指標的採集reporter
: 負責將採集到的指標寫入到數據庫scheduler
: 負責整個流程的調度,數據採集和數據寫入的協同collector
將採集到的數據寫到 channel
裏,monitor
從 channel
中讀取採集到的數據批量寫入到 influxdb
中,整個過程的系統由 scheduler
來調度golang
type Metric struct { Keys map[string]string `json:"keys"` Vals map[string]interface{} `json:"vals"` Timestamp time.Time `json:"timestamp"` }
metric 是指標數據的抽象,包含三個字段數據庫
Keys
: 指標的維度,對應 influxdb 中的 tag,主要用於查詢時對數據進行分類,目前只有 host 在該字段中,後面能夠按需添加新的字段Vals
: 指標的值,對應 influxdb 中的 field,用於記錄指標具體的值,一條數據中能夠有多個指標,好比 cpu 利用率就有 system/user/idle 三個值,Vals
被設計成 map[string]interface{}
主要是爲了和 influxdb 提供的接口對其,目前只有 float64 類型Timestamp
: 指標採集的時間,因爲數據是批量發送,剛生成的數據可能會等待下一條數據一塊兒打包發送,這個時間間隔可能較長,所以在每條數據裏面加上這條數據產生的時間戳,一塊兒發送給 influxdbtype Collector interface { Collect() []*Metric }
全部的數據採集過程抽象成一個 collector
接口,在整個工做流中,這個接口會被週期性調用,每次調用返回一條或多條 metric 數據(目前僅有一條,但可見的拓展需求,好比多網卡或多磁盤的監控就可能返回多條數據)json
func NewCollector(name string, params []interface{}) (Collector, error)
再提供一個工廠方法,經過類名和參數來構造 collectorcentos
type MetricItem struct { Table string Metric *collector.Metric } type Reporter interface { Report([]*MetricItem) error }
具體某條數據的寫入到哪一個表中,由 scheduler
經過 MetricItem
告知 reporter
api
reporter
提供一個 Report
供 scheduler 調用,將 mertic 數據打包寫入到數據庫網絡
func (s *Scheduler) SetReporter(r reporter.Reporter) func (s *Scheduler) AddCollector(c collector.Collector, table string, interval time.Duration) func (s *Scheduler) Scheduler() func (s *Scheduler) Stop()
主要提供三個接口centos7
SetReporter
: 設置 reporter
,目前只有 influxdb 一個 reporter
,目前一個 scheduler
中只有一個 reporter
AddCollector
: 新增 collector
,一個 scheduler
能夠有多個 collecotr
Scheduler
: 開始調度,這裏會建立數據採集和數據寫入協程,經過 channel 實現協程之間的通訊Stop
: 調度結束,中止全部數據採集協程,發送隊列中全部剩餘的數據,而後退出collector
,reporter
,scheduler
對象scheduler.AddCollector
,scheduler.SetReporter
將 collector
和 reporter
對象關聯到 scheduler
中scheduler.Scheduler
開始調度,這裏將建立週期執行的 collector 協程,以及負責數據寫入的 reporter 協程c := NewCollector() r := NewReporter() s := NewScheduler() s.AddCollector(c) s.SetReporter(r) s.Scheduler() s.Stop()
這是一個典型的生成者消費者問題,多個生成者 collector
往一個 channel
中寫入,一個消費者 reporter
從 channel
中消費數據
須要注意的是,執行退出時,須要將隊列中數據消費完,正確的執行順序應該爲:
collector
中止寫入collector
退出channel
reporter
退出s.stop = true s.collectorWG.Wait() close(s.metricQueue) s.reporterWG.Wait()
這裏使用兩個 sync.WaitGroup
來同步,分別用於等待 collector
和 reporter
目前主要有 cpu利用率,cpu負載,內存使用,網絡負載,iops,磁盤這些數據的採集,主要使用 github.com/mackerelio/go-osstat
相關接口,這個庫對各個操做系統的監控做了封裝,並提供了統一的便可,linux 下實現基本都是解析 /proc
目錄下系統文件的數據
cpu 利用率
github.com/mackerelio/go-osstat/cpu
下的 Get
接口返回當前總的 cpu 時間(user/system/idle),須要在每次調用減去上一次調用的值,能夠獲得這段時間以內 cpu 時間,這段時間內 user/system/idle 與 total 的比值就是 cpu 利用率
結果應該與 top
命令觀察結果一致
cpu 負載
github.com/mackerelio/go-osstat/loadavg
下的 Get
接口返回 1分鐘,5分鐘,15分鐘內的平均負載,所以直接返回這個接口便可
結果應該與 uptime
命令觀察結果一致
內存使用
github.com/mackerelio/go-osstat/memory
下的 Get
接口返回當前內存的使用狀況,直接返回這個接口便可
結果應該與 free
命令觀察結果一致
網絡負載
github.com/mackerelio/go-osstat/network
下的 Get
接口返回各個網卡下的網絡流量(包括一些虛擬網卡),這裏咱們只關注外網的流量,這個設備名通常是 eth0,centos7 爲了支持多個網卡設備名的惟一性,改爲了以 en
開頭的網卡,所以咱們須要從返回的數據中找到以 en
開頭的那個那個網卡,返回對應的數據
結果應該和 netstat -i
命令觀察結果一致
iops
github.com/mackerelio/go-osstat/disk
下的 Get
接口返回各個磁盤設備總的 io 次數,這裏咱們服務的磁盤,通常是 sda
,所以須要先找到 sda
,再減去上次的 io 次數,除以時間獲得 iops
磁盤大小
磁盤大小監控直接使用 golang 系統的 api 便可
stats := &syscall.Statfs_t{} _ = syscall.Statfs("/home", stats)
轉載請註明出處
本文連接: https://tech.hatlonely.com/article/65