用fluent-bit 导出nginx logs
在这个章节,我们将会介绍如何使用 fluent-bit,如何配置 nginx,docker 配置日志,以及如何配置 nginx 用 load balancer 和 ssl。
1. 安装 fluent-bit
我们会使用 fluent-bit 的 docker 镜像配合 docker-compose 来安装 fluent-bit。首先,我们需要创建一个 docker-compose.yml 文件,内容如下:
version: "3"
services:
fluent-bit:
image: fluent/fluent-bit
restart: always
command: fluent-bit -c /fluent-bit/etc/fluent-bit.conf
volumes:
- ./conf/fluent-bit:/fluent-bit/etc
- ./log/fluent-bit:/var/log/
network_mode: "host"
解释一下这个文件:
- fluent-bit: 这是我们的服务名称,我们可以通过这个名称来访问这个服务。
- image: 我们使用的 docker 镜像,这里我们使用的是 fluent/fluent-bit。
- restart: 如果服务退出,docker 会自动重启服务。
- command: 这里我们指定了 fluent-bit 的配置文件,这个配置文件在下面会介绍。
- volumes: 这里我们指定了 fluent-bit 的配置文件,以及 fluent-bit 的日志文件。
- network_mode: 这里我们使用了 host 模式,这样我们就可以直接访问宿主机的端口。
我们的文件架构如下:
.
├── conf
│ └── fluent-bit
│ └── fluent-bit.conf
├── data
├── docker-compose.yml
└── log
└── fluent-bit
我们的配置文件如下:
[SERVICE]
Flush 5
Daemon Off
Log_Level info
Log_File /var/log/fluent-bit.log
Parsers_File parsers.conf
[INPUT]
Name forward
Listen 0.0.0.0
Port 24224
[FILTER]
Name Parser
Match *
Parser docker
Key_Name log
[FILTER]
Name Parser
Match *
Parser nginx
Key_Name log
[FILTER]
Name grep
Match *
Exclude remote someip
[OUTPUT]
Name pgsql
Match *
Host somehost
Port 5432
User someuser
Password somepassword
Database fluent
Table fluentbit
Timestamp_Key ts
[OUTPUT]
Name stdout
Match *
解释一下这个文件:
- SERVICE: 这里我们指定了 fluent-bit 的日志文件,以及日志级别。
- INPUT: 这里我们指定了 fluent-bit 的监听端口,这里我们使用的是 24224。
- FILTER: 这里我们指定了 fluent-bit 的过滤器,我们使用了三个过滤器,分别是 Parser,grep,以及 stdout。
- Parser: 这里我们指定了 docker 和 nginx 的日志格式,顺序是先 docker,然后 nginx。原因是我们是从 docker 容器中导出日志,然后再导出到 fluent-bit,所以我们需要先解析 docker 的日志格式。而 docker 日志里包含了 nginx 日志, 所以再解析 nginx 的日志格式。
- grep: 这里我们指定了过滤掉一些 ip 地址。
- OUTPUT: 这里我们指定了 fluent-bit 的输出,我们使用了两个输出,分别是 pgsql 和 stdout。这里我们使用了 pgsql,因为我们需要把日志存储到数据库中,以便后续分析。
2. 配置 nginx
我们使用 nginx 的 docker 镜像,然后配置 nginx 的日志格式,以及 fluent-bit 的日志格式。首先,我们需要创建一个 docker-compose.yml 文件,内容如下:
version: "3"
services:
nginx:
image: nginx
restart: always
ports:
- 80:80
- 443:443
depends_on:
- fluent-bit
volumes:
- ./conf/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./data/nginx:/var/log/nginx
- ./ssl:/etc/ssl
logging:
driver: "fluentd"
options:
fluentd-address: localhost:24224
tag: nginx.access
解释一下这个文件:
- nginx: 这是我们的服务名称,我们可以通过这个名称来访问这个服务。
- image: 我们使用的 docker 镜像,这里我们使用的是 nginx。
- restart: 如果服务退出,docker 会自动重启服务。
- ports: 这里我们指定了 nginx 的端口,80 端口用来访问 http,443 端口用来访问 https。
- depends_on: 这里我们指定了依赖的服务,这里我们依赖 fluent-bit。
- volumes: 这里我们指定了 nginx 的配置文件,以及 nginx 的日志文件。
- logging: 这里我们指定了 fluent-bit 的地址,以及日志的 tag。
danger
在试验中曾经想尝试用fluentd-address: fluent-bit:24224
,但是这样会报错,所以我们使用了fluentd-address: localhost:24224
。
我们的文件架构如下:
tip
我们有一个 ssl 目录,这个目录是用来存放cloudflare
的origin certificates
的。里面保存着两个文件common.crt
和 common.key
.
├── conf
│ └── nginx
│ └── nginx.conf
├── data
├── docker-compose.yml
├── log
│ └── fluent-bit
└── ssl
├── common.crt
└── common.key
我们的配置文件如下:
events {
worker_connections 2000;
}
http {
ssl_certificate /etc/ssl/common.crt;
ssl_certificate_key /etc/ssl/common.key;
log_format postdata '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" "$request_body"';
upstream loadbalancer {
server ip1;
server ip2;
}
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;
real_ip_header CF-Connecting-IP;
server {
listen 443 ssl;
location / {
proxy_pass http://loadbalancer;
access_log /dev/stdout postdata;
}
}
}
解释一下这个文件:
- ssl_certificate: 这里我们指定了 ssl 证书。
- ssl_certificate_key: 这里我们指定了 ssl 证书的 key。
- log_format: 这里我们指定了 nginx 的日志格式,我们使用了
postdata
,这个格式是我们自定义的。里面会包含request_body
,这个字段是我们需要的。 - upstream: 这里我们指定了负载均衡的服务器。
- set_real_ip_from: 这里我们指定了
cloudflare
的 ip 地址段。这样就会把cloudflare
的 ip 地址替换成真实的 ip 地址。 - real_ip_header: 这里我们指定了
cloudflare
的CF-Connecting-IP
来获取真实的 ip 地址。 - server: 这里我们指定了 nginx 的端口,以及日志的输出。
- access_log: 这里我们指定了日志的输出,我们使用了
/dev/stdout
,这样就会把日志输出到标准输出,然后 fluent-bit 就可以把日志收集起来。因为我们使用了postdata
,所以我们的日志格式就是postdata
。
- access_log: 这里我们指定了日志的输出,我们使用了
3. 配置 fluent-bit parsers
我们需要配置 fluent-bit 的 parsers,因为我们需要把request_body
字段解析出来。首先,我们需要创建一个 parsers.conf 文件,内容如下:
[PARSER]
Name nginx
Format regex
Regex ^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)" "(?<body>[^\"]*)")
Time_Key time
Time_Format %d/%b/%Y:%H:%M:%S %z
[PARSER]
Name docker
Format json
Time_Key time
Time_Format %Y-%m-%dT%H:%M:%S.%L
Time_Keep On
之后如果看到之前的fluentbit.conf
文件,里面的parsers_file
就是指向这个文件的。
Parsers_File parsers.conf