# nginx-exporter **Repository Path**: KubeSec/nginx-exporter ## Basic Information - **Project Name**: nginx-exporter - **Description**: 使用prometheus client_golang库开发nginx-exporter - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2023-07-06 - **Last Updated**: 2024-02-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # http_stub_status_module `http_stub_status_module`是nginx的一个模块,它提供了一些简单的指标和状态信息,这些信息可用于监控nginx服务器的监控状况和性能。 要启用该模块,需要在nginx配置文件中添加以下内容: ```bash location /nginx_status { stub_status on; allow 127.0.0.1; deny all; } ``` 此配置将使用nginx在`nginx_status`上公开`stub_status`信息。 这些信息只允许本地主机(即127.0.0.1)上访问,并拒绝来自其他主机上的访问请求。 然后,您可以使用curl等工具向nginx服务器发送HTTP GET请求,以获取当前的状态信息。例如,以下命令将获取位于localhost上的nginx服务器的状态信息: ```bash curl http://localhost/nginx_status ``` 此命令将返回像这样的响应: ```bash Active connections: 1 server accepts handled requests 10 10 10 Reading: 0 Writing: 1 Waiting: 0 ``` - Active connections: 当前活跃的连接数。 - Server Accepts handled requests: 表示从启动到现在一共处理过的连接数,其中accepts表示接受的连接数,handled表示已经处理完成的连接数(可能包括已经关闭的连接数),requests表示已经处理完成的请求数; - Reading: 正在读取客户端请求的连接数; - Writing:正在向客户端发送响应的连接数; - Waiting: 正在等待请求处理的连接数。 除了以上信息,还可以通过第三方模块来扩展stub_status模块的功能,例如: ngx_http_substitutions_filter_module、lua-nginx-module。 # Prometheus Exporter Prometheus Exporter是一种Collector,用于将各种数据源中的指标数据暴露为Prometheus可读的格式。Exporter可以通过多种方式实现,例如Python、Go或Java等变成语言开发自定义的Exporter # Prometheus Registry Prometheus registry是一个集合器(Collector)的注册表,它用于管理所有可用的集合器,在Prometheus中,每个Collector都必须向registry注册自己,并在启动时提供metrics路径和处理函数。 这些Collector将从不同的数据源(如操作系统、应用程序、服务等)收集指标数据,并将其暴露为Prometheus可读的格式。 # Prometheus支持四种主要的指标类型 - Counter(计数器):仅能递增、累加,用于表示某个事件的发生次数或某个请求的处理时间等。 - Gauge(测量值):可以递增或递减,用于表示状态变量或可变大小的值,如CPU利用率、内存使用量等。 - Histogram(直方图):用于度量数据分布情况,监控请求延迟、响应大小等。它会将数据按照桶(buckets)进行划分,并统计每个桶中的数据数量,从而形成一个频率分布直方图。 - Summary(摘要):类似于Histogram,也用于度量数据分布情况,但它会计算数据的均值、标准等汇总信息,而不像Histogram那样只显示频率分布情况。 这些指标类型可以组合使用,以便更好地描述系统的运行状态和性能指标。例如,可以使用Counter来记录某个API的请求数,使用Gauge来记录内存使用量,使用Histogram来记录请求延迟分布情况,使用Summary来记录响应时间分布情况。 # Exporter ```go type Exporter struct { } func (e *Exporter) Describe(ch chan<- *prometheus.Desc) { } func (e *Exporter) Collect(ch chan<- prometheus.Metric) {} ``` 这段代码定义了一个名为Exporter的结构体,它实现了Prometheus的Collector接口。其中包含了两个方法:Describe和Collect。 func (e *Exporter) Describe(ch chan<- *prometheus.Desc)表示实现了Describe方法,参数是一个只能发送(send-only)的通道(channel),类型为*prometheus.Desc,表明该方法返回的是一个指标(metric)的描述信息。在该方法中,我们需要将所有可用的指标的描述信息写入到通道中,以便Prometheus可以获取并使用这些描述信息。 func (e *Exporter) Collect(ch chan<- prometheus.Metric) {}表示实现了Collect方法,参数是一个只能发送(send-only)的通道(channel),类型为prometheus.Metric,表明该方法返回的是一个指标(metric)的值。在该方法中,我们需要将所有可用的指标的具体值写入到通道中,以便Prometheus可以收集和查询这些指标数据。 通常情况下,我们需要在Describe中注册所有的指标描述信息,并在Collect中根据实际情况获取每个指标的值,并将其写入到通道中。例如: ```go package main import ( "github.com/prometheus/client_golang/prometheus" ) type MyExporter struct { myMetric prometheus.Gauge } func NewMyExporter() *MyExporter { return &MyExporter{ myMetric: prometheus.NewGauge(prometheus.GaugeOpts{ Name: "my_metric", Help: "This is my metric", }), } } func (e *MyExporter) Describe(ch chan<- *prometheus.Desc) { ch <- e.myMetric.Desc() } func (e *MyExporter) Collect(ch chan<- prometheus.Metric) { // Get the value of myMetric from somewhere. value := 42.0 // Set the value to myMetric and write it to the channel. e.myMetric.Set(value) ch <- e.myMetric } ``` 在该示例中,我们定义了一个名为MyExporter的结构体,其中包含一个名为myMetric的指标。在NewMyExporter函数中,我们创建了一个新的MyExporter实例,并初始化了myMetric指标。 在Describe方法中,我们向通道中写入了myMetric指标的描述信息。在Collect方法中,我们先获取了myMetric的值(例如从某个数据源获取),然后将其设置为指标的值,并将指标写入到通道中。 最终,在我们的主程序中,我们可以使用该Exporter并将其注册到Prometheus registry中: ```go package main import ( "net/http" "github.com/prometheus/client_golang/prometheus/promhttp" ) func main() { exporter := NewMyExporter() prometheus.MustRegister(exporter) http.Handle("/metrics", promhttp.Handler()) http.ListenAndServe(":8080", nil) } ``` 在代码中,我们创建了一个MyExporter实例exporter,然后将其注册到Prometheus registry中,以便Prometheus可以在"/metrics"路径下获取指标数据。我们还启动了一个HTTP服务器,以便Prometheus可以访问并收集我们的指标数据。 # nginx-exporter 示例 https://github.com/nginxinc/nginx-prometheus-exporter > 使用`Go`语言编写`Prometheus Exporter`来监控`http_stub_status`模块。首先使用Go的http客户端库来从Nginx服务器获取`stub_status`页面的数据。 > 然后,将获取的数据转换成`Prometheus`格式,并公开给`Prometheus`服务器以进行收集和查询。 ```go package main import ( "net/http" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) var ( nginxUp = prometheus.NewGauge(prometheus.GaugeOpts{ Name: "nginx_up", Help: "Whether Nginx server is up.", }) nginxRequests = prometheus.NewCounterVec(prometheus.CounterOpts{ Name: "nginx_http_requests_total", Help: "Total number of HTTP requests processed by Nginx.", }, []string{"method", "uri", "status"}) ) func main() { // Register metrics with Prometheus client. prometheus.MustRegister(nginxUp) prometheus.MustRegister(nginxRequests) // Start the web server. http.Handle("/metrics", promhttp.Handler()) http.ListenAndServe(":8080", nil) } ``` 在代码中,我们定义了两个Prometheus指标:nginx_up和nginx_http_requests_total。其中, nginx_up用于记录Nginx服务器是否正常,nginx_http_request_total用于记录Nginx 处理HTTP请求总数。 接下来,我们需要使用HTTP客户端从Nginx服务器获取stub_status页面的数据,并将其转成我们的指标格式。 ```go package main import ( "net/http" "github.com/prometheus/client_golang/prometheus" ) func updateMetrics() { resp, err := http.Get("http://localhost/server-status") if err != nil { nginxUp.Set(0) return } defer resp.Body.Close() // Parse the response body and extract the desired metrics. // ... nginxUp.Set(1) } func main() { // ... // Update metrics periodically. go func() { for { updateMetrics() time.Sleep(time.Minute) } }() // ... } ``` 在代码中,我们使用HTTP客户端从"http://localhost/server-status"获取stub_status页面的数据,并将其解析为我们的指标格式。我们还定义了一个updateMetrics函数,该函数会定期更新我们的指标数据(例如,每分钟执行一次)。 最后,通过启动一个HTTP服务器来公开我们的指标数据,以便Prometheus服务器可以收集和查询它们。下面是一个简单的示例代码: ```go package main import ( "net/http" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) func main() { // Register metrics with Prometheus client. prometheus.MustRegister(nginxUp) prometheus.MustRegister(nginxRequests) // Start the web server. http.Handle("/metrics", promhttp.Handler()) http.ListenAndServe(":8080", nil) } ``` 在代码中,我们使用promhttp.Handler()函数创建了一个HTTP处理程序,该处理程序将我们的指标数据公开在"/metrics"路径下。然后,我们使用http.ListenAndServe()函数启动了一个 # nginx sub_status.conf ```bash server { listen 8181; server_name localhost; location /status { stub_status on; } } docker run --name some-nginx -v /tmp/nginx-status.conf:/etc/nginx/conf.d/nginx-status.conf -d -p 8181:8181 nginx ```