Ingress(Nginx)日志持久化与可视化(多图预警)

前端侠
• 阅读 3845

Ingress(Nginx)日志持久化与可视化(多图预警)

[toc]

前言

早期我们通常会使用goaccess或awstat来对nginx等访问日志进行分析和统计,但随着统计分析的多样性以及后续访问日志的实时监控等定制化的需求越来越强烈,goaccess或awstat越来越不能满足我们的需求.所以我们急迫需要更加灵活的日志统计分析工具,能辅助我们对访问日志进行统计、分析和监控.这时候,随着elk/efk的广泛应用,nginx等访问日志也将纳入到elk体系当中,同时elk也能满足我们对日志的统计与分析、监控的多样化需求.

先上图
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)

部署架构

如图,以下是1个很简单的架构,也没有做缓冲和聚合,如果对日志的要求比较高,可以在中间加入redis或Kafka 等.

Ingress(Nginx)日志持久化与可视化(多图预警)

为什么ingress或者nginx的日志要转换成json格式呢?
我这边简单的解释一下:,主要是2个原因:
1:便于结合elasticseach做实时监控和报警.
比如直接监控status字段,如果1分钟连续出现20次4XX报错就直接报警,如果不转换的化,你还需要进一步解析access日志,这样带来了很多的不便.
2:便于结合elk做可视化分析.
可以组合不同的字段,对不同的需求定制不同的可视化报表.

部署步骤

一、ingress持久化步骤

1. 自建kubernetes的ingress持久化

ingress部署参考: https://www.pvcreate.com/index.php/archives/205/
Ingress(Nginx)日志持久化与可视化(多图预警)

(1) ingress添加PVC用于ingress日志存储

kubectl apply -f ingress-nfs.yaml

apiVersion: v1      
kind: PersistentVolumeClaim      
metadata:      
  name: ingress-nfs      
spec:      
  accessModes:      
  - ReadWriteMany      
  resources:      
    requests:      
      storage: 10Gi      
  storageClassName: nfs-client-local      

Ingress(Nginx)日志持久化与可视化(多图预警)

(2) ingress添加挂载

kubectl edit deployments.apps ingress-nginx-controller

        ......      
        volumeMounts:      
        - mountPath: /data/log/ingress/      
          name: ingress-nfs      
      ......      
      volumes:      
      - name: ingress-nfs      
        persistentVolumeClaim:      
          claimName: ingress-nfs      
(3) ingress修改日志格式和存储位置

kubectl edit configmaps ingress-nginx-controller

  access-log-path: /data/log/ingress/access_$hostname.log      
  error-log-path: /data/log/ingress/error.log      
  log-format-upstream: '{"@timestamp": "$time_iso8601","remote_addr": "$remote_addr","x-forward-for":      
    "$proxy_add_x_forwarded_for","request_id": "$req_id","remote_user": "$remote_user","bytes_sent":      
    $bytes_sent,"request_time": $request_time,"status": $status,"vhost": "$host","request_proto":      
    "$server_protocol","path": "$uri","request_query": "$args","request_length": $request_length,"duration":      
    $request_time,"method": "$request_method","http_referrer": "$http_referer","http_user_agent":      
    "$http_user_agent","upstream-sever":"$proxy_upstream_name","proxy_alternative_upstream_name":"$proxy_alternative_upstream_name","upstream_addr":"$upstream_addr","upstream_response_length":$upstream_response_length,"upstream_response_time":$upstream_response_time,"upstream_status":$upstream_status}'      
2. 阿里云kubernetes的ingress持久化

由于阿里云kubernetes上的ingress默认已经部署,同时官方也是建议使用AliyunLogConfig自动接入日志服务和可视化.我们考虑到自定义以及其他原因,采用了自定义接入ingress日志存储,也就是说将ingress存储到nas中,同时发送到elasticsearch中.

Ingress(Nginx)日志持久化与可视化(多图预警)

(1) 通过阿里云控制台为ingress添加nas存储

Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)

(2) ingress添加挂载

kubectl edit deployments.apps -n kube-system nginx-ingress-controller

...      
        volumeMounts:      
        - mountPath: /data      
          name: nfs-oss      
...      
      volumes:      
      - name: nfs-oss      
        persistentVolumeClaim:      
          claimName: ingress-log      
                
(3) ingress修改日志格式和存储位置

kubectl edit configmaps ingress-nginx-controller
修改内容和上面自建kubernetes的ingress一致,需要注意的是如果ingress的日志路径定义为/data/log/ingress/access.log,一定要注意挂载的目录要存在,也就是说你在修改configmaps之前要确保/data/log/ingress提前创建,可以进入pod中创建,也可以在外部创建好.

二、Nginx日志格式修改

