写点什么

graylog 日志分析系统上手教程

发布于: 2020 年 09 月 27 日
graylog日志分析系统上手教程

日志分析系统可以实时收集、分析、监控日志并报警,当然也可以非实时的分析日志。splunk 是功能强大且用起来最省心的,但是要收费,免费版有每天 500M 的限制,超过 500M 的日志就没法处理了。ELK 系统是最常见的,缺点是配置麻烦一些,比较重量级。graylog 是开源免费的,配置上要比 ELK 系统简单。综上,本文尝试容器方式搭建一套 graylog 系统,不做实时收集日志和报警的配置,只完成非实时被动接收网站日志,分析日志各项指标的功能。


docker 官方镜像国内速度我觉得慢,改成国内镜像。新建文件 daemon.json 如下

vi /etc/docker/daemon.json{"registry-mirrors": ["https://registry.docker-cn.com"]}
复制代码

也可以用网易镜像http://hub-mirror.c.163.com

配置完重启 docker 才能生效

#service docker restart
复制代码


拉取如下三个镜像

docker pull mongo:3docker pull docker.elastic.co/elasticsearch/elasticsearch-oss:6.8.10docker pull graylog/graylog:3.3
复制代码

不要急着按照网上的方法启动镜像,我开始 docker 启动 elasticsearch,虽然显示启动成功,但过半分钟后偷偷退出,这导致 graylog 在浏览器打不开。最后通过查看容器启动时的日志,发现 elasticsearch 对于系统参数是有要求的,按如下修改。


在 /etc/sysctl.conf 文件最后添加一行

vm.max_map_count=262144
复制代码


vi /etc/security/limits.conf

*              -       nofile            102400  
复制代码

修改完成后重启系统使变量生效。


docker 启动 elasticsearch 时要加上参数

--ulimit nofile=65536:65536 --ulimit nproc=4096:4096
复制代码

,确保容器内环境满足要求,否则在 docker pa -a 命令下会看到 exit(78)或 exit(1)的容器异常退出错误。

查看容器启动报错最准确的方法是“docker logs -f 容器 ID”这个命令,我们不加--ulimit 参数试试

[root@bogon ~]# docker psCONTAINER ID        IMAGE                                                      COMMAND                CREATED             STATUS              PORTS                                            NAMES7e4a811093d9        docker.elastic.co/elasticsearch/elasticsearch-oss:6.8.10   "/usr/local/bin/dock   6 seconds ago       Up 4 seconds        0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   elasticsearch
复制代码

用上面的 CONTAINER ID 产看启动时的日志

[root@bogon ~]# docker logs -f 7e4a811093d9最后会打印出[1]: max file descriptors [4096] for elasticsearch process is too low, increase to at least [65535][2]: max number of threads [3869] for user [elasticsearch] is too low, increase to at least [4096][2020-08-27T06:10:25,888][INFO ][o.e.n.Node               ] [WG6mVz4] stopping ...[2020-08-27T06:10:25,903][INFO ][o.e.n.Node               ] [WG6mVz4] stopped[2020-08-27T06:10:25,903][INFO ][o.e.n.Node               ] [WG6mVz4] closing ...[2020-08-27T06:10:25,928][INFO ][o.e.n.Node               ] [WG6mVz4] closed
复制代码

两行 too low 的提示就是容器退出的原因。

三个容器正确的启动命令如下

docker run --name mongo -d mongo:3
docker run --name elasticsearch \ -e "http.host=0.0.0.0" \ -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \ --ulimit nofile=65536:65536 --ulimit nproc=4096:4096 \ -p 9200:9200 -p 9300:9300 \ -d docker.elastic.co/elasticsearch/elasticsearch-oss:6.8.10
docker run --name graylog --link mongo --link elasticsearch \ -p 9000:9000 -p 12201:12201 -p 1514:1514 -p 5555:5555 \ -v /home/graylog/geodata:/usr/share/graylog/log \ -e GRAYLOG_HTTP_EXTERNAL_URI="http://192.168.56.106:9000/" \ -d graylog/graylog:3.3
复制代码

mongo 的启动没什么可说的。

elasticsearch 的--ulimit 必须加否则启动后退出,-p 9200:9200 是管理端口,将来删除数据需要访问这个端口。

graylog 9000 端口是系统界面,5555 是开的 tcp 端口,用于被动接收日志数据的。

-v /home/graylog/geodata:/usr/share/graylog/log
复制代码

是把本地/home/graylog/geodata 挂载到容器的/usr/share/graylog/log 目录,我这么配置是为了让 graylog 能读到 GeoLite2-City.mmdb 地理信息数据库,这个库是把 ip 和地理位置对应起来了。本来想把它拷贝到容器里,但报错

[root@localhost graylog]# docker cp ./GeoLite2-City.mmdb 151960c2f33b:/usr/share/graylog/data/Error: Path not specified
复制代码

说是要升级 docker1.7 到更高版本,不想升级,改成挂载方法了。如果不想挂载什么文件,-v 这行参数可以去掉。

