Fluentd搭建日志收集服务


Posted in Servers onSeptember 23, 2022

引言

公司需要搭建一个日志收集服务器,用于将公司的项目日志汇总到一台服务器上面,方便查看和减轻各项目服务器压力。但是由于目前资源不够充足,所以放弃使用ELK、EFK。最后在调研尝试过Linux自带的Syslog和fluentd之后,Linux自带的Syslog虽然更简单,但是汇总的数据中会有乱码的情况(怀疑是Appender问题),并且将日志信息组合成Json格式比较麻烦,因此选择使用fluentd来做日志收集。

1. 搭建环境准备工作

选用fluentd来做日志收集选择使用源码来进行安装,并且需要安装一些依赖的插件,如Ruby等,下面依次介绍需要安装的组件。

1.1 安装ruby

下载ruby压缩包 ruby-2.6.5.tar.gz,版本:2.6.5,并解压

tar -zxvf ruby-2.6.5.tar.gz
cd ruby-2.6.5

安装ruby,安装需要gcc

yum install -y gcc
./configure prefix=/export/source/ruby
make && make install

安装完成后修改系统配置文件 /etc/profile,在最后添加ruby目录并加到path中

export RUBY_HOME=/export/source/ruby
export PATH=$PATH:$JAVA_HOME/bin:$RUBY_HOME/bin

验证是否安装成功

[root@localhost ruby-2.6.5]# ruby -v
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-linux]

显示ruby版本号,安装成功

1.2 获取fluentd源码

从github上拉取fluentd源码,github地址:fluentd

git clone https://github.com/fluent/fluentd.git
cd fluentd

1.3 修改gem源

先查看当前默认源

gem source
*** CURRENT SOURCES ***
https://rubygems.org/

移除默认源

gem sources -r https://rubygems.org/

添加源,目前可用的有ruby-china的源,添加ruby-china源

gem sources -a https://gems.ruby-china.com
https://gems.ruby-china.com added to sources
# 查看当前源
gem source
*** CURRENT SOURCES ***
https://gems.ruby-china.com

更新缓存

gem sources -u

1.4 安装Bundle

gem install bundler

等待提示安装成功

1.5 构建fluentd

进入fluentd文件夹后,构建项目

[root@localhost fluentd]# bundle install
Fetching gem...
...
Bundle complete! 11 Gemfile dependencies, 37 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
[root@localhost fluentd]# bundle exec rake build
fluentd 1.7.3 built to pkg/fluentd-1.7.3.gem.
[root@localhost fluentd]# gem install pkg/fluentd-1.7.3.gem
Successfully installed fluentd-1.7.3
Parsing documentation for fluentd-1.7.3
Installing ri documentation for fluentd-1.7.3
Done installing documentation for fluentd after 3 seconds
1 gem installed

安装完成

1.6 运行fluentd

[root@localhost fluentd]# fluentd --setup ./fluent
[root@localhost fluentd]# fluentd -c ./fluent/fluent.conf -vv &

最后在控制台显示fluentd读取的配置文件信息并且打印相关日志。至此日志收集服务器所需要的fluentd已经搭建完成,接下来就是配置fluentd以完成日记收集功能。

2. 安装过程遇到的问题

2.1 安装bundler没有zlib包

ERROR: Loading command: install (LoadError)
 cannot load such file -- zlib
ERROR: While executing gem ... (NoMethodError)
    undefined method `invoke_with_build_args' for nil:NilClass

解决方案 安装zlib-devel

yum -y install zlib-devel

进入ruby源码文件夹,安装ruby自身提供的zlib包ruby-2.5.1/ext/zlib

cd ruby-2.6.5/ext/zlib
ruby ./extconf.rb
make
make install

在make时会报错

make: *** No rule to make target `/include/ruby.h', needed by `zlib.o'.  Stop.

修改目录中Makefile文件

zlib.o: $(top_srcdir)/include/ruby.h

改成

zlib.o: ../../include/ruby.h

到这里就可以make成功了。

2.2 没有openssl

错误描述:cannot load such file -- openssl

/export/source/ruby/lib/ruby/2.6.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- openssl (LoadError)
	29: from /export/source/ruby/bin/gem:21:in `<main>'
	28: from /export/source/ruby/lib/ruby/2.6.0/rubygems/gem_runner.rb:59:in `run'
	27: from /export/source/ruby/lib/ruby/2.6.0/rubygems/command_manager.rb:148:in `run'
	26: from /export/source/ruby/lib/ruby/2.6.0/rubygems/command_manager.rb:178:in `process_args'
