prometheus
prometheus简介
prometheus简介
Prometheus是一套开源的监控&报警&时间序列数据库的组合,起始是由SoundCloud公司开发的。随着发展,越来越多公司和组织接受采用Prometheus,社区也十分活跃,他们便将它独立成开源项目,并且有公司来运作。google SRE的书内也曾提到跟他们BorgMon监控系统相似的实现是Prometheus。现在最常见的Kubernetes容器管理系统中,通常会搭配Prometheus进行监控。
- Prometheus 属于一站式监控告警平台,依赖少,功能齐全。
- Prometheus 支持对云的或容器的监控,其他系统主要对主机监控。
- Prometheus 数据查询语句表现力更强大,内置更强大的统计函数。
- Prometheus 在数据存储扩展性以及持久性上没有 InfluxDB,OpenTSDB,Sensu 好。
prometheus特点
- 非常少的外部依赖,安装使用超简单
- 已经有非常多的系统集成 例如:docker HAProxy Nginx JMX mysql等等
- 服务自动化发现
- 直接集成到代码
- 设计思想是按照分布式、微服务架构来实现的
prometheus特性
- 自定义多维度的数据模型
- 非常高效的存储 平均一个采样数据占 ~3.5 bytes左右,320万的时间序列,每30秒采样,保持60天,消耗磁盘大概228G。
- 强大的查询语句 proQL
- 轻松实现数据可视化
prometheus系统架构
- 它的服务过程是这样的 Prometheus daemon 负责定时去目标上抓取 metrics(指标) 数据,每个抓取目标需要暴露一个http服务的接口给它定时抓取。
- Prometheus支持通过配置文件、文本文件、zookeeper、Consul、DNS SRV lookup等方式指定抓取目标。
- Alertmanager 是独立于Prometheus的一个组件,可以支持Prometheus的查询语句,提供十分灵活的报警方式。
- Prometheus支持很多方式的图表可视化,例如十分精美的Grafana,自带的Promdash,以及自身提供的模版引擎等等,还提供HTTP API的查询方式,自定义所需要的输出。
- PushGateway这个组件是支持Client主动推送 metrics 到PushGateway,而Prometheus只是定时去Gateway上抓取数据。
- 如果有使用过statsd的用户,则会觉得这十分相似,只是statsd是直接发送给服务器端,而Prometheus主要还是靠进程主动去抓取
结构图如下:

