使用prometheus自定義監(jiān)控

背景:

目的是監(jiān)控tomcat的cpu和內(nèi)存的,本來(lái)是打算是使用zabbix自發(fā)現(xiàn)去做,但感覺(jué)又要寫模板,又要寫腳本,還要用自動(dòng)化工具推自發(fā)現(xiàn)腳本,而且還擔(dān)心性能也不是很好。所以就打算換種新的監(jiān)控工具,最終選擇了prometheus.

實(shí)施:

1. 第一步就是要安裝prometheus了,我這邊為了保持可通用性和簡(jiǎn)潔,不污染機(jī)器環(huán)境,能用docker安裝的都用docker進(jìn)行安裝(其他的工具也是這樣的)。另外docker安裝比較方便和省心。先上premoethus的docker-compose,安裝docker-compose的可以移步docker-compose安裝


version: '2'

services:

  prometheus:

    image: prom/prometheus:v2.0.0

    ports:

      - "9090:9090"

    volumes:

      - /data/compose_data/prometheus/prometheus:/prometheus   #prometheus數(shù)據(jù)目錄

      - /data/compose_data/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml   #prometheus配置文件

      - /data/compose_data/prometheus/first_rules.yml:/etc/prometheus/first_rules.yml   #報(bào)警配置文件

    command: --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/prometheus --web.console.libraries=/usr/share/prometheus/console_libraries  --web.console.templates=/usr/share/prometheus/consoles --web.external-url=http://{ip或者域名}:9090    #重寫了啟動(dòng)的配置參數(shù),其中web.external-url配置問(wèn)prometheus地址是為了在報(bào)警郵件里面點(diǎn)擊直接到prometheus的web界面

這里需要注意我的配置文件都寫好了,所以直接進(jìn)行volumes映射的。如果是第一次創(chuàng)建容器環(huán)境,請(qǐng)先啟動(dòng)沒(méi)有映射的容器將配置文件取出來(lái),配置好進(jìn)行映射。下面列出配置文件的內(nèi)容:
prometheus.yml:

global:
  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
alerting:
  alertmanagers:
  - static_configs:
    - targets:
       - altermanager:9093   #設(shè)置altermanager的地址,后文會(huì)寫到安裝altermanager
rule_files:
  - "first_rules.yml"   # 設(shè)置報(bào)警規(guī)則
  # - "second_rules.yml"
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: 'prometheus'
    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.
    static_configs:
      - targets: ['localhost:9090']   #這個(gè)自帶的默認(rèn)監(jiān)控prometheus所在機(jī)器的prometheus狀態(tài)
#  - job_name: 'localhost'
#   static_configs:
#      - targets: ['192.168.98.73:9101']   #這部分是監(jiān)控機(jī)器的狀態(tài),需要在機(jī)器節(jié)點(diǎn)啟動(dòng)[node_exporter](https://github.com/prometheus/node_exporter),需要監(jiān)控機(jī)器的可以移步查看
#       labels:
#         instance: localhost
  - job_name: "uat-apps-status"      # 自己定義的監(jiān)控的job_name
    static_configs:
      - targets: ['192.168.98.73:9091']   # 指向pushgateway.  我在每臺(tái)機(jī)器上使用的是推的方式到pushgateway,所以采取了此種方式。
        labels:
          instance: uat    #新添加的標(biāo)簽,可以自定義
    scrape_interval: 60s

這里需要說(shuō)明的是也可以使用metrics的方式讓premetheus去各個(gè)節(jié)點(diǎn)去拉數(shù)據(jù),因?yàn)檫@樣我就需要在監(jiān)控的每個(gè)節(jié)點(diǎn)運(yùn)行web服務(wù)端,所以就改成了推到pushgateway的方式。

first_rules.yml:

groups:
- name: example   #報(bào)警規(guī)則的名字
  rules:

  # Alert for any instance that is unreachable for >5 minutes.
  - alert: InstanceDown     #檢測(cè)job的狀態(tài),持續(xù)1分鐘metrices不能訪問(wèn)會(huì)發(fā)給altermanager進(jìn)行報(bào)警
    expr: up == 0
    for: 1m    #持續(xù)時(shí)間
    labels:
      serverity: page
    annotations:
      summary: "Instance {{ $labels.instance }} down"
      description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."


  - alert: "it's has problem"  #報(bào)警的名字
    expr: "test_tomcat{exported_instance="uat",exported_job="uat-app-status",host="test",instance="uat",job="uat-apps-status"} -  test_tomcat{exported_instance="uat",exported_job="uat-app-status",host="test",instance="uat",job="uat-apps-status"} offset 1w > 5"   # 這個(gè)意思是監(jiān)控該表達(dá)式查詢出來(lái)的值與一周前的值進(jìn)行比較,大于5且持續(xù)10m鐘就發(fā)送給altermanager進(jìn)行報(bào)警
    for: 1m  #持續(xù)時(shí)間
    labels:
      serverity: warning
    annotations:
      summary: "{{ $labels.type }}趨勢(shì)增高"
      description: "機(jī)器:{{ $labels.host }} tomcat_id:{{ $labels.id }} 類型:{{ $labels.type }} 與一周前的差值大于5,當(dāng)前的差值為:{{ $value }}"    #自定義的報(bào)警內(nèi)容

這些是自定義的基本報(bào)警內(nèi)容,具體還可以使用模塊功能,構(gòu)建更詳細(xì)的報(bào)警頁(yè)面,具體可以參考模板使用方法,讀者可以基于自己環(huán)境的情況進(jìn)行配置。

2. 然后就需要安裝上面配置文件用到了altermanger和pushgateway了,這邊同樣使用docker來(lái)安裝。
altermanger的docker-compose:

version: '2'
services:
  altermanager:
    image: prom/alertmanager:master
    volumes:
      - /data/compose_data/prometheus_altermanager/conf/config.yml:/etc/alertmanager/config.yml  #altermanager配置文件
      - /data/compose_data/prometheus_altermanager/data:/altermanager  #altermanager數(shù)據(jù)目錄
    ports:
      - "9093:9093"
    command: -config.file=/etc/alertmanager/config.yml -storage.path=/alertmanager -web.external-url=http://{ip或者域名}:9093   #重寫了啟動(dòng)方式,添加了web.external參數(shù),使報(bào)警郵件點(diǎn)擊可以直接到altermanager web頁(yè)面

這里的配置文件同樣的需要從容器里面導(dǎo)出來(lái)配置好,放到對(duì)應(yīng)的映射目錄的。
confg.yml:

global:
  # The smarthost and SMTP sender used for mail notifications.
  smtp_smarthost: 'smtp.exmail.qq.com:465'  #這里是指smtp的服務(wù)器
  smtp_from: 'test@qq.com'  # 郵箱from地址,一般寫郵箱的用戶名
  smtp_auth_username: 'test@qq.com'  #郵箱的用戶名
  smtp_auth_password: '******'    #郵箱的密碼
  smtp_require_tls: false   # 這個(gè)配置了true導(dǎo)致沒(méi)有報(bào)錯(cuò),最后我設(shè)置成了false正常了
  # The auth token for Hipchat.
  #hipchat_auth_token: '1234556789'
  # Alternative host for Hipchat.
  #hipchat_api_url: 'https://hipchat.foobar.org/'    #這是其他的報(bào)警方式
route:
  group_by: ['host','id','type']    #可以機(jī)器標(biāo)簽進(jìn)行報(bào)警的分組
  group_wait: 30s   #分組等待時(shí)間
  group_interval: 30s    #分組的時(shí)間間隔 
  repeat_interval: 1h     #重復(fù)報(bào)警的時(shí)間間隔
  receiver: 'test-mails'    #發(fā)給定義的name
receivers:
- name: 'test-mails'
  email_configs:
  - to: "test@qq.com"  #收件人地址 想發(fā)送多個(gè)人可以這樣寫test1@qq.com,test2@qq.com

上面只是介紹簡(jiǎn)單的報(bào)警配置,具體可以依據(jù)分組做靜默,分類發(fā)送,按級(jí)別發(fā)送等等,具體配置可以看看docker容器默認(rèn)的配置文件配置方法。
3.接下來(lái)就是pushgateway的docker-compose:

version: '2'
services:
  pushgateway:
    image: prom/pushgateway:master
    ports:
      - "9091:9091"

這個(gè)比較簡(jiǎn)單,我們只是用這個(gè)做監(jiān)控?cái)?shù)據(jù)的中轉(zhuǎn)。
4.配置完成之后依次啟動(dòng)這些容器:

docker-compose -f /data/compose/prometheus_pushgateway/docker-compose.yml up -d
docker-compose -f /data/compose/prometheus_altermanager/docker-compose.yml up -d
docker-compose -f /data/compose/prometheus/docker-compose.yml up -d
如果啟動(dòng)失敗可以使用docker-compose -f 文件 logs 查看錯(cuò)誤詳情進(jìn)行更正

5.啟動(dòng)完成后可以訪問(wèn)相應(yīng)的web頁(yè)面進(jìn)行查看:
premetheus web頁(yè)面:

訪問(wèn) http://{premetheus_ip}:9090
premetheus.png

其中:

  • alters可以查看當(dāng)前報(bào)警的狀態(tài)
  • status->rules可以查看配置的報(bào)警規(guī)則.
  • status->targets可以查看配置的job及狀態(tài)。

altermanger頁(yè)面:

訪問(wèn):http://altermanager:9093
altermanager.png

這里可以基于label設(shè)置告警的靜默期,查看當(dāng)前報(bào)警的內(nèi)容等。郵件里面點(diǎn)擊的連接就是到達(dá)這里。

pushgateway頁(yè)面:

訪問(wèn): http://pushgateway:9091
pushgateway.png

這里可以看到pushgateway的對(duì)應(yīng)的job,已經(jīng)對(duì)應(yīng)job的key及上次收到數(shù)據(jù)的時(shí)間,也可以刪除job的數(shù)據(jù)重新生成。

6.上述步驟都完成后接下來(lái)就需要寫腳本取數(shù)據(jù)到pushgateway了。我這邊給出個(gè)實(shí)例腳本,大家可以根據(jù)此進(jìn)行更改以監(jiān)控自己想要監(jiān)控的數(shù)據(jù)

import requests,time
from get_application_status import get_app_status
# 這個(gè)get_app_status的模塊是自己寫的通過(guò)命令取得tomcat的cpu和內(nèi)存,并返回字典。

def _submit_wrapper(url, job_name, value):
    headers = {'X-Requested-With': 'Python requests', 'Content-type': 'text/xml'}
    requests.post('http://%s/metrics/job/%s' % (url, job_name),
                      data='%s\n' % (value), headers=headers)


def push_metrics(job_name,hostid,instance,url):
    all_app_status = get_app_status()
    tomcat_status = all_app_status.tomcat_status()
    metrice_name = ""
    for tomcat in tomcat_status:
        metrice_name += '%s_tomcat{id="%s",host="%s",type="mem",instance="%s",job="%s"} %s\n'%(hostid,tomcat,hostid,instance,job_name,tomcat_status[tomcat]['mem'])
        metrice_name += '%s_tomcat{id="%s",host="%s",type="cpu",instance="%s",job="%s"} %s\n' % (hostid,tomcat,hostid,instance,job_name,tomcat_status[tomcat]['cpu'])
#重點(diǎn)是這塊將取到的值組成一個(gè)字符串,字符串的格式要符合metrics的標(biāo)準(zhǔn),可以選擇target的一個(gè)metrics進(jìn)行格式查看。這里給出個(gè)實(shí)例:
# uat_tomcat{id="tomcat_1018",host="uat",type="mem",instance="uat",job="uat-app-status"} 3.2
# uat_tomcat{id="tomcat_1018",host="uat",type="cpu",instance="uat",job="uat-app-status"} 2.4
    _submit_wrapper(url=url,job_name=job_name,value=metrice_name) 