我是用命令“#docker exec -it graylog 容器 ID bash" 先进入容器,看到容器内/usr/share/graylog/log 目录没什么东西,所以选择挂载到这个目录的。

地理数据用于显示访问网站的 ip 分布在哪个城市国家,还有世界地图的显示。需要在https://dev.maxmind.com/zh-hans/geoip/geoip2/geolite2/上下载,麻烦的是这里需要注册。我下载的是 GeoLite2-City_20200825.tar.gz,解压后有 GeoLite2-City.mmdb,上传这个文件到 Linux 的/home/graylog/geodata 目录,这个文件是需要挂载到容器,给 graylog 使用的。

不想注册请从下面链接下载

链接:https://pan.baidu.com/s/1LovroJyodJml4

niI66CkmA

提取码:bsmm


GRAYLOGHTTPEXTERNAL_URI 的地址不要写 127.0.0.1,这样如果在 Linux 的外部访问,虽然能通,但是网页是空白一片,要写 Linux 对外的 ip 地址,这样在外部浏览器打开才正常。


另外 graylog 的启动是依赖于 mongo 和 elasticsearch 的,等其它两个都成功启动,再启动 graylog。


下面开始演示如果配置 graylog 系统,并且分析网站的 Apache 标准格式的日志。大概步骤如下

配置 input->给 input 配置 extractor->配置地理信息数据库->手动输入日志->分析日志。

浏览器输入http://192.168.56.106:9000/ 用户名和密码都是 admin,登陆进 graylog 系统。

system->input,


点击 select input 右侧的下拉箭头,出现下拉列表,选择 raw/plaintext TCP


然后点击 Lanch new input,Node 下拉唯一选择给选上,Title 随意起名,Port 写 5555,因为我们 docker 启动参数写的-p 5555:5555 这两个必须保持一致。

其它不用填点击下方 SAVE 按钮,会自动启动该 input,可以看到 local inputs 下方增加了刚才的配置。其实现在用 cat access.log | nc localhost 5555 等命令给 5555 端口发送日志数据,数据就可以进入到 graylog 系统,并且可以进行简单的搜索了。但这种搜索是最基础的字符串匹配,价值不大。我们要分析日志的各项指标,并且生成图表,必须让系统能解析每条日志的各个 field(字段或域值),例如 clientip 就是一个 field,request 也是一个 field。要解析出 field 要给 input 配置 extractor,点击 Manager exactor。



Extractors JSON 里贴入下面内容

{"extractors": [    {"title": "commonapache","extractor_type": "grok","converters": [],"order": 0,"cursor_strategy": "copy","source_field": "message","target_field": "","extractor_config": {"grok_pattern": "%{COMMONAPACHELOG}"      },"condition_type": "none","condition_value": ""    }  ],"version": "3.3.5"}
复制代码


最后点击 add extrators to input,显示 successful 即可。

到这里已经可以正确解析日志得 field 了。但是如果我们想分析和地理位置相关的信息,还必须配置地理信息数据库,上文下载的 mmdb 文件。

system->configurations,最右下方有一项 Geo-Location Processor,点击改项目下方的 update 按钮


配置完成,点击 save。


Configurations 最上方 Message Processors Configuration 下方表格里要把 GeoIP Resolver 放在表格的最下方。点击表格下方的 update

鼠标按住 GeoIP Resolver 往下方拖,

完成后点击 save。Message Processors Configuration 表格的 GeoIP Resolver 到了最下方。

下面是手动输入日志到 input 了,我将 access2020-07-06.log 放到了 Linux 目录下,在目录下执行

# cat access2020-07-06.log | head -n 10000 | nc localhost 5555
复制代码

命令是将 log 从头开始的 10000 行日志发送到本机的 5555 端口,由于 graylog 的 input 配置的也是 5555 端口,docker run graylog 时命令参数也是-p 5555:5555,只要这三处保持一致,这个命令是一定能成功的。这里命令 nc、ncat、netcat 三个都能到达同样的效果。


导入完成后,选择 graylog 最上方的 search 选项

上方的按钮是查询时间范围,这个时间是日志导入的时间,不是日志本身记录请求的时间,如果要查全部直接选择 search in all messages

下方放大镜按钮就是搜索,后方可以添加搜索关键字,或者某个 field 的限制,有很多搜索语法非常方便,点击搜索后,不符合条件的日志记录会被去除。

下方 All Messages 就是符合条件的原始的日志结果。

如果想统计访问来源于哪些城市,点击左侧边栏最下的 X(field)形按钮。选择 clientip_cityname->show top values

鼠标点击右侧灰色区域,回到主界面,访问来源的城市信息已经在列表里了。

N/A 表示的是有大量请求识别不出 ip 所在的城市,这有可能是我们的地理信息数据库不全不新,或者有些 192 172 这种内网地址的访问无法识别地区,这里不重点讨论了。如果要剔除 N/A 数据,只看可识别城市的分布,鼠标放到 N/A 右侧,会出现下拉菜单的箭头,点击箭头,选择 exclude from results,N/A 的数据就会去除,上面的搜索栏内也会自动增加这个筛选条件,