...
/export/source/ruby/lib/ruby/2.6.0/rubygems/request.rb:84:in `rescue in configure_connection_for_https': Unable to require openssl, install OpenSSL and rebuild Ruby (preferred) or use non-HTTPS sources (Gem::Exception)
	22: from /export/source/ruby/bin/gem:21:in `<main>'
	21: from /export/source/ruby/lib/ruby/2.6.0/rubygems/gem_runner.rb:59:in `run'
	20: from /export/source/ruby/lib/ruby/2.6.0/rubygems/command_manager.rb:148:in `run'
	19: from /export/source/ruby/lib/ruby/2.6.0/rubygems/command_manager.rb:178:in `process_args'
	...

解决方案

yum install openssl-devel -y

在ruby自身提供的额外文件夹中ruby-2.6.5/ext/openssl,执行ruby ./extconf.rb,再make

ruby ./extconf.rb
make
make install

make时出错

make: *** No rule to make target `/include/ruby.h', needed by `ossl.o'.  Stop.

修改Makefile文件,在文件顶部添加top_srcdir = ../..

3. 完成需求及修改配置

在上一节中完成了在日志服务器上单间fluentd,该日志收集服务器有五个需求,通过修改fluentd等配置文件来完成相关的需求。

需求1 日志存放路径应用+日期划分

修改配置文件,在 模块中添加path属性,如果需要将匹配相同的tag输出到不同文件中则需要将 的@type设置为copy,然后再 块中添加 块并在 中添加path属性。

在path属性中可以读取过滤的tag,tag的格式为logback配置文件中的.,因此可以将应用名设定在logback配置文件中,然后再fluentd.conf中进行读取。在path中通过${tag}占位符读取客户端发送的tag,tag属性可以根据.切分为数组,例如tag为test.demo时,tag[0]表示test,tag[1]表示demo。对于时间的配置可直接在path路径中设置,并且在buffer块加上time及timekey配置,配置文件如下:

<store>
    @type file
    @id   demo
    path         /data/log/${tag[3]}/${tag[4]}/%Y-%m-%d/${tag[4]}
    symlink_path /data/tmp/${tag[3]}_${tag[4]}_data.log
    append      false
    time_slice_wait   10m
    time_slice_format %Y%m%d
    <buffer tag, time>
      flush_mode                interval
      flush_interval            30s
      chunk_limit_size          5MB
      timekey                   1d
    </buffer>
  </store>

最后得到的目录如下

├── [  21]  dab
│   └── [  56]  logdemo
│       ├── [4.0K]  2019-10-14
│       │   ├── [3.2M]  logdemo.20191014_0.log
│       │   ├── [3.2M]  logdemo.20191014_1.log
│       │   ├── [3.5M]  logdemo.20191014_2.log
│       │   ├── [3.9M]  logdemo.20191014_3.log
│       │   ├── [4.3M]  logdemo.20191014_4.log
│       │   ├── [4.2M]  logdemo.20191014_5.log
├── [  27]  sms
│   └── [  62]  opapplication
│       ├── [ 114]  2019-10-14
│       │   ├── [2.5M]  opapplication.20191014_0.log
│       │   ├── [4.3M]  opapplication.20191014_1.log

需求2 存放日志文件按文件大小进行切分

修改配置文件,在match块中添加buffer块配置,配置内容如下

<match level.com.zhy.**>
    @type file
    @id   demo
    path         /data/log/${tag[3]}/${tag[4]}/%Y-%m-%d/${tag[5]}/${tag[4]}_${tag[5]}
    symlink_path /data/tmp/${tag[3]}_${tag[4]}_data.log
    # 不追加日志文件
    append      false
    <buffer tag, time>
      # 刷新模式
      flush_mode                interval    
      # 刷新周期
      flush_interval            10s
      # 块大小限制
      chunk_limit_size          5MB
      timekey                   1d
    </buffer>
  </store>
</match>

将buffer刷新模式修改为interval按固定时间间隔刷新,并且设置刷新的周期以及不追加文件。这样当buffer有内容时,每过10s将日志文件保存一次,或者当buffer块达到5MB就立即存一次,保证每个日志文件的大小都保证在5MB以内。生成的日志目录结构如下:

.
├── [  21]  dab
│   └── [  56]  logdemo
│       ├── [4.0K]  2019-10-14
│       │   ├── [3.2M]  logdemo.20191014_0.log
│       │   ├── [1.7M]  logdemo.20191014_10.log
│       │   ├── [1.9M]  logdemo.20191014_11.log
│       │   ├── [3.2M]  logdemo.20191014_1.log
│       │   ├── [3.5M]  logdemo.20191014_2.log
│       │   ├── [3.9M]  logdemo.20191014_3.log
│       │   ├── [4.3M]  logdemo.20191014_4.log
│       │   ├── [4.2M]  logdemo.20191014_5.log
│       │   ├── [4.5M]  logdemo.20191014_6.log
│       │   ├── [4.8M]  logdemo.20191014_7.log
│       │   ├── [4.8M]  logdemo.20191014_8.log

需求3 按照日志等级划分日志

为方便查看各类等级日志的情况,需要在目录中添加日志等级并将相应的日志放入。在不修改客户端tag情况下,在fluentd服务端重新生成tag以包含日志等级,此时需要 rewrite_tag_filter 插件来完成重置tag。在使用插件前需要安装该插件

[root@localhost fluentd]$ fluent-gem install fluent-plugin-rewrite-tag-filter
Fetching fluent-plugin-rewrite-tag-filter-2.2.0.gem
Fetching fluent-config-regexp-type-1.0.0.gem
Successfully installed fluent-config-regexp-type-1.0.0
Successfully installed fluent-plugin-rewrite-tag-filter-2.2.0
Parsing documentation for fluent-config-regexp-type-1.0.0
Installing ri documentation for fluent-config-regexp-type-1.0.0
Parsing documentation for fluent-plugin-rewrite-tag-filter-2.2.0
Installing ri documentation for fluent-plugin-rewrite-tag-filter-2.2.0
Done installing documentation for fluent-config-regexp-type, fluent-plugin-rewrite-tag-filter after 0 seconds
2 gems installed

然后在fluent.conf配置文件中配置

<match com.zhy.**>
  @type rewrite_tag_filter
  <rule>
    key msg
    pattern ^\[(\w+)\]
    tag level.${tag}.$1
  </rule>
</match>

原来的输入日志格式如下

2019-10-14 14:44:09.000000000 +0800 com.zhy.sms.opapplication: {"msg":"[ERROR] 这是error日志...error\r\n","level":"ERROR","logger":"com.sk.controller.LogController","thread":"pool-3-thread-397","message":"这是error日志...error"}

在日志信息中msg、level对应的值都包含日志等级,因此可以从键msg、level中选出日志等级来组成新的tag,这里选则提取msg对应的value中的日志等级。配置文件中的pattern属性所写正则表达式就是用来匹配msg中[]中的值的,然后再tag上将取出来的日志等级通过$1放到原来tag的最后面。

注意:如果match上的匹配规则和修改后的tag能够对应,则会一直进行匹配,从而导致修改tag失败,如下

<match com.zhy.**>
  @type rewrite_tag_filter
  <rule>
    key msg
    pattern ^\[(\w+)\]
    tag ${tag}.$1
  </rule>
</match>

此时修改后的tag仍然是以com.zhy开头,所以会导致修改失败,所以在新的tag前加上level前缀,level可自定义

<match com.zhy.**>
  @type rewrite_tag_filter
  <rule>
    key msg
    pattern ^\[(\w+)\]
    tag level.${tag}.$1
  </rule>
</match>

需求4 将目录通过nginx映射出去

在nginx配置文件中增加server配置,在server中添加root属性,设置映射到服务器根目录下的/data目录中,location属性分为两步第一步开启文件浏览,第二步设置在浏览器文本格式显示文件内容

location     /log {
    autoindex  on;
}

通过autoindex来开启文件浏览功能,配置客户端浏览路径为/log

location    ^/log/.*\.log$  {
    add_header Content-Type  text/plain;
}

首先通过正则表达式匹配浏览路径,匹配规则以/log开头并且以.log结尾的文件,然后设置Content-Type为text/plain,在浏览器便可直接浏览日志内容,如果不设置将会弹出下载窗口进行下载,并且需要清理浏览器的缓存

server {
        listen       8002;
        autoindex_exact_size off;
        charset utf-8;
        autoindex_localtime on;
        root         /data;
        location     /log {
                autoindex       on;
        }
        location    ^/log/.*\.log$  {
                add_header Content-Type         text/plain;
        }
    }

需求5 生成一个定大小的日志文件,并能够即时查看日志

需求是希望能够在项目文件夹下生成一个日志文件,与前面的日志文件不同的是该日志是显示当前日志内容,并且大小固定。由于fluentd的append生成的文件虽然能够追加到一个文件中,但是不能够固定大小,日志大小会无限膨胀。通过查阅资料,最后选择使用linux自带的日志转存工具 logrotate 来实现这需求。

