在传统的应用运行环境中,收集、分析日志往往是非常必要且常见的,一旦应用出现问题、或者需要分析应用行为时,管理员将通过一些传统工具对日志进行检查,如cat、tail、sed、awk、perl以及grep。这种做法有助于培养在常用工具方面的优秀技能,但它的适用范围仅限于少量的主机和日志文件类型。

随着应用系统的复杂性与日俱增,日志的分析也越来越重要,常见的需求包括,团队开发过程中可能遇到一些和日志有关的问题:

  • 开发没有生产环境服务器权限,需要通过系统管理员获取详细日志,沟通成本高
  • 系统可能是有多个不同语言编写、分布式环境下的模块组成,查找日志费时费力
  • 日志数量巨大,查询时间很长

对于日志来说,最常见的需求就是收集、查询、显示,正对应logstash、elasticsearch、kibana的功能。ELK(ElasticSearch + Logstash + Kibana)架构专为收集、分析和存储日志所设计。同时可以通过开源项目Kibana对日志进行查看、搜索、分析、可视化:

除了查看日志外,它自身的组件架构支持通过代理对不同服务器的日志流进行管理,并最终传送至ElasticSearch中。

ELK架构

从上图的架构很容易看出,Logstash在各个应用中设置一个Shipper用来收集并转化为统一格式的日志数据,然后将其转入Message Broker(通常是Redis),然后日志中心的Indexer(也是Logstash)负责从Broker中读取日志流,并转存至ElasticSearch中建立索引,以便日后快速查看、搜索、分析。Kibana是一个功能强大、丰富的Web界面,它从ElasticSearch中读取数据,支持各种查询、展示。

在本文接下来的部分中将展示如何部署ELK并实现这样的日志收集架构。

环境准备

  • Linux服务器,本文以CentOS 7为例
  • 安装Java环境,要求Java 7以上版本
  • 安装Redis

安装ElasticSearch

首先下载ElasticSearch的RPM安装包(其他平台可以下载其他安装):

sudo rpm -Uvh elasticsearch-{version}.noarch.rpm

安装完成后可以编辑/etc/elasticsearch/elasticsearch.yml来改变一些配置,例如监听地址、端口等。

启动elasticsearch:

sudo systemctl start elasticsearch.service

安装Kibana

首先下载Kibana 4最新版本。

解压缩到目标目录(这里是`/opt/):

$ tar xvf kibana-*.tar.gz -C /opt/

为了使Kibana能够以服务的形式运行,需要配置Systemd文件/etc/systemd/system/kibana4.service

[Service]
ExecStart=/opt/kibana/bin/kibana
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=kibana4
User=root
Group=root
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target

启动Kibana 4:

sudo systemctl start kibana4
sudo systemctl enable kibana4

访问[http://localhost:5601](http://localhost:5601)即可看到Kibana页面

安装Logstash

首先下载Logstash最新版本的RPM包,安装:

$ sudo rpm -Uvh logstash-1.5.3-1.noarch.rpm

Logstash基本原理

LogStash实例中的三个主要功能:事件输入、事件数据过滤以及事件输出。LogStash的这三个功能是根据配置信息执行的,这些信息存储在简单易懂的“.conf”文件中。 “.conf”文件中有不同的配置节对应LogStash所使用的三种不同类型的插件 输入(input)、过滤器(filter)以及输出(output)。每个LogStash实例都是根据它在整体架构中的角色需求进行定制的。

中心节点

Logstash中心节点负责将Broker(Redis)中的数据流转化到ElasticSearch中,为此创建一个配置文件:

input {
  redis {
    host => "127.0.0.1"
    port => "6379" 
    key => "logstash:demo"
    data_type => "list"
    codec  => "json"
    type => "logstash-redis-demo"
    tags => ["logstashdemo"]
  }
}

output {
  elasticsearch {
    host => "127.0.0.1"
  }
}

启动完成后,可以通过往Redis中push一条数据来测试是否成功:

RPUSH logstash:demo "{\"time\": \"2013-01-01T01:23:55\", \"message\": \"logstash demo message\"}"

然后可以通过Kibana Web界面查看数据是否插入成功。

Shipper节点

Shipper节点上运行的同样是Logstash,只不过它的功能是将各类日志收集起来并发送到Redis中。我们以收集Nginx Accesss日志为例讲解如何配置Logstash Shipper节点。假设现在nginx日志存储于/data/log/nginx/access.log中,为了能够解析Nginx日志我们首先在${LOGSTASH_HOME}/patterns目录下添加nginx文件:

NGUSERNAME [a-zA-Z\.\@\-\+_%]+
NGUSER %{NGUSERNAME}
NGINXACCESS %{IPORHOST:clientip} - %{NOTSPACE:remote_user} \[%{HTTPDATE:timestamp}\] \"(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})\" %{NUMBER:response} (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent} %{NOTSPACE:http_x_forwarded_for}

上述文件相当于对Nginx Access日志的模式匹配,将各个字段解析为Logstash存储的日志格式。接下来,配置Shipper节点:

input {
  file {
    path => [ "/data/log/nginx/access.log" ]
    start_position => "beginning"
  }
}

filter {
  grok {
    match => { "message" => "%{NGINXACCESS}" }
    add_field => { "type" => "access" }
  }
  date {
    match => [ "timestamp" , "dd/MMM/YYYY:HH:mm:ss Z" ]
  }
  geoip {
    source => "clientip"
  }
}

output {
  redis {
    host => "127.0.0.1"
    port => 6379
    data_type => "list"
    key => "logstash:demo"
  }
}

实际上,Logstash对指定文件/data/log/nginx/access.log进行检测,一旦发现其发生了变化,会将变化的内容发送至Redis中。除了inputoutput两个标签,filter中的grok插件将nginx日志解析为Logstash格式,date插件添加了时间戳,geoip插件将clientip字段转化为地理信息ip,它们都是非常有用的插件,同时也证明了Logstash的配置非常容易,可扩展性强,几行配置就可以实现非常复杂的日志处理分析功能。

登录发表评论 注册

反馈意见