除了ingress以外,如果你的nginx也需要同步推送到elasticsearch中的话,也需要修改nginx的日志格式为json,值得注意的是有部分参数ingress和nginx是不一致的,比如ingress中支持req_id而nginx中没有该参数.同时以下参数是添加到nginx.conf的http全局参数当中,添加在server段中无效的.
vim nginx.conf

        log_format json '{"@timestamp": "$time_iso8601","remote_addr": "$remote_addr","x-forward-for":"$proxy_add_x_forwarded_for","remote_user": "$remote_user","bytes_sent":$bytes_sent,"request_time": $request_time,"status": $status,"vhost": "$host","request_proto":"$server_protocol","path": "$uri","request_query": "$args","request_length": $request_length,"duration":$request_time,"method": "$request_method","http_referrer": "$http_referer","http_user_agent":"$http_user_agent","upstream_addr":"$upstream_addr","upstream_response_length":$upstream_response_length,"upstream_response_time":$upstream_response_time,"upstream_status":"$upstream_status"}';      
      
        access_log  /data/log/nginx/access.log  json;      

三、filebeat解析Ingress/Nginx日志

filebeat的安装很简单,这边就不做赘述,我这边主要贴下filebeat的配置文件.
filebeat.yml

setup.template.name: "local-app"      
setup.template.pattern: "local-app-*"      
setup.template.enabled: true      
setup.ilm.enabled: false      
filebeat.config:      
  inputs:      
    path: /data/www/apps/filebeat/inputs.d/*.yml      
    reload.enabled: true      
    reload.period: 10s      
  modules:      
    path: /data/www/apps/filebeat/modules.d/*.yml      
    reload.enabled: false      
output.elasticsearch:      
  protocol: "https"      
  ssl.verification_mode: none      
  hosts: ['192.168.1.100:9200']      
  username: "elastic"      
  password: "123456"      
  index: "local-app-%{[fields.appName]}-%{+yyyy.MM.dd}"      

nginx_ingress.yml

  - type: log      
      
    enable: true      
    tail_files: true      
    # 如果设置为true,Filebeat从文件尾开始监控文件新增内容,把新增的每一行文件作为一个事件依次发送,      
    # 而不是从文件开始处重新发送所有内容      
    paths:      
      - /data/log/nginx/access*.log      
    tags: [app, nginx-local]      
    fields:      
      appName: nginx-local      
      
    json.keys_under_root: true      
    #keys_under_root可以让字段位于根节点,默认为false      
        
    json.overwrite_keys: true      
    #对于同名的key,覆盖原有key值      
        
    json.message_key: message      
    #message_key是用来合并多行json日志使用的,如果配置该项还需要配置multiline的设置,后面会讲      
      
    json.add_error_key: true      
    #将解析错误的消息记录储存在error.message字段中      
        
    json.ignore_decoding_error: true      
    #用于指定是否JSON解码错误应该被记录到日志中。如果设为true,错误将被记录      

要注意的是,如果配置了multiline,会开启合并多条json日志的功能,如果不需要该功能请务必注释掉该yml中关于multiline的配置。(由于我在nginx/ingress中的access的json日志都是一行,所以在nginx日志当中不需要配置multiline配置)
multiline配置:

  #将'['作为新的一行的标识,如果message中不碰到'[',则合并为一条日志      
  multiline.pattern: ^\[      
  multiline.negate: true      
  multiline.match: after      

同时配置:

    processors:      
      - decode_json_fields:      
          fields: ['message']      
          target: json      

四、kibana接入elasticsearch与可视化配置

kibana的安装配置此处不再说明.
添加索引按照界面一步步操作即可.
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)

几个典型图形配置示例
Ingress(Nginx)日志持久化与可视化(多图预警)

(1)PV
Ingress(Nginx)日志持久化与可视化(多图预警)
(2)UV
Ingress(Nginx)日志持久化与可视化(多图预警)
(3)Top10(接口访问量)
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
(4)Top10(客户端IP访问占比)
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
(5)Top10(最慢接口)
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
(6)后端upstream占比
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
(7)实时流量
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
(8)客户端访问占比
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
(9)平均并发数
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
(10)异常状态码统计
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
(11)总流量
Ingress(Nginx)日志持久化与可视化(多图预警)
(12)接口异常响应码
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
(13)接口访问耗时占比
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
(14)每10秒接口访问平均耗时
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
(15)每10秒接口访问最大耗时
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
(16)状态码统计
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
(17)访问量趋势图
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
(18)超过30秒以上的接口
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
(19)超过30秒以上的接口出现次数
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)
Ingress(Nginx)日志持久化与可视化(多图预警)

五、踩坑指南

可视化Metrics无法获取耗时(duration)字段

Top10(最慢接口)举例,获取Top10耗时最慢的url组成1个表格,但是我在Metrics怎么都找不到duration字段或者request_time字段,通过排查得知,Metrics字段一般是数值型字段,对数值型字段求和、求最大值、求平均值等.但是我在ingress定义的字段都是字符串,所以同步到elasticsearch中也是字符串,所以在kibana的Metrics中也无法找到duration字段.既然找到问题症结了,我们就开始修正.重新修改ingress的confimap配置,重新在kibana添加索引.当然添加索引之前,我先删除了原来的索引重新添加.当然这个方法比较粗暴!!还有其他方法可以解决.
(1)如果是logstash可以使用mutate对字段进行转换

mutate {       
 convert => ["name-of-field", "integer"]       
}       

(2)官方没有提供字符串转数值,但我们可以创建1个新的索引,同时把原来的elasticsearch格式化数值后导入即可.

#创建新索引并格式化duration字段      
curl -H 'Content-Type: application/json' -XPUT "http://localhost:9200/ingress_new"      
curl  -H 'Content-Type: application/json' -XPOST "http://localhost:9200/ingress_new/ingress_old/_mapping?pretty" -d '       
{      
    "ingress_old": {      
            "properties": {      
                "duration": {      
                    "type": "double",      
                    "store": "true",      
                    "ignore_malformed": "true"      
                }      
            }      
        }      
  }      
      
#从旧索引中导入数据      
curl  -X POST "localhost:9200/_reindex" -H 'Content-Type: application/json' -d'      
{      
  "source": {      
    "index": "ingress_old"      
    "size": 5000      
  },      
  "dest": {      
    "index": "ingress_new"      
    "routing": "=cat"      
  }      
}'      
      
      
点赞
收藏
评论区
推荐文章
DevOpSec DevOpSec
4年前
nginx配置系列-日志切割
nginx配置系列日志切割背景nginx日志中我们希望日志能够每天或者每小时自动切割,nginx本身没有提供自动切割的机制,但是我们可以通过脚本或者稍加改造让其具备这种能力。下面让我们看看怎么操作吧。日志切割常见做法有四种,在我们做之前我们来学习一下nginx日志中常用的内置变量字段都是什么意思nginx内置变量
Stella981 Stella981
3年前
CentOS 7安装部署ELK 6.2.4
一、ELK介绍ELK是三款开源软件的缩写,即:ElasticSearchLogstashKibana。这三个工具组合形成了一套实用、易用的监控架构,可抓取系统日志、apache日志、nginx日志、mysql日志等多种日志类型,目前很多公司用它来搭建可视化的集中式日志分析平台。ElasticSearch:是一个分布式的R
Wesley13 Wesley13
3年前
nginx日志统计分析
 本文主要使用的是grep,awk,cut等工具来对nginx日志进行统计和分析,具体如下:1,列出当天访问最多次数的ip地址cutdf1/usr/local/nginx/logs/20160329/access\_2016032913.log|uniqc|sortrn|head20 ro
Stella981 Stella981
3年前
Nginx日志运维笔记
在分析服务器运行情况和业务数据时,nginx日志是非常可靠的数据来源,而掌握常用的nginx日志分析命令的应用技巧则有着事半功倍的作用,可以快速进行定位和统计。1)Nginx日志的标准格式(可参考:http://www.cnblogs.com/kevingrace/p/5893499.html(https://www.oschina.net/ac
Stella981 Stella981
3年前
Nginx 日志分析命令
查看日志存放目录\find/nameaccess.log/var/log/nginx/access.logcd/var/log/nginxIP相关统计统计IP访问量(独立ip访问数量)awk'{print$1}'access.log|sortn|uniq|wcl
Wesley13 Wesley13
3年前
LNMP架构之访问日志、日志切割、静态文件不记录及过期时间设置
本文索引:Nginx访问日志Nginx日志切割静态文件不记录日志和过期时间Nginx访问日志修改nginx配置文件root@localhostvhostvim/usr/local/nginx/conf/nginx.conf搜索:/log_format
Stella981 Stella981
3年前
Grafana+Telegraf+Influxdb监控Tomcat集群方案
前言前一段时间自家养的几只猫经常出问题,由于没有有效的监控预警手段,以至于问题出现或者许久一段时间才会被通知到。凌晨一点这个锅可谁都不想背,为此基于目前的情况搭建了以下这么一套监控预警系统。相关软件Nginx:代理访问GrafanaGrafana:可视化面板(Dashboard),有着非常漂亮的图表
Stella981 Stella981
3年前
ELK项目es+kibana+jdk配置问题
简介ELK需求背景业务发展越来越庞大,服务器越来越多各种访问日志、应用日志、错误日志量越来越多开发人员排查问题,需要到服务器上查日志,不方便运营人员需要一些数据,需要我们运维到服务器上分析日志说白了就是日志那么多我要给你们搞牛逼的系统如果有机会再搞日志系统加消息列队eskafka消化来的数据ELK包含Elasti
Stella981 Stella981
3年前
Logstash收集nginx访问日志和错误日志
1、收集访问日志1)、首先是要在nginx里面配置日志格式化输出log_formatmain"$http_x_forwarded_for|$time_local|$request|$status|$body_bytes_sent|$request_body|$content_length|$http_ref
Stella981 Stella981
3年前
Kafka文件存储机制那些事
Kafka是什么Kafka是最初由Linkedin公司开发,是一个分布式、分区的、多副本的、多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx日志、访问日志,消息服务等等,Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目。1.前言一个商
python定时任务执行shell脚本切割Nginx日志-慎用
Python定时任务执行shell脚本切割Nginx日志(慎用)缘起我们有一个Nginx服务用来接收埋点上报数据,输出的日志文件比较大,Nginx没有自带日志分割组件,这样输出的日志文件就比较大,抽取日志就比较麻烦。网上切割日志的方式一般就两种:logra