由于目前linux都会自带logrotate,所以不需要安装,比较便捷。并且logrotate在github的更新还是比较活跃的。github地址:logrotate

1.修改配置

在使用logrotate之前,先修改fluentd配置,使其在每个项目中生成一个对应的即时日志文件。在 match 块中添加一个 store 块。

<store>
    @type file
    @id   ImmediateLog
    path         /data/log/${tag[3]}/${tag[4]}/${tag[4]}_immediate
    append    true
    <buffer tag>
        path                      /data/tmp/${tag[3]}/${tag[4]}/${tag[4]}_immediate
        flush_mode                interval
        flush_interval            5s
    </buffer>
</store>

配置中主要是在对应项目文件夹下生成一个名为 appname_immediate.log 的日志文件,并且该日志文件用append追加内容,选择以5s为周期性刷新,由于是即时日志文件,所以刷新频率高。之所以不用immediate模式是因为考虑的服务器负载,如果立即刷新的话可能会造成负载较高,所以选用延迟几秒来追加日志内容

然后修改logrotate配置文件,器配置文件在 /etc/logrotate.conf 中,但是在该配置文件中不方便管理,因此可以自己写一个配置文件,保存到 /etc/logrotate.d 目录中,在该目录中已经保存有几个自带的logrotate配置。这里我们新建一个配置文件,命名 applog ,并在文件中添加配置项:

/data/log/*/*/*_immediate.log {
     daily             # 每天运行
     rotate 3          # 转存文件最多三个
     size 10M          # 当待转存文件大于10MB时才转存
     compress          # 压缩转存文件
     copytruncate      # 复制转存文件并且清空原文件
 }

logrotate配置文件中第一行表示在配置转存文件的路径,这里转存的是在/data/log目录下的所有以_immediate.log结尾的文件,路径配置可以使用通配符。其余配置见注释,这里主要的作用时每天转存一次日志文件,当文件大小超过10MB时转存,并且进行压缩,转存文件最多存在3个。其余配置参考官网:logrotate配置详解

在完成配置后,可以通过命令查看配置文件是否正确

# -d:debug模式,校验配置文件
logrotate -d /etc/logrotate.conf

运行后会在控制台显示所读取配置文件、转存信息等。如果想看实际效果,将命令中的-d变为-f强制执行。运行-f命令后会在应用对应的immediate.log目录中生成一个以日期结尾的压缩文件,并且原来的日志文件被清空。这时logrotate配置完成。

2.logrotate执行时间

logrotate是通过cron定时任务执行的,查看cron配置文件可以看到定时任务的执行时间,CentOS使用的是anacron,配置文件在 /etc/anacrontab 中

# /etc/anacrontab: configuration file for anacron
# See anacron(8) and anacrontab(5) for details.
SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22
#period in days   delay in minutes   job-identifier   command
1       5       cron.daily              nice run-parts /etc/cron.daily
7       25      cron.weekly             nice run-parts /etc/cron.weekly
@monthly 45     cron.monthly            nice run-parts /etc/cron.monthly

配置文件中 START_HOURS_RANGE=3-22 表示定时任务开始时间,默认是在3点到22点之间, RANDOM_DELAY=45 表示启动任务后的最大随机延迟时间,默认最大延迟45分钟执行。最后三行是对于不同的定时任务配置,在cron.daily行就是定义每天的定时任务执行方式,每天一次,并且强制延迟5分钟执行,所以默认配置一般会在凌晨三点过执行。

在这里修改START_HOURS_RANGE、RANDOM_DELAY以及cron.daily的delay,可以自定义每日定时任务的执行时间。

4. 遇到的问题

问题描述

在所有都配置好后,使用 logrotate -d 不报错,手动执行 logrotate -f 也能够生成转存文件,但是转存文件却不能按照配置每天自动生成。

查看cron日志(cron日志地址:/var/log/cron)发现每天的定时任务都会执行

Oct 16 3:00:47 localhost anacron[24471]: Job `cron.daily' started
Oct 16 3:00:47 localhost run-parts(/etc/cron.daily)[24475]: starting logrotate
Oct 16 3:00:50 localhost run-parts(/etc/cron.daily)[24484]: finished logrotate
Oct 16 3:00:50 localhost run-parts(/etc/cron.daily)[24475]: starting man-db.cron
Oct 16 3:00:51 localhost run-parts(/etc/cron.daily)[24495]: finished man-db.cron
Oct 16 3:00:51 localhost anacron[24471]: Job `cron.daily' terminated

但是没有生成转存文件。

解决方案

