廣義上講全部能夠向Prometheus提供監控樣本數據的程序均可以被稱爲一個Exporter。而Exporter的一個實例稱爲target,以下所示,Prometheus經過輪詢的方式按期從這些target中獲取樣本數據:node
社區提供的linux
Prometheus社區提供了豐富的Exporter實現,涵蓋了從基礎設施,中間件以及網絡等各個方面的監控功能。這些Exporter能夠實現大部分通用的監控需求。下表列舉一些社區中經常使用的Exporter:ios
範圍 | 經常使用Exporter |
---|---|
數據庫 | MySQL Exporter, Redis Exporter, MongoDB Exporter, MSSQL Exporter等 |
硬件 | Apcupsd Exporter,IoT Edison Exporter, IPMI Exporter, Node Exporter等 |
消息隊列 | Beanstalkd Exporter, Kafka Exporter, NSQ Exporter, RabbitMQ Exporter等 |
存儲 | Ceph Exporter, Gluster Exporter, HDFS Exporter, ScaleIO Exporter等 |
HTTP服務 | Apache Exporter, HAProxy Exporter, Nginx Exporter等 |
API服務 | AWS ECS Exporter, Docker Cloud Exporter, Docker Hub Exporter, GitHub Exporter等 |
日誌 | Fluentd Exporter, Grok Exporter等 |
監控系統 | Collectd Exporter, Graphite Exporter, InfluxDB Exporter, Nagios Exporter, SNMP Exporter等 |
其餘 | Blockbox Exporter, JIRA Exporter, Jenkins Exporter, Confluence Exporter等 |
用戶自定義的nginx
除了直接使用社區提供的Exporter程序之外,用戶還能夠基於Prometheus提供的Client Library建立本身的Exporter程序,目前Promthues社區官方提供了對如下編程語言的支持:Go、Java/Scala、Python、Ruby。同時還有第三方實現的如:Bash、C++、Common Lisp、Erlang,、Haskeel、Lua、Node.js、PHP、Rust等。git
從Exporter的運行方式來說,又能夠分爲
github
以咱們已經使用過的Node Exporter爲例,因爲操做系統自己並不直接支持Prometheus,同時用戶也沒法經過直接從操做系統層面上提供對Prometheus的支持。所以,用戶只能經過獨立運行一個程序的方式,經過操做系統提供的相關接口,將系統的運行狀態數據轉換爲可供Prometheus讀取的監控數據。 除了Node Exporter之外,好比MySQL Exporter、Redis Exporter等都是經過這種方式實現的。 這些Exporter程序扮演了一箇中間代理人的角色。正則表達式
爲了可以更好的監控系統的內部運行狀態,有些開源項目如Kubernetes,ETCD等直接在代碼中使用了Prometheus的Client Library,提供了對Prometheus的直接支持。這種方式打破的監控的界限,讓應用程序能夠直接將內部的運行狀態暴露給Prometheus,適合於一些須要更多自定義監控指標需求的項目。docker
全部的Exporter程序都須要按照Prometheus的規範,返回監控的樣本數據。以Node Exporter爲例,當訪問/metrics地址時會返回如下內容:shell
# HELP node_cpu Seconds the cpus spent in each mode. # TYPE node_cpu counter node_cpu{cpu="cpu0",mode="idle"} 362812.7890625 # HELP node_load1 1m load average. # TYPE node_load1 gauge node_load1 3.0703125
這是一種基於文本的格式規範,在Prometheus 2.0以前的版本還支持Protocol buffer規範。相比於Protocol buffer文本具備更好的可讀性,以及跨平臺性。Prometheus 2.0的版本也已經再也不支持Protocol buffer。數據庫
Exporter返回的樣本數據,主要由三個部分組成:樣本的通常註釋信息(HELP),樣本的類型註釋信息(TYPE)和樣本。Prometheus會對Exporter響應的內容逐行解析:
若是當前行以# HELP開始,Prometheus將會按照如下規則對內容進行解析,獲得當前的指標名稱以及相應的說明信息:
# HELP <metrics_name> <doc_string>
若是當前行以# TYPE開始,Prometheus會按照如下規則對內容進行解析,獲得當前的指標名稱以及指標類型:
# TYPE <metrics_name> <metrics_type>
TYPE註釋行必須出如今指標的第一個樣本以前。若是沒有明確的指標類型須要返回爲untyped。 除了# 開頭的全部行都會被視爲是監控樣本數據。 每一行樣本須要知足如下格式規範:
metric_name [ "{" label_name "=" `"` label_value `"` { "," label_name "=" `"` label_value `"` } [ "," ] "}" ] value [ timestamp ]
其中metric_name和label_name必須遵循PromQL的格式規範要求。value是一個float格式的數據,timestamp的類型爲int64(從1970-01-01 00:00:00以來的毫秒數),timestamp爲可選默認爲當前時間。具備相同metric_name的樣本必須按照一個組的形式排列,而且每一行必須是惟一的指標名稱和標籤鍵值對組合。
須要特別注意的是對於histogram和summary類型的樣本。須要按照如下約定返回樣本數據:
1 . 類型爲summary或者histogram的指標x,該指標全部樣本的值的總和須要使用一個單獨的x_sum指標表示
2 . 類型爲summary或者histogram的指標x,該指標全部樣本的總數須要使用一個單獨的x_count指標表示。
3 . 對於類型爲summary的指標x,其不一樣分位數quantile所表明的樣本,須要使用單獨的x{quantile="y"}表示。
4 . 對於類型histogram的指標x爲了表示其樣本的分佈狀況,每個分佈須要使用x_bucket{le="y"}表示,其中y爲當前分佈的上位數。同時必須包含一個樣本x_bucket{le="+Inf"},而且其樣本值必須和x_count相同。
5 . 對於histogram和summary的樣本,必須按照分位數quantile和分佈le的值的遞增順序排序。
如下是類型爲histogram和summary的樣本輸出示例
# A histogram, which has a pretty complex representation in the text format: # HELP http_request_duration_seconds A histogram of the request duration. # TYPE http_request_duration_seconds histogram http_request_duration_seconds_bucket{le="0.05"} 24054 http_request_duration_seconds_bucket{le="0.1"} 33444 http_request_duration_seconds_bucket{le="0.2"} 100392 http_request_duration_seconds_bucket{le="+Inf"} 144320 http_request_duration_seconds_sum 53423 http_request_duration_seconds_count 144320 # Finally a summary, which has a complex representation, too: # HELP rpc_duration_seconds A summary of the RPC duration in seconds. # TYPE rpc_duration_seconds summary rpc_duration_seconds{quantile="0.01"} 3102 rpc_duration_seconds{quantile="0.05"} 3272 rpc_duration_seconds{quantile="0.5"} 4773 rpc_duration_seconds_sum 1.7560473e+07 rpc_duration_seconds_count 2693
指定樣式格式的版本
在Exporter響應的HTTP頭信息中,能夠經過Content-Type指定特定的規範版本,例如:
HTTP/1.1 200 OK Content-Encoding: gzip Content-Length: 2906 Content-Type: text/plain; version=0.0.4 Date: Sat, 17 Mar 2018 08:47:06 GMT
其中version用於指定Text-based的格式版本,當沒有指定版本的時候,默認使用最新格式規範的版本。同時HTTP響應頭還須要指定壓縮格式爲gzip。
Docker是一個開源的應用容器引擎,讓開發者能夠打包他們的應用以及依賴包到一個可移植的容器中,而後發佈到任何流行的Linux/Windows/Mac機器上。容器鏡像正成爲一個新的標準化軟件交付方式。
例如,能夠經過一下命令快速在本地啓動一個Nginx服務:
# 安裝一些必要的系統工具 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 # 添加軟件源信息 # docker 官方源 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 阿里雲源 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo sudo yum makecache fast # CentOS7安裝 Docker-ce yum -y install docker-ce mkdir /etc/docker vim /etc/docker/daemon.json { "registry-mirrors": ["https://registry.docker-cn.com"] } # 啓動Docker後臺服務 systemctl start docker && systemctl enable docker systemctl daemon-reload # 守護進程重啓 # 運行一個nginx作測試 docker run -itd nginx
爲了可以獲取到Docker容器的運行狀態,用戶能夠經過Docker的stats命令獲取到當前主機上運行容器的統計信息,能夠查看容器的CPU利用率、內存使用量、網絡IO總量以及磁盤IO總量等信息。
docker stats CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS 9a1648bec3b2 0.30% 196KiB / 3.855GiB 0.00% 828B / 0B 827kB / 0B 1 # 除了使用命令之外,用戶還能夠經過docker提供的http api查看容器的監控統計信息.
使用CAdvisor
CAdvisor是Google開源的一款用於展現和分析容器運行狀態的可視化工具。經過在主機上運行CAdvisor用戶能夠輕鬆的獲取到當前主機上容器的運行統計信息,並以圖表的形式向用戶展現。
在本地運行CAdvisor也很是簡單,直接運行一下命令便可:
docker run \ --volume=/:/rootfs:ro \ --volume=/var/run:/var/run:rw \ --volume=/sys:/sys:ro \ --volume=/var/lib/docker/:/var/lib/docker:ro \ --publish=8080:8080 \ --detach=true \ --name=cadvisor \ google/cadvisor:latest # 經過訪問http://localhost:8080能夠查看,當前主機上容器的運行狀態.
CAdvisor是一個簡單易用的工具,相比於使用Docker命令行工具,用戶不用再登陸到服務器中便可以可視化圖表的形式查看主機上全部容器的運行狀態。
而在多主機的狀況下,在全部節點上運行一個CAdvisor再經過各自的UI查看監控信息顯然不太方便,同時CAdvisor默認只保存2分鐘的監控數據。好消息是CAdvisor已經內置了對Prometheus的支持。訪問http://localhost:8080/metrics便可獲取到標準的Prometheus監控樣本輸出:
下面列舉了一些CAdvisor中獲取的典型監控指標
指標名稱 | 類型 | 含義 |
---|---|---|
gauge | 再過去10秒內容器CPU的平均負載 | |
container_cpu_usage_seconds_total |
指標名稱 | 類型 | 含義 |
---|---|---|
container_cpu_load_average_10s | gauge | 過去10秒內容器CPU的平均負載 |
container_cpu_usage_seconds_total | counter | 容器在每一個CPU內核上的累積佔用時間 (單位:秒) |
container_cpu_system_seconds_total | counter | System CPU累積佔用時間(單位:秒) |
container_cpu_user_seconds_total | counter | User CPU累積佔用時間(單位:秒) |
container_fs_usge_bytes | gauge | 容器中文件系統的使用量(單位:字節) |
container_network_receive_bytes_total | counter | 容器網絡累計接受數據總量(單位: 字節) |
container_network_transmit_bytes_total | counter | 容器網絡累計傳輸數據總量(單位: 字節) |
修改/etc/prometheus/prometheus.yml,將cAdvisor添加監控數據採集任務目標當中:
- job_name: 'docker' static_configs: - targets: ['172.19.0.27:8080'] systemctl restart prometheus
啓動Prometheus服務,能夠在Prometheus UI中看到當前全部的Target狀態:
當可以正常採集到cAdvisor的樣本數據後,能夠經過一下表達式計算容器的CPU使用率.
sum(irate(container_cpu_usage_seconds_total{image!=""}[1m])) without (cpu)
查詢容器內存使用量(單位: 字節)
container_memory_usage_bytes{image!=""}
查詢容器網絡接收量速率(單位: 字節/秒)
sum(rate(container_network_receive_bytes_total{image!=""}[1m])) without (interface)
查詢容器網絡傳輸量速率
sum(rate(container_network_transmit_bytes_total{image!=""}[1m])) without (interface)
查詢容器文件系統讀取速率
sum(rate(container_fs_reads_bytes_total{image!=""}[1m])) without (device) # 爲了方便看出效果,咱們使用dd命令 docker exec -it 628d /bin/bash dd if=/dev/zero of=test bs=1M count=1000
sum(rate(container_fs_writes_bytes_total{image!=""}[1m])) without (device)
接下來咱們主要介紹Prometheus下如何進行白盒監控,咱們以前監控主機的資源用量、容器的運行狀態、數據庫中間件的運行數據。 這些都是支持業務和服務的基礎設施,經過白盒可以瞭解其內部的實際運行狀態,經過對監控指標的觀察可以預判可能出現的問題,從而對潛在的不肯定因素進行優化。而從完整的監控邏輯的角度,除了大量的應用白盒監控之外,還應該添加適當的黑盒監控。
黑盒監控即以用戶的身份測試服務的外部可見性,常見的黑盒監控包括HTTP探針、TCP探針等用於檢測站點或者服務的可訪問性,以及訪問效率等。黑盒監控相較於白盒監控最大的不一樣在於黑盒監控是以故障爲導向當故障發生時,黑盒監控能快速發現故障,而白盒監控則側重於主動發現或者預測潛在的問題。一個完善的監控目標是要可以從白盒的角度發現潛在問題,可以在黑盒的角度快速發現已經發生的問題。
Blackbox Exporter是Prometheus社區提供的官方黑盒監控解決方案,其容許用戶經過:HTTP、HTTPS、DNS、TCP以及ICMP的方式對網絡進行探測。用戶能夠直接使用go get命令獲取Blackbox Exporter源碼並生成本地可執行文件:
wget https://github.com/prometheus/blackbox_exporter/releases/download/v0.16.0/blackbox_exporter-0.16.0.linux-amd64.tar.gz
tar xvf blackbox_exporter-0.16.0.linux-amd64.tar.gz -C /usr/local/prometheus/ mv blackbox_exporter-0.16.0.linux-amd64/ blackbox_exporter useradd prometheus chown -R prometheus:prometheus /usr/local/prometheus/ vim /usr/lib/systemd/system/blackbox_exporter.service [Unit] Description=blackbox_exporter After=network.target [Service] Type=simple User=prometheus ExecStart=/usr/local/prometheus/blackbox_exporter/blackbox_exporter --config.file=/usr/local/prometheus/blackbox_exporter/blackbox.yml Restart=on-failure [Install] WantedBy=multi-user.target systemctl enable blackbox_exporter.service systemctl start blackbox_exporter.service
運行Blackbox Exporter時,須要用戶提供探針的配置信息,這些配置信息多是一些自定義的HTTP頭信息,也多是探測時須要的一些TSL配置,也多是探針自己的驗證行爲。在Blackbox Exporter每個探針配置稱爲一個module,而且以YAML配置文件的形式提供給Blackbox Exporter。 每個module主要包含如下配置內容,包括探針類型(prober)、驗證訪問超時時間(timeout)、以及當前探針的具體配置項:
# 探針類型:http、 tcp、 dns、 icmp. prober: <prober_string> # 超時時間 [ timeout: <duration> ] # 探針的詳細配置,最多隻能配置其中的一個 [ http: <http_probe> ] [ tcp: <tcp_probe> ] [ dns: <dns_probe> ] [ icmp: <icmp_probe> ]
下面是一個簡化的探針配置文件blockbox.yml,包含兩個HTTP探針配置項
modules: http_2xx: prober: http http: method: GET http_post_2xx: prober: http http: method: POST
經過運行一下命令,並指定使用的探針設置文件啓動Blockbox Exporter實例:
blackbox_exporter --config.file=/etc/prometheus/blackbox.yml or systemctl restart blackbox_exporter.service
啓動成功後,就能夠經過訪問http://172.19.0.27:9115/probe?module=http_2xx&target=baidu.com對baidu.com進行探測。這裏經過在URL中提供module參數指定了當前使用的探針,target參數指定探測目標,探針的探測結果經過Metrics的形式返回:
# HELP probe_dns_lookup_time_seconds Returns the time taken for probe dns lookup in seconds # TYPE probe_dns_lookup_time_seconds gauge probe_dns_lookup_time_seconds 0.004359875 # HELP probe_duration_seconds Returns how long the probe took to complete in seconds # TYPE probe_duration_seconds gauge probe_duration_seconds 0.046153996 # HELP probe_failed_due_to_regex Indicates if probe failed due to regex # TYPE probe_failed_due_to_regex gauge probe_failed_due_to_regex 0 # HELP probe_http_content_length Length of http content response # TYPE probe_http_content_length gauge probe_http_content_length 81 # HELP probe_http_duration_seconds Duration of http request by phase, summed over all redirects # TYPE probe_http_duration_seconds gauge probe_http_duration_seconds{phase="connect"} 0.00105657 probe_http_duration_seconds{phase="processing"} 0.039457402 probe_http_duration_seconds{phase="resolve"} 0.004359875 probe_http_duration_seconds{phase="tls"} 0 probe_http_duration_seconds{phase="transfer"} 0.000337184 # HELP probe_http_last_modified_timestamp_seconds Returns the Last-Modified HTTP \ response header in unixtime # TYPE probe_http_last_modified_timestamp_seconds gauge probe_http_last_modified_timestamp_seconds 1.26330408e+09 # HELP probe_http_redirects The number of redirects # TYPE probe_http_redirects gauge probe_http_redirects 0 # HELP probe_http_ssl Indicates if SSL was used for the final redirect # TYPE probe_http_ssl gauge probe_http_ssl 0 # HELP probe_http_status_code Response HTTP status code # TYPE probe_http_status_code gauge probe_http_status_code 200 # HELP probe_http_uncompressed_body_length Length of uncompressed response body # TYPE probe_http_uncompressed_body_length gauge probe_http_uncompressed_body_length 81 # HELP probe_http_version Returns the version of HTTP of the probe response # TYPE probe_http_version gauge probe_http_version 1.1 # HELP probe_ip_protocol Specifies whether probe ip protocol is IP4 or IP6 # TYPE probe_ip_protocol gauge probe_ip_protocol 4 # HELP probe_success Displays whether or not the probe was a success # TYPE probe_success gauge probe_success 1
從返回的樣本中,用戶能夠獲取站點的DNS解析耗時,站點響應時間,HTTP響應狀態碼等等和站點訪問質量相關的監控指標,從而幫助管理員主動的發現故障和問題.
接下來,只須要在Prometheus下配置對Blockbox Exporter實例的採集任務便可、最直觀的配置方式.
- job_name: 'baidu_http2xx_probe' params: module: - http_2xx target: - baidu.com metrics_path: /probe static_configs: - targets: ['172.19.0.27:9115'] - job_name: 'prometheus_http2xx_probe' params: module: - http_2xx target: - prometheus.io metrics_path: /probe static_configs: - targets: ['172.19.0.27:9115'] systemctl restart prometheus
這裏分別配置了名爲baidu_http2x_probe和prometheus_http2xx_probe的採集任務,而且經過params指定使用的探針(module)以及探測目標(target).
那問題就來了,假如咱們有N個目標站點且都須要M種探測方式,那麼Prometheus中將包含N * M個採集任務,從配置管理的角度來講顯然是不可接受的。這裏咱們也能夠採用Relabling的方式對這些配置進行簡化,配置方式以下:
- job_name: 'blackbox' metrics_path: /probe params: module: [http_2xx] static_configs: - targets: - http://prometheus.io # Target to probe with http. - https://prometheus.io # Target to probe with https. - http://example.com:8080 # Target to probe with http on port 8080. relabel_configs: - source_labels: [__address__] target_label: __param_target - source_labels: [__param_target] target_label: instance - target_label: __address__ replacement: 172.19.0.27:9115
這裏針對每個探針服務(如http_2xx)定義一個採集任務,而且直接將任務的採集目標定義爲咱們須要探測的站點,在採集樣本數據以前經過relabel_configs對採集任務進行動態配置.
* 第一步, 根據Target實例的地址,寫入__param_target標籤中,__param_<name>形式的標籤來表示, # 在採集任務時會在請求目標地址中添加<name>參數,等同於params的設置. * 第二步, 獲取__param_target的值,並覆寫到instance標籤中. * 第三步, 覆寫Target實例的__address__標籤值爲BlockBox Exporter實例的訪問地址.
HTTP探針是進行黑盒監控時最經常使用的探針之一,經過HTTP探針可以網站或者HTTP服務創建有效的監控,包括其自己的可用性,以及用戶體驗相關的如響應時間等等。除了可以在服務出現異常的時候及時報警,還能幫助系統管理員分析和優化網站體驗。
Blockbox Exporter中全部的探針均是以Module的信息進行配置。以下所示,配置了一個最簡單的HTTP探針:
modules: http_2xx_example: prober: http http:
經過prober配置項指定探針類型。配置項http用於自定義探針的探測方式,這裏有沒對http配置項添加任何配置,表示徹底使用HTTP探針的默認配置,該探針將使用HTTP GET的方式對目標服務進行探測,而且驗證返回狀態碼是否爲2XX,是則表示驗證成功,不然失敗。
HTTP服務一般會以不一樣的形式對外展示,有些可能就是一些簡單的網頁,而有些則多是一些基於REST的API服務。 對於不一樣類型的HTTP的探測須要管理員可以對HTTP探針的行爲進行更多的自定義設置,包括:HTTP請求方法、HTTP頭信息、請求參數等。對於某些啓用了安全認證的服務還須要可以對HTTP探測設置相應的Auth支持。對於HTTPS類型的服務還須要可以對證書進行自定義設置。
以下所示,這裏經過method定義了探測時使用的請求方法,對於一些須要請求參數的服務,還能夠經過headers定義相關的請求頭信息,使用body定義請求內容:
http_post_2xx: prober: http timeout: 5s http: method: POST headers: Content-Type: application/json body: '{}'
若是HTTP服務啓用了安全認證,Blockbox Exporter內置了對basic_auth的支持,能夠直接設置相關的認證信息便可:
http_basic_auth_example: prober: http timeout: 5s http: method: POST headers: Host: "login.example.com" basic_auth: username: "username" password: "mysecret"
對於使用了Bear Token的服務也能夠經過bearer_token配置項直接指定令牌字符串,或者經過bearer_token_file指定令牌文件。
對於一些啓用了HTTPS的服務,可是須要自定義證書的服務,能夠經過tls_config指定相關的證書信息:
http_custom_ca_example: prober: http http: method: GET tls_config: ca_file: "/certs/my_cert.crt"
http_2xx_example: prober: http timeout: 5s http: valid_http_versions: ["HTTP/1.1", "HTTP/2"] valid_status_codes: []
默認狀況下,Blockbox返回的樣本數據中也會包含指標probe_http_ssl,用於代表當前探針是否使用了SSL:
# HELP probe_http_ssl Indicates if SSL was used for the final redirect # TYPE probe_http_ssl gauge probe_http_ssl 0
而若是用戶對於HTTP服務是否啓用SSL有強制的標準。則可使用fail_if_ssl和fail_if_not_ssl進行配置。fail_if_ssl爲true時,表示若是站點啓用了SSL則探針失敗,反之成功。fail_if_not_ssl恰好相反。
http_2xx_example: prober: http timeout: 5s http: valid_status_codes: [] method: GET no_follow_redirects: false fail_if_ssl: false fail_if_not_ssl: false
除了基於HTTP狀態碼,HTTP協議版本以及是否啓用SSL做爲控制探針探測行爲成功與否的標準之外,還能夠匹配HTTP服務的響應內容。使用fail_if_matches_regexp和fail_if_not_matches_regexp用戶能夠定義一組正則表達式,用於驗證HTTP返回內容是否符合或者不符合正則表達式的內容。
http_2xx_example: prober: http timeout: 5s http: method: GET fail_if_matches_regexp: - "Could not connect to database" fail_if_not_matches_regexp: - "Download the latest version here"
最後須要提醒的時,默認狀況下HTTP探針會走IPV6的協議。 在大多數狀況下,可使用preferred_ip_protocol=ip4強制經過IPV4的方式進行探測。在Bloackbox響應的監控樣本中,也會經過指標probe_ip_protocol,代表當前的協議使用狀況:
# HELP probe_ip_protocol Specifies whether probe ip protocol is IP4 or IP6 # TYPE probe_ip_protocol gauge probe_ip_protocol 6
除了支持對HTTP協議進行網絡探測之外,Blackbox還支持對TCP、DNS、ICMP等其餘網絡協議![]