prometheus数据模型
- Prometheus 从根本上所有的存储都是按时间序列去实现的,相同的 metrics(指标名称) 和 label(一个或多个标签) 组成一条时间序列,不同的label表示不同的时间序列。为了支持一些查询,有时还会临时产生一些时间序列存储 metrics name & label 指标名称和标签 每条时间序列是由唯一的 指标名称 和 一组 标签 (key=value)的形式组成。
- 指标名称 一般是给监测对像起一名字,例如 httprequeststotal 这样,它有一些命名规则,可以包字母数字_之类的的 通常是以应用名称开头_监测对像_数值类型_单位这样。
- 标签 就是对一条时间序列不同维度的识别了,例如 一个http请求用的是POST还是GET,它的endpoint是什么,这时候就要用标签去标记了。 最终形成的标识便是这样了http_requests_total{method="POST",endpoint="/api/tracks"}记住,针对httprequeststotal这个metrics name 无论是增加标签还是删除标签都会形成一条新的时间序列。
- 查询语句就可以跟据上面标签的组合来查询聚合结果了。
- 如果以传统数据库的理解来看这条语句,则可以考虑 httprequeststotal是表名,标签是字段,而timestamp是主键,还有一个float64字段是值了。(Prometheus里面所有值都是按float64存储)
prometheus的四种数据类型
counter
Counter 用于累计值,例如 记录 请求次数、任务完成数、错误发生次数。 一直增加,不会减少。 重启进程后,会被重置。 例如:http_response_total{method="GET",endpoint="/api/tracks"} 100 10秒后抓取 http_response_total{method="GET",endpoint="/api/tracks"} 100
Gauge
Gauge 常规数值,例如 温度变化、内存使用变化。 可变大,可变小。 重启进程后,会被重置 例如:
memoryusagebytes{host="master-01"} 100 < 抓取值
memoryusagebytes{host="master-01"} 30
memoryusagebytes{host="master-01"} 50
memoryusagebytes{host="master-01"} 80 < 抓取值
Histogran
Histogram 可以理解为柱状图的意思,常用于跟踪事件发生的规模,例如:请求耗时、响应大小。它特别之处是可以对记录的内容进行分组,提供 count 和 sum 全部值的功能
例如:{小于10=5次,小于20=1次,小于30=2次},count=7次,sum=7次的求和值
Summary
Summary和Histogram十分相似,常用于跟踪事件发生的规模,例如:请求耗时、响应大小。同样提供 count 和 sum 全部值的功能。 例如:count=7次,sum=7次的值求值 它提供一个quantiles的功能,可以按%比划分跟踪的结果。例如:quantile取值0.95,表示取采样值里面的95%数据。
Promethes vs Zabbix
- Zabbix 使用的是 C 和 PHP, Prometheus 使用 Golang, 整体而言 Prometheus 运行速度更快一点。
- Zabbix 属于传统主机监控,主要用于物理主机,交换机,网络等监控,Prometheus 不仅适用主机监控,还适用于 Cloud, SaaS, Openstack,Container 监控。
- Zabbix 在传统主机监控方面,有更丰富的插件。
- Zabbix 可以在 WebGui 中配置很多事情,但是 Prometheus 需要手动修改文件配置。
Prometheus vs Graphite
- Graphite 功能较少,它专注于两件事,存储时序数据, 可视化数据,其他功能需要安装相关插件,而 Prometheus 属于一站式,提供告警和趋势分析的常见功能,它提供更强的数据存储和查询能力。
- 在水平扩展方案以及数据存储周期上,Graphite 做的更好。
Prometheus vs InfluxDB
- InfluxDB 是一个开源的时序数据库,主要用于存储数据,如果想搭建监控告警系统, 需要依赖其他系统。
- InfluxDB 在存储水平扩展以及高可用方面做的更好, 毕竟核心是数据库
Prometheus vs OpenTSDB
- OpenTSDB 是一个分布式时序数据库,它依赖 Hadoop 和 HBase,能存储更长久数据, 如果你系统已经运行了 Hadoop 和 HBase, 它是个不错的选择。
- 如果想搭建监控告警系统,OpenTSDB 需要依赖其他系统。
Prometheus vs Nagios
- Nagios 数据不支持自定义 Labels, 不支持查询,告警也不支持去噪,分组, 没有数据存储,如果想查询历史状态,需要安装插件。
- Nagios 是上世纪 90 年代的监控系统,比较适合小集群或静态系统的监控,显然 Nagios 太古老了,很多特性都没有,Prometheus 要优秀很多
Prometheus vs Sensu
- Sensu 广义上讲是 Nagios 的升级版本,它解决了很多 Nagios 的问题,如果你对 Nagios 很熟悉,使用 Sensu 是个不错的选择。
- Sensu 依赖 RabbitMQ 和 Redis,数据存储上扩展性更好。
Prometheus安装
官网下载地址:https://prometheus.io/download/ 下载下来是二进制文件,可以直接运行。
运行配置
可以直接运行,但一般我们都会添加参数和指定配置文件,配置文件一般都是指定从哪里获取数据,
一般会启动会添加以下参数
--config.file="/home/conf/prometheus.yml" #指定配置文件,--config.file或以写成-config.file,一个-和两个-没有差别。 --web.listen-address=":9090"这个默认是这个,可以不写,如果换ip的话,那可以添加上这个参数,更改。 --log.level="info" #日志级别 --log.format="" #可以通过syslog来把日志记录起来。 --storage.local.path="存储目录" --storage.local.retention="360h0m0s" #数据存储多长时间之后删除。 --alertmanager.url="http://ip:9093" #altermanager的地址,但加在这不是很好,可以在prometheus.yml的配置文件中添加,下面会讲到。
日志配置
有两种方式来配置,一种是直接打到一个文件中 通过supervise来启的话,可以把日志打到指定的位置,脚本如下:
[root@node3 scripts]# cat run_prometheus.sh
#!/bin/bash
set -e
ulimit -n 1000000
# WARNING: This file was auto-generated. Do not edit!
#          All your edit might be overwritten!
exec > >(tee -i -a "/home/tidb/deploy/log/prometheus.log")
exec 2>&1
exec bin/prometheus \
    --config.file="/home/tidb/deploy/conf/prometheus.yml" \
    --web.listen-address=":9090" \
    --web.external-url="http://192.168.7.232:9090/" \
    --log.level="info" \
    --storage.local.path="/home/tidb/deploy/data.metrics" \
    --storage.local.retention="360h0m0s"