注意现在的统计是剔除了 N/A 的数据,数据范围实际是比全部日志范围缩小了的,这在实际应用中很有价值,很多情况下我们统计某些指标,就是要看某个局部范围的。下面我们看看访问来源城市的统计图,点击右上角下拉箭头,选择 Edit

点击左侧 Date Table 处下拉菜单,可以看到柱状图、饼状图、散点图等都列在里面,选择哪个右侧就会出现那种统计的图表。

如果要展示访问来源在世界地图的分布,field 菜单选择 clientip_geolocation->show top values,

弹出的统计表格是经纬度坐标的访问次数。和上面图标一样,进入 Date Tabel 下拉菜单,最下方有 world map

选择会显示地图统计结果,放大调整位置如下图


其它指标的统计如 request 分布,访问时间分布,在 field 下列表里都有,根据需要按上面同样操作。地理信息数据和标准的 Apache 日志可以结合生效,但一些自定义的 extractor 是否生效是不一定的。


番外篇


给 input 配置 extractor,上面配置的是标准的 Apache 格式日志,如果日志格式是 nginx 或者自定义的怎么办呢?

graylog 提供了给日志配置 extractor 的功能,假设我们配置完 input,没有给 input 配置 extractor,直接导入日志,按如下步骤配置 extractor

input 界面选择 manager extractor

getstarted

load message 会将刚进入的日志中的一条显示出来,点击 message 位置的 select extractor type,表示我们要对 message 也就是整条信息配置 extractor,下拉菜单选择 Grok Pattern。如果日志进入时间比较久,load message 无法展示日志,需要通过旁边 message ID 的标签来搜索日志,需要提供 message ID 和 index,这两个参数在搜索界面下方 all message 里,随便点击一条日志数据,展开就可以看到。message ID 形如 4b282600-e8d2-11ea-b962-0242ac110008,index 形如 graylog_0。

进入 Extractor configuration,里面的 pattern 要自己填写,可以在右侧已有的 pattern 选择若干个组合,也可以自己定义,这里需要对 grok 和正则语法熟练了。我这里填写的是解析 nginx 原生日志的 pattern 格式,也是网上搜索的。填写完点击 try against example,如果解析成功,下方会表格形式列出各个 field 对应该条日志的值。不成功就会报错,需要修改 pattern 直到不报错。

我的 pattern 如下

^%{IPORHOST:clientip} (?:-|%{USER:ident}) (?:-|%{USER:auth}) \[%{HTTPDATE:timestamp}\] \"(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|-)\" %{NUMBER:response} (?:-|%{NUMBER:bytes})([\s\S]{1})\"(?<http_referer>\S+)\"([\s\S]{1})\"(?<http_user_agent>(\S+\s+)*\S+)\".*%{BASE16FLOAT:request_time}
复制代码

解析成功,Extractor title 随便起个名,点击最下方 create extractor


extractor 已经成功添加给 input 了,上面的 action 有 export extractor,点击可以以 json 格式展示刚才配置的 extractor。

拷贝这个 json 文本,保存在本地,以后遇到 nginx 原生格式日志,直接通过上面的 import extractor 就直接使用,不用在配置 grok pattern 测试了。

需要说明的是一条日志记录有没有被解析为各个 field,取决于日志进入系统时,有没有配置 extractor。后配置的 extractor 对在之前的日志是起不到解析作用的。

如果配置完 extractor,相同格式日志只进入系统一小部分,不要找其它原因了,原因就是 pattern 不对,虽然测试通过了,也配上了,但是还需要你重新修改 pattern,如果 pattern 正确,符合格式的日志应该全都进入系统。


对于有些日志格式,配置 grok pattern 需要大量调试,graylog 调试并不方便,官方 grok 调试器网站国内都打不开了。下面提供一个工具,可以直接粘贴日志到页面调试

链接:https://pan.baidu.com/s/1gWX4ZcAzh-zn5hSahdOMig

提取码:t6q6

windows 的 cmd 直接 java -jar GrokConstructor-0.1.0-SNAPSHOT-standalone.jar

然后浏览器访问 127.0.0.1:8080,点击 matcher,上面填写日志,下方填写 grok pattern,

点击 go,如果成功解析,会表格形式展示解析各个 field 结果。

ramdom example 给出了一些常见日志的例子和对应的 pattern 格式。


如果要重新配置 graylog 和输入数据,先

docker stop $(docker ps -a -q)
复制代码

停止所有容器,然后

docker rm $(docker ps -a -q)
复制代码

删除所有容器,然后 docker run 按顺序启动三个容器,这样启动的容器是全新的,之前的配置和数据都会丢失。

上面对容器的操作麻烦,可以使用

curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
复制代码

安装 docker-compose,将启动参数等要求写到 docker-compose.yml 文件里,这种方式操作命令会很简单。


发布于: 2020 年 09 月 27 日阅读数: 759
用户头像

总结 分享 收获 2020.08.17 加入

公众号“MySQL从删库到跑路”作者 最纯粹的技术 最高级的享受

评论

发布
暂无评论
graylog日志分析系统上手教程