123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396 |
- // 首先确定监测指标:度量什么(Name),
- // 再确定监测点
- package metrics
- import (
- "fmt"
- "log"
- "net/http"
- "sync"
- "leafstalk/conf"
- "github.com/prometheus/client_golang/prometheus"
- "github.com/prometheus/client_golang/prometheus/promhttp"
- )
- var (
- prometheusReporter *PrometheusReporter
- once sync.Once
- )
- // PrometheusReporter reports metrics to prometheus
- type PrometheusReporter struct {
- serverType string
- project string
- countReportersMap map[string]*prometheus.CounterVec
- summaryReportersMap map[string]*prometheus.SummaryVec
- gaugeReportersMap map[string]*prometheus.GaugeVec
- histogramReportersMap map[string]*prometheus.HistogramVec
- additionalLabels map[string]string
- }
- func (p *PrometheusReporter) registerCustomMetrics(
- constLabels map[string]string,
- additionalLabelsKeys []string,
- spec *CustomMetricsSpec,
- ) {
- // 监测点指定比例的分布情况
- for _, summary := range spec.Summaries {
- p.summaryReportersMap[summary.Name] = prometheus.NewSummaryVec(
- prometheus.SummaryOpts{
- Namespace: p.serverType,
- Subsystem: summary.Subsystem,
- Name: summary.Name,
- Help: summary.Help,
- Objectives: summary.Objectives,
- ConstLabels: constLabels,
- },
- append(additionalLabelsKeys, summary.Labels...),
- )
- }
- // 监测点数值变化度量,变大变小
- for _, gauge := range spec.Gauges {
- p.gaugeReportersMap[gauge.Name] = prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Namespace: p.serverType,
- Subsystem: gauge.Subsystem,
- Name: gauge.Name,
- Help: gauge.Help,
- ConstLabels: constLabels,
- },
- append(additionalLabelsKeys, gauge.Labels...),
- )
- }
- // 监测点命中次数或
- for _, counter := range spec.Counters {
- p.countReportersMap[counter.Name] = prometheus.NewCounterVec(
- prometheus.CounterOpts{
- Namespace: p.serverType,
- Subsystem: counter.Subsystem,
- Name: counter.Name,
- Help: counter.Help,
- ConstLabels: constLabels,
- },
- append(additionalLabelsKeys, counter.Labels...),
- )
- }
- }
- func (p *PrometheusReporter) registerMetrics(
- constLabels, additionalLabels map[string]string,
- spec *CustomMetricsSpec,
- ) {
- // constLabels["game"] = p.game
- // constLabels["serverType"] = p.serverType
- p.additionalLabels = additionalLabels
- additionalLabelsKeys := make([]string, 0, len(additionalLabels))
- for key := range additionalLabels {
- additionalLabelsKeys = append(additionalLabelsKeys, key)
- }
- p.registerCustomMetrics(constLabels, additionalLabelsKeys, spec)
- // 定义多个指标,并选择响应的度量方式
- // HandlerResponseTimeMs summary
- // 响应耗时分布统计
- p.summaryReportersMap[ResponseTime] = prometheus.NewSummaryVec(
- prometheus.SummaryOpts{
- Namespace: p.serverType,
- Subsystem: "handler",
- Name: ResponseTime,
- Help: "处理一条消息耗时NS",
- Objectives: map[float64]float64{0.7: 0.02, 0.95: 0.005, 0.99: 0.001},
- ConstLabels: constLabels,
- },
- append([]string{"route", "status", "type", "code"}, additionalLabelsKeys...),
- )
- // ProcessDelay summary
- // 用户请求延时分布
- p.summaryReportersMap[ProcessDelay] = prometheus.NewSummaryVec(
- prometheus.SummaryOpts{
- Namespace: p.serverType,
- Subsystem: "handler",
- Name: ProcessDelay,
- Help: "处理消息延迟NS",
- Objectives: map[float64]float64{0.7: 0.02, 0.95: 0.005, 0.99: 0.001},
- ConstLabels: constLabels,
- },
- append([]string{"route", "type"}, additionalLabelsKeys...),
- )
- // ConnectedClients gauge
- // 当前的客户端连接数
- p.gaugeReportersMap[ConnectedClients] = prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Namespace: p.serverType,
- Subsystem: "acceptor",
- Name: ConnectedClients,
- Help: "当前连接的客户端数目",
- ConstLabels: constLabels,
- },
- additionalLabelsKeys,
- )
- // 当前服务端连接数
- p.gaugeReportersMap[CountServers] = prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Namespace: p.serverType,
- Subsystem: "service_cluster",
- Name: CountServers,
- Help: "当前连接的服务端数量",
- ConstLabels: constLabels,
- },
- append([]string{"type"}, additionalLabelsKeys...),
- )
- // 通道可用容量
- p.gaugeReportersMap[ChannelCapacity] = prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Namespace: p.serverType,
- Subsystem: "channel",
- Name: ChannelCapacity,
- Help: "the available capacity of the channel",
- ConstLabels: constLabels,
- },
- append([]string{"channel"}, additionalLabelsKeys...),
- )
- // 丢弃RPC消息的数量
- p.gaugeReportersMap[DroppedMessages] = prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Namespace: p.serverType,
- Subsystem: "rpc_server",
- Name: DroppedMessages,
- Help: "the number of rpc server dropped messages (messages that are not handled)",
- ConstLabels: constLabels,
- },
- additionalLabelsKeys,
- )
- // 当前协程数量
- p.gaugeReportersMap[Goroutines] = prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Namespace: p.serverType,
- Subsystem: "sys",
- Name: Goroutines,
- Help: "当前协程数量",
- ConstLabels: constLabels,
- },
- additionalLabelsKeys,
- )
- // 当前堆大小
- p.gaugeReportersMap[HeapSize] = prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Namespace: p.serverType,
- Subsystem: "sys",
- Name: HeapSize,
- Help: "当前堆的大小",
- ConstLabels: constLabels,
- },
- additionalLabelsKeys,
- )
- // 当前堆栈对象数目
- p.gaugeReportersMap[HeapObjects] = prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Namespace: p.serverType,
- Subsystem: "sys",
- Name: HeapObjects,
- Help: "当前堆对象数目",
- ConstLabels: constLabels,
- },
- additionalLabelsKeys,
- )
- // 当前重试JOB数量
- p.gaugeReportersMap[WorkerJobsRetry] = prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Namespace: p.serverType,
- Subsystem: "worker",
- Name: WorkerJobsRetry,
- Help: "当前重试JOB数量",
- ConstLabels: constLabels,
- },
- additionalLabelsKeys,
- )
- //当前队列大小
- p.gaugeReportersMap[WorkerQueueSize] = prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Namespace: p.serverType,
- Subsystem: "worker",
- Name: WorkerQueueSize,
- Help: "当前队列大小",
- ConstLabels: constLabels,
- },
- append([]string{"queue"}, additionalLabelsKeys...),
- )
- //
- p.gaugeReportersMap[WorkerJobsTotal] = prometheus.NewGaugeVec(
- prometheus.GaugeOpts{
- Namespace: p.serverType,
- Subsystem: "worker",
- Name: WorkerJobsTotal,
- Help: "the total executed jobs",
- ConstLabels: constLabels,
- },
- append([]string{"status"}, additionalLabelsKeys...),
- )
- // 计数度量
- p.countReportersMap[ExceededRateLimiting] = prometheus.NewCounterVec(
- prometheus.CounterOpts{
- Namespace: p.serverType,
- Subsystem: "acceptor",
- Name: ExceededRateLimiting,
- Help: "the number of blocked requests by exceeded rate limiting",
- ConstLabels: constLabels,
- },
- additionalLabelsKeys,
- )
- // 玩家请求的消息计数
- p.countReportersMap[MessageHandler] = prometheus.NewCounterVec(
- prometheus.CounterOpts{
- Namespace: p.serverType,
- Subsystem: "messageHandler",
- Name: MessageHandler,
- Help: "玩家发送请求数量",
- ConstLabels: constLabels,
- },
- append([]string{"handler"}, additionalLabelsKeys...),
- )
- p.histogramReportersMap[MessageResponseTime] = prometheus.NewHistogramVec(
- prometheus.HistogramOpts{
- Namespace: p.serverType,
- Name: MessageResponseTime,
- Help: "各种消息响应耗时",
- },
- []string{"handler"},
- )
- // 注册到注册表
- toRegister := make([]prometheus.Collector, 0)
- for _, c := range p.countReportersMap {
- toRegister = append(toRegister, c)
- }
- for _, c := range p.gaugeReportersMap {
- toRegister = append(toRegister, c)
- }
- for _, c := range p.summaryReportersMap {
- toRegister = append(toRegister, c)
- }
- for _, c := range p.histogramReportersMap {
- toRegister = append(toRegister, c)
- }
- prometheus.MustRegister(toRegister...)
- }
- // StartPrometheusReporter gets the prometheus reporter singleton
- func StartPrometheusReporter(
- serverType string,
- config *conf.Config,
- // constLabels map[string]string,
- ) (*PrometheusReporter, error) {
- once.Do(func() {
- var (
- port = config.GetInt("metrics.prometheus.port")
- game = config.GetString("projectName")
- additionalLabels = config.GetStringMapString("metrics.additionalTags")
- constLabels = config.GetStringMapString("metrics.constTags")
- )
- prometheusReporter = &PrometheusReporter{
- serverType: serverType,
- project: game,
- countReportersMap: make(map[string]*prometheus.CounterVec),
- summaryReportersMap: make(map[string]*prometheus.SummaryVec),
- gaugeReportersMap: make(map[string]*prometheus.GaugeVec),
- histogramReportersMap: make(map[string]*prometheus.HistogramVec),
- }
- spec, err := NewCustomMetricsSpec(config)
- if err != nil {
- log.Fatalf("NewCustomMetricsSpec error. %v", err)
- return
- }
- prometheusReporter.registerMetrics(constLabels, additionalLabels, spec)
- http.Handle("/metrics", promhttp.Handler())
- go (func() {
- log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), nil))
- })()
- })
- return prometheusReporter, nil
- }
- // ReportSummary reports a summary metric
- func (p *PrometheusReporter) ReportSummary(metric string, labels map[string]string, value float64) error {
- sum := p.summaryReportersMap[metric]
- if sum != nil {
- labels = p.ensureLabels(labels)
- sum.With(labels).Observe(value)
- return nil
- }
- return ErrMetricNotKnown
- }
- // ReportCount reports a summary metric
- func (p *PrometheusReporter) ReportCount(metric string, labels map[string]string, count float64) error {
- cnt := p.countReportersMap[metric]
- if cnt != nil {
- labels = p.ensureLabels(labels)
- cnt.With(labels).Add(count)
- return nil
- }
- return ErrMetricNotKnown
- }
- // ReportGauge reports a gauge metric
- func (p *PrometheusReporter) ReportGauge(metric string, labels map[string]string, value float64) error {
- g := p.gaugeReportersMap[metric]
- if g != nil {
- labels = p.ensureLabels(labels)
- g.With(labels).Set(value)
- return nil
- }
- return ErrMetricNotKnown
- }
- // ReportHistogram reports a histogram metric
- func (p *PrometheusReporter) ReportHistogram(metric string, label string, value float64) error {
- g := p.histogramReportersMap[metric]
- if g != nil {
- g.WithLabelValues(label).Observe(value)
- return nil
- }
- return ErrMetricNotKnown
- }
- // ensureLabels checks if labels contains the additionalLabels values,
- // otherwise adds them with the default values
- func (p *PrometheusReporter) ensureLabels(labels map[string]string) map[string]string {
- for key, defaultVal := range p.additionalLabels {
- if _, ok := labels[key]; !ok {
- labels[key] = defaultVal
- }
- }
- return labels
- }
|