对普罗米修斯的理解

Understanding of Prometheus

我想试试simple example of using Prometheus

  1. 我已经下载了服务器二进制文件
  2. 我已经开始了simple code,但几乎没有修改

    var addr = flag.String("listen-address", ":8080", "The address to listen on for HTTP requests.")
    func main() {
        flag.Parse()
        http.Handle("/metrics", promhttp.Handler())
        http.Handle("/test/{id}", myHandler(promhttp.Handler()))
    
        log.Fatal(http.ListenAndServe(*addr, nil))
    }
    
    func myHandler(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            fmt.Fprintf(w, "hello, you've hit %s\n", r.URL.Path)
            next.ServeHTTP(w, r)
        })
    }
    

    问题:

    1. 我假设 Prometheus 是监控工具,我想分别监控端点 metrics/test/{id}。我是否通过创建多个处理程序并使用 promhttp.Handler() 作为中间件正确地理解了这个想法?
    2. 除了请求的数量和延迟之外,还有什么可以监控,例如带有数据库的简单网络应用程序?

为了跟进@David Maze 的回答,默认处理程序 promhttp.Handler 用于报告指标。 (从所有注册的处理程序中收集并根据要求报告)。

不幸的是,它不是一个通用的 http 中间件,可以为您提供开箱即用的任何指标。

我看到很多 go 的 web 框架都有某种社区 prometheus 中间件 (gin's),它们提供开箱即用的指标(延迟、响应代码、请求计数等)。

go prometheus client library 提供了如何向您的应用程序添加指标的示例。

var (

    httpRequests = prometheus.NewCounter(
        prometheus.CounterOpts{
            Name: "http_requests_total",
            Help: "Number of http requests.",
        },
    )
)

func init() {
    // Metrics have to be registered to be exposed:
    prometheus.MustRegister(httpRequests)
}

func myHandler(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        httpRequests.Inc()
        fmt.Fprintf(w, "hello, you've hit %s\n", r.URL.Path)
        next.ServeHTTP(w, r)
    })
}

关于你的第二个问题很多 :) Google 提倡监测 4 个黄金信号:

https://landing.google.com/sre/book/chapters/monitoring-distributed-systems.html#xref_monitoring_golden-signals

这些是

  • 流量 - 吞吐量 - Counts/Time
  • 延迟 - 分布/直方图
  • 错误 - HTTP 响应 codes/explicit 错误计数
  • 饱和度 - 资源队列,即如果有一个 goroutine 池,在给定时间有多少 goroutine 处于活动状态

在我的经验中,了解应用程序与数据库之间的所有交互(即应用于数据库的 4 个黄金信号)也很有帮助:

  • 从应用程序调用数据库的次数
  • 通话延迟
  • 您为确定可用性(成功/总计)而进行的调用的结果(err/success)
  • 您的数据库驱动程序可用的饱和度 (https://golang.org/pkg/database/sql/#DBStats)