使用 Loki 收集 nginx 日志

打印 上一主题 下一主题

主题 548|帖子 548|积分 1644

转载自:https://mp.weixin.qq.com/s?__biz=MzU4MjQ0MTU4Ng==&mid=2247492075&idx=1&sn=ba63984111671a2590ebc82b60441b74&chksm=fdbaeef6cacd67e0a001731c2caab8a3dd7ea41850c7bed04efd986679e54454838ef3f6a32b&cur_album_id=1837018771652149250&scene=190#rd
ELK在日志方面给我的感觉是大而全,查询匹配是杠杠的,Kibana图表非常丰富。但如果面对大量的数据,需要查询,在不堆机器的情况下,还是会比较疲软,查询比较慢,之前公司每当突发流量的时候,由于日志写入比较大,队列都在kafka,es消费慢,导致无法实时出数据。
Loki 受到了 prometheus启 发,对日志进行打标签的方式而非全文索引的方,而且也可以跟kubernetes集成。
安装Loki(使用Local方式)

安装和运行

1、https://github.com/grafana/loki/releases/
2.找到要安装的版本,我采用的是v2.1.0
3.下载Loki和Promtail, (Loki为日志的引擎,通过Promtail来发送日志到Loki)
4.在本机找一个目录存放这两个2进制文件
5.下载两者的配置文件
  1. wget https://raw.githubusercontent.com/grafana/loki/master/cmd/loki/loki-local-config.yaml
  2. wget https://raw.githubusercontent.com/grafana/loki/master/cmd/promtail/promtail-local-config.yaml
复制代码
6.使用如下命令启动Loki
  1. ./loki-linux-amd64 -config.file=loki-local-config.yaml
复制代码
  1. cd /usr/local/loki/
  2. ls
  3. loki-linux-amd64  loki-local-config.yaml  promtail-linux-amd64  promtail-local-config.yaml
  4. ./loki-linux-amd64 -config.file=loki-local-config.yaml
复制代码
尝试搜集nginx日志

1.首先对nginx默认的日志进行改造,让他以json的方式进行输出到目录,然后用Promtail对其进行读取。
2.读取使用LogQL的json方式去读取,这个LogQL内容填写在grafana中。
nginx的部分配置改造

promtail_json日志格式配置
  1. log_format promtail_json '{"@timestamp":"$time_iso8601",'
  2.         '"@version":"Promtail json",'
  3.         '"server_addr":"$server_addr",'
  4.         '"remote_addr":"$remote_addr",'
  5.         '"host":"$host",'
  6.         '"uri":"$uri",'
  7.         '"body_bytes_sent":$body_bytes_sent,'
  8.         '"bytes_sent":$body_bytes_sent,'
  9.         '"request":"$request",'
  10.         '"request_length":$request_length,'
  11.         '"request_time":$request_time,'
  12.         '"status":"$status",'
  13.         '"http_referer":"$http_referer",'
  14.         '"http_user_agent":"$http_user_agent"'
  15.         '}';
复制代码
虚拟server配置
  1. server {
  2.     server_name  loki.test.com; # 域名设置
  3.     listen       8888;
  4.     access_log /var/log/nginx/loki_access.log promtail_json;
  5.     location / {
  6.         return 200 "It's ok!";
  7.     }
  8. }
复制代码
访问127.0.0.1:8888,观察日志已经正常输出为json格式,请保证该json格式正确。
  1. root@test:/etc/nginx/conf.d$tail -f /var/log/nginx/loki_access.log
  2. {"@timestamp":"2021-03-06T01:54:42-05:00","@version":"Promtail json","server_addr":"127.0.0.1","remote_addr":"192.168.65.130","host":"127.0.0.1","uri":"/","body_bytes_sent":8,"bytes_sent":8,"request":"GET / HTTP/1.1","request_length":78,"request_time":0.000,"status":"200","http_referer":"-","http_user_agent":"curl/7.29.0"}
复制代码
nginx日志改造完毕
Promtail配置文件修改

1.因为搜集日志是Promtail处理,所以自然而然是需要根据自己需求来配置Promtail的配置文件。
  1. server:
  2.   http_listen_port: 9080
  3.   grpc_listen_port: 0
  4. positions:
  5.   filename: /tmp/loki-positions.yaml  # 记录pos点
  6.   sync_period: 5s # 5s一次将当前读取到的pos点同步至filename配置的文件内
  7. clients:
  8.   - url: http://localhost:3100/loki/api/v1/push
  9. scrape_configs:
  10. - job_name: Loki
  11.   static_configs:
  12.   - labels: # 设定的部分标签
  13.      job: Loki-nginx
  14.      host: localhost
  15.      app: nginx
  16.      __path__: /var/log/nginx/loki_access.log # 待读取的nginx日志
复制代码
LogQL json部分文档理解