if __name__ == "__main__":
    job_name = "{{ job_name }}"  #我這里使用的是ansible批量推的形式運(yùn)行該腳本,所有用了jinja的變量,如果不需要可以直接加此設(shè)置成對(duì)應(yīng)的值運(yùn)行。
    hostid = "{{ hostid }}".replace("-","_")  #這里我發(fā)現(xiàn)type標(biāo)簽的值不支持-,所以就替換成_
    instance = "{{ instance }}"
    url = "{{ url }}"  #這里的地址填寫的是altermanger的地址(algermanger:9091)
    while True:
        push_metrics(job_name=job_name,hostid=hostid,instance=instance,url=url)
        time.sleep(60)   #這里用的是死循環(huán)不斷的取數(shù)據(jù),其實(shí)也可以使用計(jì)劃任務(wù)。

7.接下來(lái)運(yùn)行上面的腳本推到gateway,prometheus就可以取到數(shù)據(jù)了。我這邊再補(bǔ)充下用ansible推的大致yml:
我用的anisible的roles功能:
tasks/main.yml:

---
# tasks file for premethous_client

- name: test dir is exits
  file: path=/root/scripts state=directory

- name: copy service_promethous
  copy: src=service_promethous.sh dest=/root/scripts/service_promethous.sh  #這是自己寫的簡(jiǎn)單啟動(dòng)關(guān)閉該腳本的文件

- name: copy get_application_status
  template: src=get_application_status.py dest=/root/scripts/get_application_status.py   #這是那個(gè)模塊,這個(gè)根據(jù)大家寫的腳本內(nèi)容,可用可不用的。這里就不說(shuō)明了

- name: copy single_gateway
  template: src=single_gateway.py dest=/root/scripts/single_gateway.py  #這是推gateway的腳本,我寫的是以死循環(huán)的方式運(yùn)行,其實(shí)可以用計(jì)劃任務(wù)
  notify:
    - restart prometheus

- name: start prometheus
  shell: sh /root/scripts/service_promethous.sh start
  ignore_errors: True

files/service_promethous.sh:

#!/bin/bash

start(){
  ps aux |grep single_gateway.py | grep python | grep -v grep > /dev/null
  if [ $? -eq 0 ];then
    echo "already start"
    exit 0
  else
    nohup python /root/scripts/single_gateway.py > /dev/null 2>&1 &
  fi
}

stop(){
  num=`ps aux |grep single_gateway.py | grep -v grep | awk  '{print $2}'`
  if [ $num ];then
    kill $num
    echo "stop success..."
  else
    echo "no starting..."
  fi
}

status(){
  ps aux |grep single_gateway.py | grep python | grep -v grep > /dev/null
  if [ $? -eq 0 ];then
    echo "starting...."
  else
    echo "stoping......"
  fi
}

case "$1" in
        start)
                start
                ;;
        stop)
                stop
                ;;
        restart)
                stop
                sleep 2
                start
                ;;
        status)
                status
                ;;
        *)
                echo "only suport start|stop|restart|status"
esac

# 偷懶寫的簡(jiǎn)單的啟動(dòng)關(guān)閉文件,大家看下就好了。

handlers/main.yml:

---
# handlers file for premethous_client
#
- name: restart prometheus
  shell: sh /root/scripts/service_promethous.sh restart  #文件變化重啟腳本的handles

premethous_client.yml:

- hosts: uat_env
  gather_facts: True
  roles:
    - premethous_client
  vars:
    job_name: uat-app-status
    hostid: "{{ ansible_hostname }}"
    instance: uat
    url: altermanager:9091
  tags:
    - uat-premethous

這是執(zhí)行role的playbook,主要就是定義了全局變量替換role的templates。做到不同的機(jī)器推到pushgateway的值的key不一樣。
8.配置完ansible

ansible-playbook premethous_client.yml

指定的機(jī)器就可以就行數(shù)據(jù)的推送了。

注:ansible只是為了方便才做的,其實(shí)可以不做。

9.現(xiàn)在其實(shí)prometheus的監(jiān)控報(bào)警已經(jīng)完成了,這邊我再擴(kuò)展下grafana結(jié)合prometheus展示的使用方法。
按照慣例依然使用docker-compose部署

