通常咱们须要进行日志分析场景:直接在日志文件中 grep、awk 就能够得到本身想要的信息。但在规模较大的场景中,此方法效率低下,面临问题包括日志量太大如何归档、文本搜索太慢怎么办、如何多维度查询。须要集中化的日志管理,全部服务器上的日志收集汇总。常看法决思路是创建集中式日志收集系统,将全部节点上的日志统一收集,管理,访问。java
通常大型系统是一个分布式部署的架构,不一样的服务模块部署在不一样的服务器上,问题出现时,大部分状况须要根据问题暴露的关键信息,定位到具体的服务器和服务模块,构建一套集中式日志系统,能够提升定位问题的效率。linux
一个完整的集中式日志系统,须要包含如下几个主要特色:
收集-可以采集多种来源的日志数据
传输-可以稳定的把日志数据传输到中央系统
存储-如何存储日志数据
分析-能够支持 UI 分析
警告-可以提供错误报告,监控机制nginxELK提供了一整套解决方案,而且都是开源软件,之间互相配合使用,完美衔接,高效的知足了不少场合的应用。目前主流的一种日志系统。正则表达式
Logstash : 开源的服务器端数据处理管道,可以同时从多个来源采集数据,转换数据,而后将数据存储到数据库中。redis
Elasticsearch:搜索,分析和存储数据,分布式数据库。数据库
Kibana:数据可视化。apache
Beats:轻量型采集器的平台,从边缘机器向Logstash和Elasticsearch发送数据。vim
Filebeat:轻量型日志采集器。安全
Input:输入,输出数据能够是Stdin,File,TCP,Redis,Syslog等
Filter:过滤,将日志格式化。有丰富的过滤插件:Grok正则捕获,Date时间处理,Json编码解码,Mutate数据修改等
Output:输出,输出目标能够是Stdout,File,TCP,Redis,ES等
主机名 | IP | 备注 |
---|---|---|
elkstack | 192.168.200.70 | 内存3G |
连接:https://pan.baidu.com/s/1PTUOKy5MNXYIhSUkkbb-DA
提取码:fa6n
cat /etc/redhat-release
uname -r
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
ls
tar xf jdk-8u60-linux-x64.tar.gz -C /usr/local/
mv /usr/local/jdk1.8.0_60 /usr/local/jdk
vim /etc/profile
tail -3 /etc/profile
export JAVA_HOME=/usr/local/jdk/
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPATH
source /etc/profile
java -version
kibana主要用来展示数据,它自己不存储数据
https://artifacts.elastic.co/downloads/kibana/kibana-6.2.3-linux-x86_64.tar.gz
useradd -s /sbin/nologin -M elk
ls
tar xf kibana-6.2.3-linux-x86_64.tar.gz -C /usr/local/
mv /usr/local/kibana-6.2.3-linux-x86_64 /usr/local/kibana
cat -n /usr/local/kibana/config/kibana.yml | sed -n '2p;7p;21p;39p;40p'
2 #server.port: 5601
7 #server.host: "localhost"
21 #elasticsearch.url: "http://localhost:9200"
39 #elasticsearch.username: "user"
40 #elasticsearch.password: "pass"
vim /usr/local/kibana/config/kibana.yml
cat -n /usr/local/kibana/config/kibana.yml | sed -n '2p;7p;21p;39p;40p'
2 server.port: 5601 #暂时就先修改这两行
7 server.host: "0.0.0.0" #暂时就先修改这两行
21 #elasticsearch.url: "http://localhost:9200"
39 #elasticsearch.username: "user"
40 #elasticsearch.password: "pass"
chown -R elk:elk /usr/local/kibana/
vim /usr/local/kibana/bin/start.sh
cat /usr/local/kibana/bin/start.sh
nohup /usr/local/kibana/bin/kibana >> /tmp/kibana.log 2>> /tmp/kibana.log &
chmod a+x /usr/local/kibana/bin/start.sh
su -s /bin/bash elk '/usr/local/kibana/bin/start.sh'
ps -ef | grep elk | grep -v grep
若是有防火墙须要开放tcp5601端口
cat /tmp/kibana.log | grep warning | head -5
这里有个警告,意思是链接不上elasticsearch,忽略,由于咱们尚未装它。
{"type":"log","@timestamp":"2019-01-03T14:12:30Z","tags":["warning","elasticsearch","admin"],"pid":1451,"message":"Unable to revive connection: http://localhost:9200/"}
{"type":"log","@timestamp":"2019-01-03T14:12:30Z","tags":["warning","elasticsearch","admin"],"pid":1451,"message":"No living connections"}
{"type":"log","@timestamp":"2019-01-03T14:12:32Z","tags":["warning","elasticsearch","admin"],"pid":1451,"message":"Unable to revive connection: http://localhost:9200/"}
{"type":"log","@timestamp":"2019-01-03T14:12:32Z","tags":["warning","elasticsearch","admin"],"pid":1451,"message":"No living connections"}
{"type":"log","@timestamp":"2019-01-03T14:12:35Z","tags":["warning","elasticsearch","admin"],"pid":1451,"message":"Unable to revive connection: http://localhost:9200/"}
因为kibana没有权限控制,能够借助nginx来部署认证和进行ip控制
vim /usr/local/kibana/config/kibana.yml
sed -n '7p' /usr/local/kibana/config/kibana.yml
ps -ef | grep elk
kill -9 1451
ps -ef | grep elk
su -s /bin/bash elk '/usr/local/kibana/bin/start.sh'
ps -ef | grep elk | grep -v grep
yum -y install pcre-devel openssl-devel
tar xf nginx-1.10.2.tar.gz -C /usr/src/
cd /usr/src/nginx-1.10.2/
useradd -s /sbin/nologin -M nginx
./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
make && make install
ln -s /usr/local/nginx/sbin/* /usr/local/sbin/
nginx -V
cd /usr/local/nginx/
cp conf/nginx.conf{,.bak}
egrep -v "#|^$" conf/nginx.conf.bak > conf/nginx.conf
vim conf/nginx.conf
cat conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request"'
'$status $body_bytes_sent "$http_referer"'
'"$http_user_agent""$http_x_forwarded_for"';
sendfile on;
keepalive_timeout 65;
server {
listen 5609;
access_log /usr/local/nginx/logs/kibana_access.log main;
error_log /usr/local/nginx/logs/kibana_error.log error;
location / {
allow 192.168.200.1;
deny all;
proxy_pass http://127.0.0.1:5601;
}
}
}
nginx -t
nginx
netstat -antup | grep nginx
location / {
auth_basic "elk auth";
auth_basic_user_file /usr/local/nginx/conf/htpasswd;
proxy_pass http://127.0.0.1:5601;
}
elasticsearch未安装以前,kibana网页上报错,提示找不到elasticsearch。
elastic search主要用来存储数据,供kibana调取并进行展示
https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.2.3.tar.gz
ls
tar xf elasticsearch-6.2.3.tar.gz -C /usr/local/
mv /usr/local/elasticsearch-6.2.3 /usr/local/elasticsearch
cp /usr/local/elasticsearch/config/elasticsearch.yml{,.bak}
cat -n /usr/local/elasticsearch/config/elasticsearch.yml | sed -n '33p;37p;55p;59p'
33 #path.data: /path/to/data
37 #path.logs: /path/to/logs
55 #network.host: 192.168.0.1
59 #http.port: 9200
vim /usr/local/elasticsearch/config/elasticsearch.yml
cat -n /usr/local/elasticsearch/config/elasticsearch.yml | sed -n '33p;37p;55p;59p'
33 path.data: /usr/local/elasticsearch/data
37 path.logs: /usr/local/elasticsearch/logs
55 network.host: 127.0.0.1
59 http.port: 9200
chown -R elk:elk /usr/local/elasticsearch
由于咱们实验环境是虚拟机,1g内存一下子就会被跑满,就会很慢。因此,咱们要调整内存占用的限制。
cat -n /usr/local/elasticsearch/config/jvm.options | sed -n '22p;23p'
22 -Xms1g
23 -Xmx1g
vim /usr/local/elasticsearch/config/jvm.options --->这里没作修改
cat -n /usr/local/elasticsearch/config/jvm.options | sed -n '22p;23p'
22 -Xms100M
23 -Xmx100M
vim /usr/local/elasticsearch/bin/start.sh
cat /usr/local/elasticsearch/bin/start.sh
/usr/local/elasticsearch/bin/elasticsearch -d >> /tmp/elasticsearch.log 2>> /tmp/elasticsearch.log
chmod a+x /usr/local/elasticsearch/bin/start.sh
su -s /bin/bash elk '/usr/local/elasticsearch/bin/start.sh'
ps -ef | grep elk | grep -v grep
> /tmp/kibana.log
tail -f /tmp/kibana.log
从新刷新url:http://192.168.200.70:5609
观察日志,看看还有没有报错。
假如elasticsearch若是监听在非127.0.0.1,那么须要修改内核参数等,在这里就很少说了。
用来读取日志,正则分析日志,发送给elasticsearch数据库
https://artifacts.elastic.co/downloads/logstash/logstash-6.2.3.tar.gz
ls
tar xf logstash-6.2.3.tar.gz -C /usr/local/
mv /usr/local/logstash-6.2.3 /usr/local/logstash
cat -n /usr/local/logstash/config/jvm.options | sed -n '6p;7p;'
6 -Xms1g
7 -Xmx1g
cat -n /usr/local/logstash/config/jvm.options | sed -n '6p;7p;'
6 -Xms150M
7 -Xmx150M
vim /usr/local/logstash/config/logstash.conf
cat /usr/local/logstash/config/logstash.conf
input {
file {
path => "/usr/local/nginx/logs/kibana_access.log" #读取日志路径
}
}
output {
elasticsearch {
hosts => ["http://127.0.0.1:9200"] #保存日志url
}
}
vim /usr/local/logstash/bin/start.sh
cat /usr/local/logstash/bin/start.sh
nohup /usr/local/logstash/bin/logstash -f /usr/local/logstash/config/logstash.conf >> /tmp/logstash.log 2>> /tmp/logstash.log &
chmod a+x /usr/local/logstash/bin/start.sh
logstash并无监听端口,所以不须要用elk用户来启动
/usr/local/logstash/bin/start.sh
ps -ef | grep logstash
logstash启动的比较慢,须要多等一下子。
若是在kibana的Discover里能看到添加索引就说明logstash启动好了
图片说明
进行数据展示字段的筛选
对nginx的kibana_access.log进行数据追踪,对比分析
tail -f /usr/local/nginx/logs/kibana_access.log
ps -ef | grep logstash
kill -9 17120
/usr/local/logstash/bin/logstash -e ""
welcome --->输入的内容
{
"@version" => "1",
"@timestamp" => 2018-08-16T13:18:13.383Z,
"message" => "welcome",
"type" => "stdin",
"host" => "elkstack"
}
能够看到logstash结尾自动添加了几个字段,时间戳@timestamp,版本@version,输入的类型type,以及主机名host
Logstash使用管道方式进行日志的搜集处理和输出。有点相似于管道命令xxx|ccc|ddd,xxx执行完了会执行ccc,而后执行ddd。
在logstash中,包括了三个阶段:
输入input ---> 处理filter(不是必须的) ---> 输出output
每一个阶段都有不少的插件配合工做,好比file,elasticsearch,redis等
每一个阶段也能够指定多种方式,好比输出既能够输出到elasticsearch中,也能够指定到stdout在控制台打印。
因为这种插件式的组织方式,使得logstash变得易于扩展和定制
-f:经过这个命令能够指定Logstash的配置文件,根据配置文件配置logstash
-e:后面跟着字符串,该字符串能够被看成logstash的配置(若是是""则默认使用stdin做为默认输入,stdout做为默认输出)
-l:日志输出的地址(默认就是stdout直接在控制台中输出)
-t:测试配置文件是否正确,而后退出。
前面介绍过logstash基本上由三部分组成,input,output以及用户须要才添加的filter,所以标准的配置文件格式以下:
input {...}
filter {...}
output {...}
在每一个部分中,也能够指定多个访问方式,例如我想要指定两个日志来源文件,则能够这样写:
input {
file { path => "/var/log/messages" type => "syslog" }
file { path => "/var/log/apache/access.log" type => "apache" }
}
相似的,若是在filter中添加了多种处理规则,则按照它的顺序----处理,可是有一些插件并非线程安全的。
好比在filter中指定了两个同样的插件,这两个任务并不能保证准确的按顺序执行,所以官方也推荐避免在filter中重复使用插件。
咱们更改一下logstash的配置文件进行正则抓取数据的测试。
cd /usr/local/logstash/config/
vim logstash.conf
cat logstash.conf
input {
stdin{} #从标准输入读取数据
}
filter {
grok {
match => {
"message" => '(?<字段名>正则表达式).*'
}
}
}
output {
elasticsearch { #若是要输入到elasticsearch里,那么须要注释掉stdout{}
hosts => ["http://127.0.0.1:9200"]
}
stdout { #只将信息输出到屏幕上
codec => rubydebug #用于正则提取测试,将正则抓取结果输出到屏幕上
}
}
ps -ef | grep logstash --->查询PID号
kill -9 PID号
/usr/local/logstash/bin/logstash -f /usr/local/logstash/config/logstash.conf
Aug 16 18:29:49 ELK systemd: Startup finished in 789ms (kernel) + 1.465s (initrd) + 18.959s (userspace) = 21.214s.
vim /usr/local/logstash/config/logstash.conf
cat /usr/local/logstash/config/logstash.conf
input {
stdin{}
}
filter {
grok {
match => {
"message" => '(?<mydate>[a-zA-Z]+ [0-9]+ [0-9:]+) (?<hostname>[a-zA-Z]+).*'
}
}
}
output {
elasticsearch {
hosts => ["http://127.0.0.1:9200"]
}
stdout {
codec => rubydebug
}
}
/usr/local/logstash/bin/logstash -f /usr/local/logstash/config/logstash.conf
Aug 16 18:29:49 ELK systemd: Startup finished in 789ms (kernel) + 1.465s (initrd) + 18.959s (userspace) = 21.214s.
{
"hostname" => "ELK", #这就是抓取的字段
"mydate" => "Aug 16 18:29:49", #这就是抓取的字段
"@timestamp" => 2018-08-16T12:47:46.904Z,
"message" => "Aug 16 18:29:49 ELK systemd: Startup finished in 789ms (kernel) + 1.465s (initrd) + 18.959s (userspace) = 21.214s.",
"host" => "elkstack",
"@version" => "1"
}
请经过配置文件进行反复测试验证,熟悉logstash正则表达的使用方法
vim /usr/local/logstash/config/logstash.conf
cat /usr/local/logstash/config/logstash.conf
input {
stdin{}
}
filter {
grok {
match => {
"message" => '(?<mydate>[a-zA-Z]+ [0-9]+ [0-9:]+) (?<hostname>[a-zA-Z]+).*'
}
}
}
output {
elasticsearch {
hosts => ["http://127.0.0.1:9200"]
}
# stdout {
# codec => rubydebug
# }
}
/usr/local/logstash/bin/logstash -f /usr/local/logstash/config/logstash.conf
Aug 16 18:29:49 ELK systemd: Startup finished in 789ms (kernel) + 1.465s (initrd) + 18.959s (userspace) = 21.214s.
logstash若是直接把一整行日志直接发送给elasticsearch,kibana显示出来就没有什么意义,咱们须要提取本身想要的字段。假如说咱们想要提取响应码,用户访问url,响应时间等,就得依靠正则来提取。
input { #日志输入来源函数
file {
path => "/usr/local/nginx/logs/kibana_access.log"
}
}
filter { #字段数据提取函数
grok {
match => {
"message" => '(?<字段名>正则表达式).*'
}
}
}
output { #数据输出目的地函数
elasticsearch {
hosts => ["http://127.0.0.1:9200"]
}
}
vim /usr/local/logstash/config/logstash.conf
cat /usr/local/logstash/config/logstash.conf
input {
file {
path => "/usr/local/nginx/logs/kibana_access.log"
}
}
filter {
grok {
match => {
"message" => '(?<IP>[0-9.]+) .*'
}
}
}
output {
elasticsearch {
hosts => ["http://127.0.0.1:9200"]
}
}
/usr/local/logstash/bin/logstash -f /usr/local/logstash/config/logstash.conf
vim /usr/local/logstash/config/logstash.conf
cat /usr/local/logstash/config/logstash.conf
input {
file {
path => "/usr/local/nginx/logs/kibana_access.log"
}
}
filter {
grok {
match => {
"message" => '(?<IP>[0-9.]+) .*HTTP/[0-9.]+"(?<mark>[0-9]+) (?<size>[0-9]+)[ "]+(?<url>[a-zA-Z]+://[0-9.]+:[0-9]+/[a-zA-Z/]+)".*'
}
}
}
output {
elasticsearch {
hosts => ["http://127.0.0.1:9200"]
}
}
/usr/local/logstash/bin/logstash -f /usr/local/logstash/config/logstash.conf