
ELK分别表示:Elasticsearch , Logstash, Kibana 。他们组成了一套完整的日志系统的解决方案,方便我们使用。
在使用Logstash进行收集的时候,仅仅需要简单的一个配置文件就可以启动一个logstash-agent来进行日志收集。
上述示例简单的从某个文件目录下收集日志打印到控制台。
然后我们启动这个logstash-agent: bin/logstash -f conf/datafall/test.config
往日志文件push数据:
echo "hello world" >>1.txt
就可以看到控制输出:
到此时是正确的一个流程。
误 *** 作开始了:
但是我们以 vim 命令进入日志文件的时候,在文件末尾追加一个数据 happy ,此时控制台会输出:
会发现logstash会从文件开始从新读取数据(此时就会造成数据的重复收集)。
为什么会出现这种情况呢?
Logstash有一个有趣的组件或功能叫做sincedb。该文件存储了当前logstash-agent收集的文件日志的offset。在前面 test.config 配置了sincedb的位置。
如果不配置,它会默认在当前用户的根目录下创建一个 .sincedb开头的文件 。
sincedb的具体内容:
看到上述内容,发现我们明明只收集了一个日志文件,为什么会又多出来一条记录呢。
这就要追述到使用 vim 命令编辑文件并保存时。相当于会创建拥有全新inode的文件。
此时logstash会发现一个文件名一样但是inode却不一样的文件。logstash还是会进行文件的收集工作。
通过debug模式可以看到更详细的细节:
从上述日志可以看出logstash会产生监控到一个新的inode文件,并且在原有 sincedb 文件中并没有这个inode记录,因此logstash会从头开始收集这个日志文件中的日志。
当我们在使用logstash收集日志文件时,尽量不要用 Vim、vi 命令去打开日志文件,尽量使用 cat、more 这之类的。
注:
inode: *** 作系统中的文件数据都储存在"块"中,当然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为"索引节点"
inode包含文件的元信息,具体来说有以下内容:
一般情况下,文件名和inode号码是"一一对应"关系,每个inode号码对应一个文件名。
vim、vi:为什么在编辑的时候会产生一个新的inode: 在使用vim打开文件是,会把当前打开的文件放入buffer中(内存),然后进行 *** 作。当我们保存时,相当于替换了原来的文件。所以会有个新的inode的文件产生。
场景描述:一个Web应用,前端设置了8个具有相同配置的Tomcat服务器,跑在Nginx反向代理后。每个Tomcat服务器运行在一个虚拟机上,要求能对Tomcat服务器的访问日志汇总存储并提供一定的分析能力。
需要的开源软件:Logstash和Elasticsearch。通过在各个虚拟机上安装Logstash收集Tomcat的日志数据,并存储在Elasticsearch中达到日志集中收集和分析的目的。
过程有两个步骤:
一、配置Tomcat的日志存储格式。编辑Tomcat目录下server.xml,填写如下内容
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t &quot%r&quot%s %b %D &quot%{Referer}i&quot&quot%{User-Agent}i&quot" />
</Host>
directory表示访问日志存储在Tomcat的logs目录中。
prefix表示日志文件名以localhost_access_log.开头。
suffix表示日志文件名以.txt截尾。
pattern="%h %l %u %t &quot%r&quot%s %b %D &quot%{Referer}i&quot&quot%{User-Agent}i&quot"
pattern这一句非常重要,用于表示日志的存储格式,一般为了方便会使用common或者combined,这两种自定义格式已经可以记录足够详细的信息,我这里使用了自定义方式。在这个pattern描述里:
%h表示访问来源的主机名或者IP地址;
%l表示客户端的标示,通常是 -;
%u表示得到了授权的访问者标示,通常都是 -;
%t表示日志事件的发生时间戳,用 [ 和 ] 括起来的;
&quot%r&quot表示用双引号&quot括起来的访问命令和链接,比如“GET /resource/logo.png”;
%s表示HTTP状态码,如200和404等;
%b是服务器返回的数据量,以字节为单位;
%D表示服务器的响应时间,可以用于分析页面的执行效率;
&quot%{Referer}i&quot表示用两个双引号括起来的网址,用于告诉服务器这个访问请求是从哪个页面链接过来的;
&quot%{User-Agent}i&quot表示用双引号括起来的浏览器的HTTP代理信息,可以得到客户端使用了什么浏览器内核。
二、配置Logstash
1、在每个虚拟机上传logstash安装文件,安装logstash,以2.2.2版本为例
rpm -ivh logstash-2.2.2-1.noarch.rpm
2、创建Logstash的工作目录
mkdir /root/logstash_work_dirmkdir /root/logstash_work_dir/configmkdir /root/logstash_work_dir/logsmkdir /root/logstash_work_dir/pid
其中/root/logstash_work_dir是工作目录,config目录用于存储Logstash的配置文件,logs目录用于存储Logstash的日志数据,pid目录用于存储Logstash的pid文件。
3、设置Logstash的运行脚本,修改/etc/init.d/logstash中,替换其中的代码如下
LS_WORK_DIR=/root/logstash_work_dir
name=logstash
LS_USER=root
LS_GROUP=root
LS_HOME=/var/lib/logstash
LS_HEAP_SIZE="1g"
pidfile=${LS_WORK_DIR}/pid/$name.pid
LS_LOG_DIR=${LS_WORK_DIR}/logs
LS_LOG_FILE=${LS_WORK_DIR}/logs/$name.log
LS_CONF_DIR=${LS_WORK_DIR}/config/root_tomcat.conf
LS_OPEN_FILES=16384
LS_NICE=19
LS_OPTS=""
LS_USER和LS_GROUP指定了Logstash进程运行时的用户名和组,我这里使用了root,也可以使用其他权限更低的一般用户和组。
LS_CONF_DIR=${LS_WORK_DIR}/config/root_tomcat.conf这一句最重要,指定了Logstash服务运行时的配置文件路径。
4、在/root/logstash_work_dir/config/目录中编写Logstash的配置文件root_tomcat.conf,这是本系统最重要的文件。
input {
file {
path =>"/root/tomcat/logs/localhost_access_log*.txt"
sincedb_path =>"/root/logstash_work_dir/config/sincedb_apache_access_log.txt"
type =>"apache_access_log"
add_field =>{"tomcatip" =>"10.128.18.61"}
}
}
filter{
if [type] == "apache_access_log" {
grok{
match =>{ "message" =>"%{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] \"(?:%{WORD:verb} %{URIPATHPARAM:request}(?: HTTP/%{NUMBER:httpversion})?|-)\" %{NUMBER:response} (?:%{NUMBER:bytes}|-) %{NUMBER:responsetime} \"(?:%{URI:referrer}|-)\" %{QS:agent}" }
}
date{
match =>[ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
target =>["writetime"]
}
mutate {
convert =>{
"response" =>"integer"
"bytes" =>"integer"
"responsetime" =>"integer"
}
}
}
}
output {
if [type] == "apache_access_log" {
elasticsearch {
hosts =>["10.128.18.74:9200","10.128.18.75:9200","10.128.18.77:9200"]
index =>"logstash-apacheaccesslog-%{+YYYY.MM.dd}"
}
}
}
Logstash的配置文件包括input、filter和output三部分。
input部分,使用了file插件。path指定了Logstash扫描的文件,每当有文件变化时,Logstash会读取文件尾部新增的数据;sincedb_path用于存储上一次文件读取的位置信息,如果这个文件不存在,则会从日志文件首部获取所有数据;type用于对这个配置插件做标识,当一个配置文件中有多个数据收集任务时尤其有用;add_field用于标识本机的ip地址,当数据存储在Elasticsearch后,用于区分来自哪一个Tomcat服务器。
filter插件,使用了grok、date和mutate三个插件。
grok插件用于解析Tomcat的访问日志,logstash自带了COMBINEDAPACHELOG等多个配置模式,但由于我使用了自定义的Tomcat日志配置,这里也自己编写;
date部分用于从日志中提取时间戳信息;
mutate中用convert将response、byte和responsetime三个解析得到的字符串转化为整数integer类型,这个步骤对于后续的分析比较重要,因为这样可以在Elasticsearch中做数值比较运算。
output插件,使用了elasticsearch插件,其中hosts指定了Elasticsearch集群的地址,本例子中指定了三个实例;index指定了数据存储在Elasticsearch中的索引名字,以logstash作为开头是因为Logstash自带的针对ELasticsearch的mapping映射中,对于所有的字符串类型都附带设置了一个raw不做解析的设置,这样便于在Elasticsearch中做底层的文本检索。
5、设置chkconfig的启动命令
chkconfig --add logstash
6、启动Logstash服务
service logstash start
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)