第二种是能过系统日志来打印到指定的位置(rsyslog)
配置rsyslog:在/etc/rsyslog.conf文件中添加以下: local3.* /var/log/prometheus.log
然后在更改一行,也就是在下面一行增加了local3.none,目的是不让日志打到/var/log/messages里面去,不然就有两份日志了,*.info;mail.none;authpriv.none;cron.none;local3.none /var/log/messages
然后重启rsyslog 在启动prometheus上添加参数–log.formate=”logger:syslog?appname=bob&local=3″ 总体启动命令如下:
./bin/prometheus --config.file="/home/tidb/deploy/conf/prometheus.yml" \ --web.listen-address=":9090" \ --alertmanager.url="http://192.168.7.232:9093" \ --web.external-url="http://192.168.7.232:9090/" \ --log.level="info" \ --log.format="logger:syslog?appname=bob&local=3" \ --storage.local.path="/home/tidb/deploy/data.metrics" \ -storage.local.retention="360h0m0s" &>/dev/null &
获取数据配置
配置文件样本
---
global:
  scrape_interval:     15s # By default, scrape targets every 15 seconds.
  evaluation_interval: 15s # By default, scrape targets every 15 seconds.
  # scrape_timeout is set to the global default (10s).
  labels:
    cluster: 'test-cluster'
    monitor: "prometheus"
scrape_configs:
  - job_name: 'overwritten-cluster'
    scrape_interval: 3s
    honor_labels: true # don't overwrite job & instance labels
    static_configs:
      - targets: 
        - '192.168.7.232:9091'
        - 'localhost:9090'
  - job_name: "overwritten-nodes"
    honor_labels: true # don't overwrite job & instance labels
    static_configs:
    - targets:
      - '192.168.7.230:9100'
      - '192.168.7.231:9100'
      - '192.168.7.235:9100'
      - '192.168.7.234:9100'
      - '192.168.7.233:9100'
      - '192.168.7.232:9100'
# Load and evaluate rules in this file every 'evaluation_interval' seconds.
rule_files:
  - 'alert.rules'
样例(sample)
global:
  scrape_interval:     15s # By default, scrape targets every 15 seconds.
  evaluation_interval: 15s # By default, scrape targets every 15 seconds.
rule_files:
  - "rules/node.rules"
scrape_configs:
  - job_name: 'prometheus'
    scrape_interval: 5s
    static_configs:
      - targets: ['localhost:9090']
  - job_name: 'node'
    scrape_interval: 8s
    static_configs:
      - targets: ['127.0.0.1:9100', '127.0.0.12:9100']
  - job_name: 'mysqld'
    static_configs:
      - targets: ['127.0.0.1:9104']
  - job_name: 'memcached'
    static_configs:
      - targets: ['127.0.0.1:9150']
全局配置
global 属于全局的默认配置,它主要包含 4 个属性,
- scrape_interval: 拉取 targets 的默认时间间隔。
- scrape_timeout: 拉取一个 target 的超时时间。
- evaluation_interval: 执行 rules 的时间间隔。
- external_labels: 额外的属性,会添加到拉取的数据并存到数据库中。
配置文件结构大概为:
global:
  scrape_interval:     15s # By default, scrape targets every 15 seconds.
  evaluation_interval: 15s # By default, scrape targets every 15 seconds.
  scrape_timeout: 10s # is set to the global default (10s).
  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
    monitor: 'codelab-monitor'
