使用 Loki 收集 nginx 日志
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.下载两者的配置文件
wget https://raw.githubusercontent.com/grafana/loki/master/cmd/loki/loki-local-config.yaml
wget https://raw.githubusercontent.com/grafana/loki/master/cmd/promtail/promtail-local-config.yaml
6.使用如下命令启动Loki
./loki-linux-amd64 -config.file=loki-local-config.yaml
cd /usr/local/loki/
ls
loki-linux-amd64 loki-local-config.yaml promtail-linux-amd64 promtail-local-config.yaml
./loki-linux-amd64 -config.file=loki-local-config.yaml
尝试搜集nginx日志
1.首先对nginx默认的日志进行改造,让他以json的方式进行输出到目录,然后用Promtail对其进行读取。
2.读取使用LogQL的json方式去读取,这个LogQL内容填写在grafana中。
nginx的部分配置改造
promtail_json日志格式配置
log_format promtail_json '{"@timestamp":"$time_iso8601",'
'"@version":"Promtail json",'
'"server_addr":"$server_addr",'
'"remote_addr":"$remote_addr",'
'"host":"$host",'
'"uri":"$uri",'
'"body_bytes_sent":$body_bytes_sent,'
'"bytes_sent":$body_bytes_sent,'
'"request":"$request",'
'"request_length":$request_length,'
'"request_time":$request_time,'
'"status":"$status",'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent"'
'}';
虚拟server配置
server {
server_name loki.test.com; # 域名设置
listen 8888;
access_log /var/log/nginx/loki_access.log promtail_json;
location / {
return 200 "It's ok!";
}
}
访问127.0.0.1:8888,观察日志已经正常输出为json格式,请保证该json格式正确。
root@test:/etc/nginx/conf.d$tail -f /var/log/nginx/loki_access.log
{"@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的配置文件。
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/loki-positions.yaml # 记录pos点
sync_period: 5s # 5s一次将当前读取到的pos点同步至filename配置的文件内
clients:
- url: http://localhost:3100/loki/api/v1/push
scrape_configs:
- job_name: Loki
static_configs:
- labels: # 设定的部分标签
job: Loki-nginx
host: localhost
app: nginx
__path__: /var/log/nginx/loki_access.log # 待读取的nginx日志
LogQL json部分文档理解
json的提取分为两种方式,带参数和不带参数
1.不带参数的方式
- 使用
|json
来提取日志的json内容,前提是json内容为有效json格式。 - 嵌套的字段会用”_”将内外层的key进行拼接。
- 忽略数组。
看一下官网中不带参数方式的样例
{
"protocol": "HTTP/2.0",
"servers": ["129.0.1.1","10.2.1.3"],
"request": {
"time": "6.032",
"method": "GET",
"host": "foo.grafana.net",
"size": "55",
"headers": {
"Accept": "*/*",
"User-Agent": "curl/7.68.0"
}
},
"response": {
"status": 401,
"size": "228",
"latency_seconds": "6.031"
}
}
被json解后,得到如下:
"protocol" => "HTTP/2.0"
"request_time" => "6.032"
"request_method" => "GET"
"request_host" => "foo.grafana.net"
"request_size" => "55"
"response_status" => "401"
"response_size" => "228"
"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"]
进行提取
{
"protocol": "HTTP/2.0",
"servers": ["129.0.1.1","10.2.1.3"],
"request": {
"time": "6.032",
"method": "GET",
"host": "foo.grafana.net",
"size": "55",
"headers": {
"Accept": "*/*",
"User-Agent": "curl/7.68.0"
}
},
"response": {
"status": 401,
"size": "228",
"latency_seconds": "6.031"
}
}
输出结果为:
"first_server" => "129.0.1.1"
"ua" => "curl/7.68.0"
first_server和ua都为原先参数中指定的key
如果要提取整个对象,可以使用| json server_list=”servers”, headers=”request.headers
这样就能得到如下输出:
"server_list" => `["129.0.1.1","10.2.1.3"]`
"headers" => `{"Accept": "*/*", "User-Agent": "curl/7.68.0"}`
尝试写一条LogQL表达式
一条完整的LogQL表达式由两部分构成:
- a log stream selector,可以理解为,通过设定的label去匹配要抓取哪些日志。
- a log pipeline,可以理解为表达式。比如json的提取。
比如如下表达式
{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后面直接跟随|statu
s即可,即|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]))
使用 Loki 收集 nginx 日志的更多相关文章
- ELK Stack (2) —— ELK + Redis收集Nginx日志
ELK Stack (2) -- ELK + Redis收集Nginx日志 摘要 使用Elasticsearch.Logstash.Kibana与Redis(作为缓冲区)对Nginx日志进行收集 版本 ...
- ELK filter过滤器来收集Nginx日志
前面已经有ELK-Redis的安装,此处只讲在不改变日志格式的情况下收集Nginx日志. 1.Nginx端的日志格式设置如下: log_format access '$remote_addr - $r ...
- ELK日志系统之使用Rsyslog快速方便的收集Nginx日志
常规的日志收集方案中Client端都需要额外安装一个Agent来收集日志,例如logstash.filebeat等,额外的程序也就意味着环境的复杂,资源的占用,有没有一种方式是不需要额外安装程序就能实 ...
- 安装logstash5.4.1,并使用grok表达式收集nginx日志
关于收集日志的方式,最简单性能最好的应该是修改nginx的日志存储格式为json,然后直接采集就可以了. 但是实际上会有一个问题,就是如果你之前有很多旧的日志需要全部导入elk上查看,这时就有两个问题 ...
- ELK 二进制安装并收集nginx日志
对于日志来说,最常见的需求就是收集.存储.查询.展示,开源社区正好有相对应的开源项目:logstash(收集).elasticsearch(存储+搜索).kibana(展示),我们将这三个组合起来的技 ...
- 第七章·Logstash深入-收集NGINX日志
1.NGINX安装配置 源码安装nginx 因为资源问题,我们先将nginx安装在Logstash所在机器 #安装nginx依赖包 [root@elkstack03 ~]# yum install - ...
- ELASTIC 5.2部署并收集nginx日志
elastic 5.2集群安装笔记 设计架构如下: nginx_json_log ->filebeat ->logstash ->elasticsearch ->kiban ...
- rsyslog收集nginx日志配置
rsyslog日志收集配置 rsyslog服务器收集各服务器的日志,并汇总,再由logstash处理 请查看上一篇文章 http://bbotte.blog.51cto.com/6205307/16 ...
- EFK收集nginx日志
准备三台centos7的服务器 两核两G的 关闭防火墙和SELinux systemctl stop firewalld setenforce 0 1.每一台都安装jdk rpm -ivh jdk-8 ...
随机推荐
- java,捕获和抛出异常
package Exrro; public class Test { //ctrl + alt + T快速生成异常捕捉 public static void main(String[] args) { ...
- IDea折叠模块快捷键-*04
如何折叠IntelliJ IDEA代码片段 IntelliJ IDEA 快捷键说明大全(转载) idea 字体_IDEA 新手实用插件分享:让你的 IDEA 逼格瞬间提升
- intellidea 快捷键-*01
快捷键: 0.竖向选择文本: alt+shift+insert:https://www.cnblogs.com/JonaLin/p/11422110.html 如果想修改快捷键(setting-> ...
- 74HC595驱动(并转串,fpga与时钟匹配,fpga与外部芯片的连接注意事项)
上一次设计的动态扫描数码管显示电路模型如上,这是一个32位并行数据[31:0]disp_num选通输出并行数据[7:0]select和[7:0]段选的电路.因此需要输出16个信号 而在开发板上的电路与 ...
- 绝对路径和相对路径和File类的构造方法
路径: 绝对路径:是一个完整的路径 以盼复(C:,D:)开始的路径 c:\a.txt C:\User\itcast\IdeaProjects\shungyuan\123.txt D:\demo\b.t ...
- 迭代器和增强for循环
iterator 迭代:即Collection集合元素的通过获取方法,在获取元素之前先要判断集合中有没有元素,如果有就把这个元素取出来,然后在判断,如果还有就再去除卡u,一直把集合中的所有元素全部拿出 ...
- for循环和while循环dowhile循环
第四章 循环语句 4.1循环概述 循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段代码被重复执行的代码被称为循环体语句,当反复执行这个循环体的时候,需要在核实的时候吧循环判断条件修改为fa ...
- 6.15 NOI 模拟
\(T1\ ckr\)与平方数 不会吧,不会吧,真有人不会积分,好吧,我真的一点也不会... 基本公式\(:\) \(1.\)多项式定积分的计算方法 \[f(x)=\sum_{i=0}^nc_ix^i ...
- Python 汽车之家 全系车型参数(包含历史停售车型) 最全
本文仅供学习交流使用,如侵立删!联系方式及demo下载见文末 汽车之家2021 全系车型参数(包含历史停售车型) 2021.10.21更新 增加参数:电动扰流板.无框设计车门.隐藏电动门把手.自动驾驶 ...
- Prometheus+Grafana+钉钉部署一个单机的MySQL监控告警系统
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. GreatSQL是MySQL的国产分支版本,使用上与MySQL一致. 目录 一.Prometheus 二.exporter ...