Prometheus 通过 nginx log 日志监控应用服务

news/2024/5/18 22:51:55 标签: prometheus, nginx, 应用监控

选型

通常后端应用都通过 api 接口暴露服务,通过 nginx log 监控服务有以下特点和优势

  • 满足应用监控的需求
  • 通过响应状态码识别错误
  • 距离用户侧更近,请求时延包含了 nginx 到后端的网络时延,更接近用户体验
  • 对后端程序完全无侵入
  • 可以通过 namespace 从一份日志中解析出各个服务

指标

应用监控使用 RED 指标,即

  • requests 请求频率
  • errors 错误数
  • Duration 请求时延

监控方案

  • 使用 prometheus-nginx-exporter采集 nginx 的 access log,有三种采集方式
    1. 如果有统一存储日志文件的地方就在那里部署 exporter
    2. 如果应用部署在 k8s 上,每台宿主机都在相同的目录存储 nginx 日志,就使用 daemonset 部署 exporter,不侵入pod,但是查询 promQL 需要小心
    3. 如果应用部署在 k8s 上,将 exporter 容器作为 sidecar 与 nginx 容器部署在同一个 pod 里,这个方案比2好
  • 在 exporter 的配置文件中配置解析表达式解析日志文件
  • Prometheus 抓取 exporter 解析转换成的指标

注意

目前 prometheus-nginx-exporter 仅支持普通文本格式的日志解析,不支持 json 格式的,通常 nginx 会配置 json 格式的日志以便输送到 es,可以额外再打印一份普通文本格式的日志用于 exporter 解析。

架构

在这里插入图片描述

配置

服务名为 app1,access log 存储在宿主机的 /var/logs/nginx 目录下。

  1. nginx 配置
log_format main   '{"@timestamp":"$time_iso8601",'
                        '"@source":"$server_addr",'
                        '"hostname":"$hostname",'
                        '"ip":"$http_x_forwarded_for",'
                        '"client":"$remote_addr",'
                        '"request_method":"$request_method",'
                        '"scheme":"$scheme",'
                        '"domain":"$server_name",'
                        '"referer":"$http_referer",'
                        '"request":"$request_uri",'
                        '"args":"$args",'
                        '"size":$body_bytes_sent,'
                        '"status": $status,'
                        '"responsetime":$request_time,'
                        '"upstreamtime":"$upstream_response_time",'
                        '"upstreamaddr":"$upstream_addr",'
                        '"http_user_agent":"$http_user_agent",'
                        '"https":"$https"'
                        '}';

    access_log  /app/logs/access.log  main;
    log_format  prometheus '[$time_local] $request_method "$request" '
                          '$body_bytes_sent $status $request_time $upstream_response_time';
  1. exporter daemonset 配置
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginxlog-exporter-config
  namespace: monitor
data:
  config.yml: |
    namespaces:
    - name: app1
      format: '[$time_local] $request_method "$request" $body_bytes_sent $status $request_time $upstream_response_time'
      source:
        files:
          - /mnt/nginxlog/access1.log      
      relabel_configs:
      - target_label: app
        from: request
        split: 2
        matches:
        - regexp: '/gateway/([a-z]+)(/.*)'
          replacement: $1
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginxlog-exporter
  namespace: monitor
  labels:
    app: nginxlog-exporter