json的提取分为两种方式,带参数和不带参数
1.不带参数的方式

  • 使用|json来提取日志的json内容,前提是json内容为有效json格式。
  • 嵌套的字段会用”_”将内外层的key进行拼接。
  • 忽略数组。
看一下官网中不带参数方式的样例
  1. {
  2.     "protocol": "HTTP/2.0",
  3.     "servers": ["129.0.1.1","10.2.1.3"],
  4.     "request": {
  5.         "time": "6.032",
  6.         "method": "GET",
  7.         "host": "foo.grafana.net",
  8.         "size": "55",
  9.         "headers": {
  10.           "Accept": "*/*",
  11.           "User-Agent": "curl/7.68.0"
  12.         }
  13.     },
  14.     "response": {
  15.         "status": 401,
  16.         "size": "228",
  17.         "latency_seconds": "6.031"
  18.     }
  19. }
复制代码
被json解后,得到如下:
  1. "protocol" => "HTTP/2.0"
  2. "request_time" => "6.032"
  3. "request_method" => "GET"
  4. "request_host" => "foo.grafana.net"
  5. "request_size" => "55"
  6. "response_status" => "401"
  7. "response_size" => "228"
  8. "response_size" => "228"
复制代码
从输出能看到,原本request字段内容为嵌套,所以request里面的内容的key验证了如上第二点,使用”_”进行了拼接。同时servers由于是个数组,所以在解析后直接丢弃了servers这个key,验证了第三点。
2.带参数的方式

  • 带参数的方式,json只会根据参数来解开需要的部分(当单条json数据比较大的时候应该能省很多资源)。
  • 使用| json label=”expression”, another=”expression”的方式来编写该方法。可以存在多个参数
看一下官网中带参数方式的样例
使用| json first_server=”servers[0]”, ua=”request.headers["User-Agent"]进行提取
  1. {
  2.     "protocol": "HTTP/2.0",
  3.     "servers": ["129.0.1.1","10.2.1.3"],
  4.     "request": {
  5.         "time": "6.032",
  6.         "method": "GET",
  7.         "host": "foo.grafana.net",
  8.         "size": "55",
  9.         "headers": {
  10.           "Accept": "*/*",
  11.           "User-Agent": "curl/7.68.0"
  12.         }
  13.     },
  14.     "response": {
  15.         "status": 401,
  16.         "size": "228",
  17.         "latency_seconds": "6.031"
  18.     }
  19. }
复制代码
输出结果为:
  1. "first_server" => "129.0.1.1"
  2. "ua" => "curl/7.68.0"
复制代码
first_server和ua都为原先参数中指定的key
如果要提取整个对象,可以使用| json server_list=”servers”, headers=”request.headers 这样就能得到如下输出:
  1. "server_list" => `["129.0.1.1","10.2.1.3"]`
  2. "headers" => `{"Accept": "*/*", "User-Agent": "curl/7.68.0"}`
复制代码
尝试写一条LogQL表达式

一条完整的LogQL表达式由两部分构成:

  • a log stream selector,可以理解为,通过设定的label去匹配要抓取哪些日志。
  • a log pipeline,可以理解为表达式。比如json的提取。
比如如下表达式
  1. {container="query-frontend",namespace="tempo-dev"} |= "metrics.go" | logfmt | duration > 10s and throughput_mb < 500
复制代码
{container=”query-frontend”,namespace=”tempo-dev”} 部分为log stream selector,后面部分为log pipeline。
编写一个简单的nginx日志需求


  • Loki-nginx日志中状态码为200的条数。
  • 根据当前选定时间范围,自动调整。
思考:
1.如何指定Loki-nginx,可以使用log stream selector的表达式来选定。
2.nginx日志已经转变为了json,所以可以用|json来提取。
3.如何获取status字段的信息? |json后面直接跟随|status即可,即|json|status。
4.如何根据当前选定的时间范围?使用内置变量[$\_\_interval]。
5.条数该得用什么方法获得?LogQL有内置函数count_over_time配合sum,这边需要注意的是count_over_time是根据指定时间范围返回日志条目的具体内容,所以还需要配合sum获得时间段内的总数。
编写:
1.首先选定Loki-nginx的日志,{job="Loki-nginx"}。
2.使用count_over_time函数配合[$\_\_interval]来获取总共的条数。count_over_time({job="Loki-nginx"}[$\_\_interval])
3.过滤status字段,让其等于200,表达式count_over_time({job="Loki-nginx"} | json | status = 200 [$\_\_interval]),此时会报错,因为status为字符串,可以添加__error__=””让其忽略转换出现的异常。得到count_over_time({job="Loki-nginx"} | json | status = 200 \_\_error\_\_="" [$\_\_interval])
4.此时在grafana上显示为多条数据,配合sum得到单独一个数值。
5.最终的表达式为:sum(count_over_time({job="Loki-nginx"} | json | status = 200 __error__="" [$__interval]))

原文链接:https://kirakirazone.com/2021/03/06/Loki日志服务01/

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

飞不高

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表