告警配置
通常我们可以使用运行参数 -alertmanager.xxx 来配置 Alertmanager, 但是这样不够灵活,没有办法做到动态更新加载,以及动态定义告警属性。
所以 alerting 配置主要用来解决这个问题,它能够更好的管理 Alertmanager, 主要包含 2 个参数:
- alertrelabelconfigs: 动态修改 alert 属性的规则配置。
- alertmanagers: 用于动态发现 Alertmanager 的配置。
配置结构如下:
alerting:
  alert_relabel_configs:
    [ -  ... ]
  alertmanagers:
    [ -  ... ]
规则配置
rule_files: - "rules/node.rules" - "rules2/*.rules"
数据拉取配置
scrape_configs 主要用于配置拉取数据节点,每一个拉取配置主要包含以下参数:
- job_name:任务名称
- honor_labels: 用于解决拉取数据标签有冲突,当设置为 true, 以拉取数据为准,否则以服务配置为准
- params:数据拉取访问时带的请求参数
- scrape_interval: 拉取时间间隔
- scrape_timeout: 拉取超时时间
- metrics_path: 拉取节点的 metric 路径
- scheme: 拉取数据访问协议
- sample_limit: 存储的数据标签个数限制,如果超过限制,该数据将被忽略,不入存储;默认值为0,表示没有限制
- relabel_configs: 拉取数据重置标签配置
- metricrelabelconfigs:metric 重置标签配置
远程可写存储和可读存储
remote_write 主要用于可写远程存储配置,主要包含以下参数:
- url: 访问地址
- remote_timeout: 请求超时时间
- writerelabelconfigs: 标签重置配置, 拉取到的数据,经过重置处理后,发送给远程存储
remotewrite和remoteread属于试验阶段,慎用。
服务发现
在 Prometheus 的配置中,一个最重要的概念就是数据源 target,而数据源的配置主要分为静态配置和动态发现, 大致为以下几类:
- static_configs: 静态服务发现
- dnssdconfigs: DNS 服务发现
- filesdconfigs: 文件服务发现
- consulsdconfigs: Consul 服务发现
- serversetsdconfigs: Serverset 服务发现
- nervesdconfigs: Nerve 服务发现
- marathonsdconfigs: Marathon 服务发现
- kubernetessdconfigs: Kubernetes 服务发现
- gcesdconfigs: GCE 服务发现
- ec2sdconfigs: EC2 服务发现
- openstacksdconfigs: OpenStack 服务发现
- azuresdconfigs: Azure 服务发现
- tritonsdconfigs: Triton 服务发现
它们中最重要的,也是使用最广泛的应该是 static_configs, 其实那些动态类型都可以看成是某些通用业务使用静态服务封装的结果。
alertmanager
使用和prometheus一样,它的作用就是接收prometheus发过来的alert,然后通过email,发送出去。
日志配置也和prometheus一样,有两种方式。这里就不说了。
配置文件可以参考以下: 邮件部份可以配置以下,其他的可以用默认的就可以,
smtp_smarthost: 'smtp.sina.com:25' smtp_from: 'linuxclc@sina.com' smtp_auth_username: 'linuxclc' smtp_auth_password: 'linuxclc123456'
接收邮件如下:
receivers:
- name: 'team-X-mails'
  email_configs:
  - to: 'chenlc@yunduo.com'
    send_resolved: true 