出现该问题是由于selinux的安全策略导致的,只需要给转存日志所在的目录增加安全上下文 var_log_t 即可

chcon -Rv --type=var_log_t /data/log

执行上面命令会对/data/log目录中的所有文件添加安全上下文。之后再观察转存文件便能够成功生成。

以上就是Fluentd搭建日志收集服务的详细内容,更多关于Fluentd 日志收集的资料请关注三水点靠木其它相关文章!

Servers 相关文章推荐
基于Nginx实现限制某IP短时间访问次数
Mar 31 Servers
Apache Calcite 实现方言转换的代码
Apr 24 Servers
制作能在nginx和IIS中使用的ssl证书
Jun 21 Servers
Tomcat用户管理的优化配置详解
Mar 31 Servers
阿里云k8s服务升级时502错误 springboot项目应用
Apr 09 Servers
CentOS7安装GlusterFS集群以及相关配置
Apr 12 Servers
nginx日志格式分析和修改
Apr 28 Servers
Linux磁盘管理方法介绍
Jun 01 Servers
永中文档在线转换预览基于nginx配置部署方案
Jun 10 Servers
设置IIS Express并发数
Jul 07 Servers
Zabbix6通过ODBC方式监控Oracle 19C的详细过程
Sep 23 Servers
nginx sticky实现基于cookie负载均衡示例详解
Dec 24 Servers
Flink 侧流输出源码示例解析
Sep 23 #Servers
修改Nginx配置返回指定content-type的方法
Sep 23 #Servers
Nginx如何配置多个服务域名解析共用80端口详解
Sep 23 #Servers
VMware虚拟机安装 Windows Server 2022的详细图文教程
zabbix如何添加监控主机和自定义监控项
Aug 14 #Servers
教你使用RustDesk 搭建一个自己的远程桌面中继服务器
Aug 14 #Servers
nginx配置指令之server_name的具体使用
Aug 14 #Servers
You might like
php设计模式 Delegation(委托模式)
2011/06/26 PHP
php对包含html标签的字符串进行截取的函数分享
2014/06/19 PHP
php中使用gd库实现远程图片下载实例
2015/05/12 PHP
PHP的时间戳与具体时间转化的简单实现
2016/06/13 PHP
JavaScript随机排序(随即出牌)
2010/09/17 Javascript
用JQuery在网页中实现分隔条功能的代码
2012/08/09 Javascript
js中小数转换整数的方法
2014/01/26 Javascript
用javascript关闭本窗口不弹出询问框的方法
2014/09/12 Javascript
利用原生js和jQuery实现单选框的勾选和取消操作的方法
2016/09/04 Javascript
JavaScript仿网易选项卡制作代码
2016/10/06 Javascript
利用js获取下拉框中所选的值
2016/12/01 Javascript
js实现带三角符的手风琴效果
2017/03/01 Javascript
JavaScript禁止微信浏览器下拉回弹效果
2017/05/16 Javascript
javascript+html5+css3自定义提示窗口
2017/06/21 Javascript
提升页面加载速度的插件InstantClick
2017/09/12 Javascript
从零开始搭建一个react项目开发
2018/02/09 Javascript
vue打包使用Nginx代理解决跨域问题
2018/08/27 Javascript
WEEX环境搭建与入门详解
2019/10/16 Javascript
原生JavaScript实现进度条
2021/02/19 Javascript
Django admin美化插件suit使用示例
2017/12/12 Python
Python实现购物车程序
2018/04/16 Python
基于python3 pyQt5 QtDesignner实现窗口化猜数字游戏功能
2019/07/15 Python
e路東瀛(JAPANiCAN)香港:日本旅游、日本酒店和温泉旅馆预订
2018/11/21 全球购物
北美主要的汽车零部件零售商:AutoShack.com
2019/02/23 全球购物
Java中compareTo和compare的区别
2016/04/12 面试题
新闻网站实习自我鉴定
2013/09/25 职场文书
中文系师范生自荐信
2013/10/01 职场文书
计算机专业自荐信
2013/10/14 职场文书
大学生活学习的自我评价
2013/12/03 职场文书
大学生社会实践自我鉴定
2014/03/24 职场文书
建议书的格式
2014/05/12 职场文书
小学生竞选班干部演讲稿(5篇)
2014/09/12 职场文书
企业财务总监岗位职责
2015/04/03 职场文书
大客户经理岗位职责
2015/04/09 职场文书
党员干部学习十八届五中全会精神心得体会
2016/01/05 职场文书
演讲稿:​快乐,从不抱怨开始!
2019/04/02 职场文书