version: '2'
services:
  grafana:
    image: grafana/grafana:4.6.3
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=123456   #設(shè)置管理員的密碼
    volumes:
      - /data/compose_data/grafana:/var/lib/grafana  #設(shè)置數(shù)據(jù)目錄
    command: cfg:default.smtp.enabled=true cfg:default.smtp.host=smtp.exmail.qq.com:25 cfg:default.smtp.user=test@qq.com cfg:default.smtp.password=***** cfg:default.smtp.from_address=test@qq.com cfg:default.server.root_url=http://{grafna_url或者域名}:3000
#重寫了grafana啟動(dòng)的配置,添加了郵件發(fā)送的功能

啟動(dòng)grafna:

docker-compose -f /data/compose/grafana/docker-compose.yml up -d

訪問(wèn):http://granfana:3000 輸入用戶名密碼登錄

grafana.png

這里有幾個(gè)步驟,添加數(shù)據(jù)源及添加用戶,我就不說(shuō)了,根據(jù)提示可以很輕松的完成。我這里主要介紹dashboard templates的使用,點(diǎn)擊到dashboard然后點(diǎn)擊new,然后點(diǎn)擊齒輪形狀的圖標(biāo),點(diǎn)擊templating,新建variable
templating.png

這里需要注意的是從取到的數(shù)據(jù)顧慮出來(lái)單個(gè)的值要用()包括才能取所有的key值里面取到想要的appid,這里讀者可以嘗試用括號(hào)包裹不同的內(nèi)容進(jìn)行測(cè)試。然后還可以新建variables一個(gè)取相應(yīng)的host。這里根據(jù)實(shí)際環(huán)境做適合自己的配置。我這邊配置的整體效果是這個(gè)樣子的。


status.png

注:在創(chuàng)建graph圖形的時(shí)候,如果要引用templating設(shè)定的值,可以使用這樣的格式[[]],比如引用appid就使用[[appid]],在legend format使用label的值可以使用{{}}將labels括起來(lái).
下面給出大致配置的截圖:


config.png

結(jié)語(yǔ):

這里也就是用到了prometheus自定義監(jiān)控的基本功能,實(shí)際上prometheus還支持其他好幾種數(shù)據(jù)類型,各種豐富的算術(shù)表達(dá)式,報(bào)警聚合和抑制,以及自動(dòng)發(fā)現(xiàn)等,這些需要大家慢慢發(fā)掘與學(xué)習(xí)了,真正業(yè)務(wù)有需求了就會(huì)驅(qū)動(dòng)技術(shù)的進(jìn)步。

這里有1個(gè)問(wèn)題,就是推送端的監(jiān)控問(wèn)題,如果腳本意外出錯(cuò)停止,數(shù)據(jù)就不會(huì)更新了,這邊我用的是zabbix監(jiān)控了機(jī)器的這個(gè)進(jìn)程,當(dāng)然還有更好的方法,大家可以嘗試嘗試。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • Docker — 云時(shí)代的程序分發(fā)方式 要說(shuō)最近一年云計(jì)算業(yè)界有什么大事件?Google Compute Engi...
    ahohoho閱讀 15,828評(píng)論 15 147
  • 【電影類】 最佳男主角: 卡西·阿弗萊克 《海邊的曼徹斯特》 安德魯·加菲爾德 《血戰(zhàn)鋼鋸嶺》 瑞恩·高斯林 《愛(ài)...
    Sir電影閱讀 449評(píng)論 0 2
  • 《實(shí)用性閱讀指南》,書如其名,這是一本實(shí)用型的閱讀指導(dǎo)類書籍,作者大巖俊之用親身經(jīng)歷向我們講述了讀書對(duì)他的職業(yè)和人...
    火殘翼閱讀 1,048評(píng)論 0 4
  • 寒假,和幾個(gè)老朋友一起吃飯聚會(huì),小言說(shuō)自己活了20年堅(jiān)持得最久的一件事就是單身,我笑了笑問(wèn)她說(shuō),那我呢?她望著我毫...
    傾北閱讀 487評(píng)論 0 0

友情鏈接更多精彩內(nèi)容