Prometheus 是一个开源的系统监控和告警工具包,最开始是在 2012 年左右的时候由谷歌的工程师研发,设计用于对时间序列数据的收集和处理,特别适合于云原生环境的监控。后来在 2016 年 5 月的时候加入了云原生计算基金会,成为继 Kubernetes 之后的第二个 CNCF 托管项目。它的优势在于简单、灵活和云原生环境的适应性,配合 grafana 可视化监控平台展示的各项度量指标,使其成为各个互联网公司业务监控告警的首选工具。
Prometheus 系统有许多优势,首先它易于管理,极大的简化了部署和管理过程,同时采用灵活的多维数据模型,每个时间序列数据由键值对组成,查询非常高效;其次它支持强大的查询语言,支持复杂查询和聚合函数,方便提取各种信息;另外它可扩展、易于集成、高可用低成本,特别是它的高性能,轻松应对百万级指标和 10 万 QPS 的数据上报。
- java 实现
import java.net.URL;
import io.prometheus.client.Gauge;
import io.prometheus.client.Counter;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.exporter.PushGateway;
import org.apache.commons.configuration.PropertiesConfiguration;
public class FrzcPrometheus {
private static String job; // Job 名称
private static PushGateway pushGateway; // Gateway 实例
private static CollectorRegistry collectorRegistry; // Registry 实例
/**
* 初始资源
*/
public static void initFrzcPrometheus(PropertiesConfiguration propertiesConfiguration) {
try {
collectorRegistry = new CollectorRegistry();
job = propertiesConfiguration.getString("prometheus.job");
pushGateway = new PushGateway(new URL(propertiesConfiguration.getString("prometheus.url")));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 测量器注册
*/
public static Gauge registerGauge(String name, String help) {
return Gauge.build().name(name).help(help).register(collectorRegistry);
}
/**
* 计数器注册
*/
public static Counter registerCounter(String name, String help) {
return Counter.build().name(name).help(help).register(collectorRegistry);
}
/**
* 计时器注册
*/
public static Gauge.Timer registerGaugeTimer(String name, String help) {
Gauge gauge = registerGauge(name, help);
return gauge.startTimer();
}
/**
* 计数器提交
*/
public static void inc(Counter counter) {
try {
counter.inc();
pushGateway.pushAdd(collectorRegistry, job);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 计时器复位
*/
public static Gauge.Timer reset(Gauge gauge) {
return gauge.startTimer();
}
/**
* 计时器提交
*/
public static void timer(Gauge.Timer timer) {
try {
timer.setDuration();
pushGateway.pushAdd(collectorRegistry, job);
} catch (Exception e) {
e.printStackTrace();
}
}
}
- python 实现
import os
from prometheus_client.core import CollectorRegistry
from prometheus_client import Counter, Summary, push_to_gateway
url = os.getenv("PROMETHEUS_URL")
job = os.getenv("PROMETHEUS_JOB")
registry = CollectorRegistry(auto_describe=False)
flow_timer = Summary('flow_timer', 'flow_timer 耗时', registry=registry)
flow_error = Counter("flow_error", "flow_error 错误数", registry=registry)
flow_request = Counter("flow_request", "flow_request 请求数", registry=registry)
flow_response = Counter("flow_response", "flow_response 应答数", registry=registry)
class Workflow:
@staticmethod
@flow_timer.time()
def check_workflow(text):
flow_request.inc()
// 业务处理
flow_response.inc()
push_to_gateway(url, job, registry=registry)
return 'very good'
- golang 实现
package prometheus
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/push"
"./pkg/config"
"time"
)
var DefaultPrometheus *Prometheus
type Prometheus struct {
pusher *push.Pusher
}
func NewPrometheus() *Prometheus {
registry := prometheus.NewRegistry()
cfg := config.NewConfig("prometheus.json")
pusher := push.New(cfg.GetString("prometheus.url"), cfg.GetString("prometheus.job")).Gatherer(registry)
return &Prometheus{
pusher: pusher,
}
}
// NewPrometheusGauge 测量器注册
func NewPrometheusGauge(name, help string) prometheus.Gauge {
return promauto.NewGauge(
prometheus.GaugeOpts{
Name: name,
Help: help,
},
)
}
// NewPrometheusCounter 计数器注册
func NewPrometheusCounter(name, help string) prometheus.Counter {
return promauto.NewCounter(
prometheus.CounterOpts{
Name: name,
Help: help,
},
)
}
// Collector 收集器执行
func (p *Prometheus) Collector(c prometheus.Collector) {
p.pusher.Collector(c)
}
// Collectors 收集器执行
func (p *Prometheus) Collectors(cs ...prometheus.Collector) {
for _, c := range cs {
p.pusher.Collector(c)
}
}
// Inc 计数器提交
func (p *Prometheus) Inc(counter prometheus.Counter) error {
counter.Inc()
return p.pusher.Add()
}
// Timer 计时器提交
func (p *Prometheus) Timer(gt prometheus.Gauge, tm time.Time) error {
//tm := time.Now()
gt.Set(time.Since(tm).Seconds())
return p.pusher.Add()
}
func init() {
DefaultPrometheus = NewPrometheus()
}
上面给了 java、python 和 golang 三种语言的基础实现,供参考。