node_exporter
日志配置和prometheus一样,有两种方式。
不需要配置文件,直接启动就可以了,默认端口 9100 会自动监控主机的一些常用信息。
pushgateway
这个日志配置和prometheus一样,有两种方式。 直接启动就可以了,默认端口是9091,别的应用可以自动把数据推送给pushgateway,然后prometheus来pushgateway来抓取数据。
grafana
grafana安装
参考:http://docs.grafana.org/installation/rpm/
安装方法一: rpm包安装:
下载rpm包及安装依赖:
$ wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-4.4.1-1.x86_64.rpm $ sudo yum install initscripts fontconfig freetype* urw-fonts $ sudo rpm -Uvh grafana-4.4.1-1.x86_64.rpm
方法二:yum安装:
cat >/etc/yum.repos.d/grafana.repo<< EOF [grafana] name=grafana baseurl=https://packagecloud.io/grafana/stable/el/6/$basearch repo_gpgcheck=1 enabled=1 gpgcheck=1 gpgkey=https://packagecloud.io/gpg.key https://grafanarel.s3.amazonaws.com/RPM-GPG-KEY-grafana sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt EOF
yum install grafana -y
方法三:二进制安装
下载二进制解压就可以,同prometheus一样。
可以直接启动,配置文件也可以通过参数来指定:–config=
data目录其实内容很少,存一些sessions和dashboard格式之类的。
在data目录下有一个data_source.json文件,可以直接配置,不需要在web界面上配置。样例如下:
[root@node3 data.grafana]# cat data_source.json 
{
    "name":"test-cluster",
    "type":"prometheus",
    "access":"proxy",
    "url":"http://192.168.7.232:9090/",
    "basicAuth":false
}
可以参考的配置文件:
##################### Grafana Configuration Example #####################
#
# Everything has defaults so you only need to uncomment things you want to
# change
# possible values : production, development
; app_mode = production
# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty
; instance_name = ${HOSTNAME}
#################################### Paths ####################################
[paths]
# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
#
data = /home/tidb/deploy/data.grafana
#
# Directory where grafana can store logs
#
logs = /home/tidb/deploy/log
#
# Directory where grafana will automatically scan and look for plugins
#
plugins = /home/tidb/deploy/opt/grafana/plugins
#
#################################### Server ####################################
[server]
# Protocol (http or https)
;protocol = http
# The ip address to bind to, empty will bind to all interfaces
;http_addr =
# The http port  to use
http_port = 3000
# The public facing domain name used to access grafana from a browser
domain = 192.168.7.232
# Redirect to correct domain if host header does not match domain
# Prevents DNS rebinding attacks
;enforce_domain = false
# The full public facing url
;root_url = %(protocol)s://%(domain)s:%(http_port)s/
# Log web requests
;router_logging = false
# the path relative working path
;static_root_path = public
# enable gzip
;enable_gzip = false
# https certs & key file
;cert_file =
;cert_key =
#################################### Database ####################################
[database]
# Either "mysql", "postgres" or "sqlite3", it's your choice
;type = sqlite3
;host = 127.0.0.1:3306
;name = grafana
;user = root
;password =
# For "postgres" only, either "disable", "require" or "verify-full"
;ssl_mode = disable
# For "sqlite3" only, path relative to data_path setting
;path = grafana.db
#################################### Session ####################################
[session]
# Either "memory", "file", "redis", "mysql", "postgres", default is "file"
;provider = file
# Provider config options
# memory: not have any config yet
# file: session dir path, is relative to grafana data_path
# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=grafana`
# mysql: go-sql-driver/mysql dsn config string, e.g. `user:password@tcp(127.0.0.1:3306)/database_name`
# postgres: user=a password=b host=localhost port=5432 dbname=c sslmode=disable
;provider_config = sessions
# Session cookie name
;cookie_name = grafana_sess
# If you use session in https only, default is false
;cookie_secure = false
# Session life time, default is 86400
;session_life_time = 86400
#################################### Analytics ####################################
[analytics]
# Server reporting, sends usage counters to stats.grafana.org every 24 hours.
# No ip addresses are being tracked, only simple counters to track
# running instances, dashboard and error counts. It is very helpful to us.
# Change this option to false to disable reporting.
;reporting_enabled = true
# Set to false to disable all checks to https://grafana.net
# for new vesions (grafana itself and plugins), check is used
# in some UI views to notify that grafana or plugin update exists
# This option does not cause any auto updates, nor send any information
# only a GET request to http://grafana.net to get latest versions
check_for_updates = true
# Google Analytics universal tracking code, only enabled if you specify an id here
;google_analytics_ua_id =
#################################### Security ####################################
[security]
# default admin user, created on startup
admin_user = admin
# default admin password, can be changed before first start of grafana,  or in profile settings
admin_password = admin
# used for signing
;secret_key = SW2YcwTIb9zpOOhoPsMm
# Auto-login remember days
;login_remember_days = 7
;cookie_username = grafana_user
;cookie_remember_name = grafana_remember
# disable gravatar profile images
;disable_gravatar = false
# data source proxy whitelist (ip_or_domain:port separated by spaces)
;data_source_proxy_whitelist =
[snapshots]
# snapshot sharing options
;external_enabled = true
;external_snapshot_url = https://snapshots-origin.raintank.io
;external_snapshot_name = Publish to snapshot.raintank.io
#################################### Users ####################################
[users]
# disable user signup / registration
;allow_sign_up = true
# Allow non admin users to create organizations
;allow_org_create = true
# Set to true to automatically assign new users to the default organization (id 1)
;auto_assign_org = true
# Default role new users will be automatically assigned (if disabled above is set to true)
;auto_assign_org_role = Viewer
# Background text for the user field on the login page
;login_hint = email or username
# Default UI theme ("dark" or "light")
;default_theme = dark
#################################### Anonymous Auth ##########################
[auth.anonymous]
# enable anonymous access
;enabled = false
# specify organization name that should be used for unauthenticated users
;org_name = Main Org.
# specify role for unauthenticated users
;org_role = Viewer
#################################### Basic Auth ##########################
[auth.basic]
;enabled = true
#################################### Auth LDAP ##########################
[auth.ldap]
;enabled = false
;config_file = /etc/grafana/ldap.toml
#################################### SMTP / Emailing ##########################
[smtp]
;enabled = false
;host = localhost:25
;user =
;password =
;cert_file =
;key_file =
;skip_verify = false
;from_address = admin@grafana.localhost
[emails]
;welcome_email_on_sign_up = false
#################################### Logging ##########################
[log]
# Either "console", "file", "syslog". Default is console and  file
# Use space to separate multiple modes, e.g. "console file"
mode = file
# Either "trace", "debug", "info", "warn", "error", "critical", default is "info"
;level = info
# For "console" mode only
[log.console]
;level =
# log line format, valid options are text, console and json
;format = console
# For "file" mode only
[log.file]
level = info
# log line format, valid options are text, console and json
format = text
# This enables automated log rotate(switch of following options), default is true
;log_rotate = true
# Max line number of single file, default is 1000000
;max_lines = 1000000
# Max size shift of single file, default is 28 means 1 << 28, 256MB
;max_size_shift = 28
# Segment log daily, default is true
;daily_rotate = true
# Expired days of log file(delete after max days), default is 7
;max_days = 7
[log.syslog]
;level =
# log line format, valid options are text, console and json
;format = text
# Syslog network type and address. This can be udp, tcp, or unix. If left blank, the default unix endpoints will be used.
;network =
;address =
# Syslog facility. user, daemon and local0 through local7 are valid.
;facility =
# Syslog tag. By default, the process' argv[0] is used.
;tag =
#################################### AMQP Event Publisher ##########################
[event_publisher]
;enabled = false
;rabbitmq_url = amqp://localhost/
;exchange = grafana_events
;#################################### Dashboard JSON files ##########################
[dashboards.json]
enabled = false
path = /home/tidb/deploy/opt/grafana/dashboards
#################################### Internal Grafana Metrics ##########################
# Metrics available at HTTP API Url /api/metrics
[metrics]
# Disable / Enable internal metrics
;enabled           = true
# Publish interval
;interval_seconds  = 10
# Send internal metrics to Graphite
; [metrics.graphite]
; address = localhost:2003
; prefix = prod.grafana.%(instance_name)s.
#################################### Internal Grafana Metrics ##########################
# Url used to to import dashboards directly from Grafana.net
[grafana_net]
url = https://grafana.net
原文链接:prometheus,grafana,alertmanager,转载请注明来源!