spec:
  selector:
    matchLabels:
      name: nginxlog-exporter
  template:
    metadata:
      labels:
        name: nginxlog-exporter
    spec:
      hostNetwork: true
      containers:
      - name: nginxlog-exporter
        image: quay.io/martinhelmich/prometheus-nginxlog-exporter:v1
        imagePullPolicy: IfNotPresent
        args:
          [
            "-config-file",
            "/etc/prometheus-nginxlog-exporter/config.yml",
            "-enable-experimental",
          ]
        volumeMounts:
        - name: nginxlog-exporter-config
          mountPath: /etc/prometheus-nginxlog-exporter
        - name: container-log
          mountPath: /mnt/nginxlog
          readOnly: true
        ports:
          - name: http
            containerPort: 4040
            protocol: TCP
        readinessProbe:
          tcpSocket:
            port: 4040
          initialDelaySeconds: 5
          periodSeconds: 10
      terminationGracePeriodSeconds: 10
      volumes:
      - name: nginxlog-exporter-config
        configMap:
          name: nginxlog-exporter-config
      - name: container-log
        hostPath:
          path: /var/logs/nginx
  1. grafana proql
    • QPS
    sum by (app)(rate(app1_http_response_count_total[5m])
    
    • 一分钟内错误响应
    increase(app1_http_response_count_total{status=~"4..|5.."}[1m]) > 0
    
    • 90线响应时间
    app1_http_response_time_seconds{method="GET",quantile="0.9"} > 0
    
    • 一分钟内请求数量
    increase(app1_http_response_count_total[1m])
    

http://www.niftyadmin.cn/n/1531804.html

相关文章

【分享】asp.net WebChart 折线图、饼形图、柱状图

折线图形的数据库设计: id int name varchar(50) dataTime datetime 饼形图和柱状图使用同一个表的数据: id int name varchar(50) shuliang int 下面的ChartControl1、ChartControl2、ChartControl3都是从工具箱拖进页面的webChart控…

Prometheus源码学习(4) 通过2.24对实例化Discoverer代码的改进学习依赖倒置

前面读的是 2.19.2 版本的代码,最新更新了 2.24.1,发现在实例化 Discoverer 时改进了设计。这个改变是在 2.21 做出的。 2.19.2 中的实现方式 在 discovery.Manager 结构体中包含了一个 *provider 的 slice type Manager struct {...// providers kee…

类Hashtable(集合)

概述 java.util.Hashtable<K,V>集合 implements Map<K,V>接口Hashtable:底层也是一个哈希表,是一个线程安全的集合,是单线程集合,速度慢HashMap:底层是一个哈希表,是一个线程不安全的集合,是多线程的集合,速度快HashMap集合(之前学的所有的集合):可以存储null值,nu…

第一次开源项目代码贡献 - prometheus-nginxlog-exporter

2021年2月26日&#xff0c;我的第一次开源项目代码贡献被合并了。 这完成了我一个宿愿。几年前老罗向 OpenSSL 捐献手机发布会门票款&#xff0c;我在上班的地铁上看到《隐形战友》这篇文章&#xff0c;有点激动&#xff0c;许下一个心愿&#xff1a;此生哪怕为开源项目贡献一…

Prometheus源码学习(5) notifier

文章目录notifier 模块Alert 结构体Manager 结构体Manager.Run()Manager.sendAll()习得notifier 模块 notifier 模块是用于向 Alertmanager 发送告警通知的。 主要的结构体包括&#xff1a; AlertManagerOptionsalertMetricsalertmanagerLabelsalertmanagerSet Alert 结构体…

c#.net执行应用程序有两种方法

在asp.net中执行应用程序有两种方法&#xff1a;1、调用win32函数ShellExecute。2、用.NET Framework中的Process类。下面我分别用这两种方法执行Windows中的记事本程序notepad.exe。新建一个ASP.Net页面Default.aspx&#xff0c;在上面放一个按钮&#xff0c;进入Default.aspx…

Prometheus源码学习(6) labels

github.com/prometheus/prometheus/pkg/labels 时间序列由一组 Label 唯一标识。labels包中是对 Label 和 Labels 对象的定义和方法。还有一个构建 Labels 的 Builder 对象。 一个标签(Label)就是一个字符串键值对 // Label is a key/value pair of strings. type Label str…

Prometheus源码学习(7) targetgroup

targroup 是抓取目标 // Group is a set of targets with a common label set(production , test, staging etc.). // Group 是一组目标的集合&#xff0c;这组目标有一个共同的标签集。 type Group struct {// Targets is a list of targets identified by a label set. Each…