Flume + Solr + log4j搭建web日志采集系统

前言

很多web应用会选择ELK来做日志采集系统,这里选用Flume,一方面是因为熟悉整个Hadoop框架,另一方面,Flume也有很多的优点。

关于Apache Hadoop Ecosystem 请点击这里。

Cloudera 官方的教程也是基于这个例子开始的,get-started-with-hadoop-tutorial

并且假设我们已经了解Flume(agent, Source, Channel, Sink) , Morphline (ETL), Solr (全文检索),如果都没有了解,请自行百度。

Scenario (需求)

首先我们有多个web 应用,每个web应用每天都有不断的日志产生,这些日志文件现在以文件的形式存储在服务器当中,我们需要收集这些日志,并对日志进行查询

所以整个流程就是,Flume agent 收集日志 -> Morphline 进行过滤 -> 对结果进行索引然后在Solr中进行搜索。

Flume 收集日志

    1、使用 Spooling Directory Source
         就是监视指定目录是否有新文件移入,如果有,就会读取这些Event, 但是文件一旦被移到该目录之后,就不应该被写入,目录               下的文件名也不可重复,这样的情况就是需要定期将文件移动到指定的目录,不能实现实时的读取。

    2、使用 Exec Source
         就是通过下面的命令行产生的结果作为源,在agent 死亡或或者机器重启的过程可能会存在数据丢失
agent.sources.execSrc.type = exec
agent.sources.execSrc.shell=/bin/bash -c
agent.sources.execSrc.command= tail -F /var/log/flume/flume.log | grep "error: "
     1、使用消息中间件JMS或者KAFKA
          请参考: 基于Flume+Log4j+Kafka的日志采集架构方案
          客户端直接发送至kafaka queue , 用 log4j KafkaAppender

      2、使用Flume Appender
            对于Java web 应用,我们就最简单直接采取这种方式。 Flume Appender 我们这里就直接采用log4j2 , 关于日志框架的这些说                 明,请看另一片博客 spring boot use log4j log4j 关于flume Appender 的配置

The Flume Appender supports three modes of operation.

    1、It can act as a remote Flume client which sends Flume events via Avro to a Flume Agent configured with an Avro Source.(同                 步,Avro协议)

     2、It can act as an embedded Flume Agent where Flume events pass directly into Flume for processing.(异步,需要维护客户端                  flume)

      3、It can persist events to a local BerkeleyDB data store and then asynchronously send the events to Flume, similar to the    embedded Flume Agent but without most of the Flume dependencies.(先写数据库,再异步发送)

Usage as an embedded agent will cause the messages to be directly passed to the Flume Channel and then control will be immediately returned to the application. All interaction with remote agents will occur asynchronously. Setting the "type" attribute to "Embedded" will force the use of the embedded agent. In addition, configuring agent properties in the appender configuration will also cause the embedded agent to be used.

我们下面就简单的用第一种方式

客户端配置

log4j.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
  <Appenders>
    <Flume name="eventLogger" compress="true">
      <Agent host="192.168.10.101" port="8800"/>
      <Agent host="192.168.10.102" port="8800"/>
      <RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
    </Flume>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="eventLogger"/>
    </Root>
  </Loggers>
</Configuration>

服务端配置

参考:flume log4j appender config

下载 flume, 在conf 目录下,配置example.conf :

# example.conf: A single-node Flume configuration

# Name the components on this agent
a1.sources = r1
a1.sinks = k1
a1.channels = c1

# Describe/configure the source
a1.sources.r1.type = org.apache.flume.clients.log4jappender.Log4jAppender
a1.sources.r1.bind = localhost
a1.sources.r1.port = 44444

# Describe the sink
a1.sinks.k1.type = logger

# Use a channel which buffers events in memory
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 100

# Bind the source and sink to the channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

启动 flume

bin/flume-ng agent --conf conf --conf-file example.conf --name a1 -Dflume.root.logger=INFO,console

查看日志,是否成功。

Solr 配置

关于solr的介绍

这里 solr的数据也是需要存储到 hdfs中的,另外solr 是通过zookeeper 来管理的

以下配置,这里用的cloudera manager 安装,所以自动配好了,但是需要检验,如果是手动安装也有对应的文档可以直接查看, 另外这里省略Solr Authentication。

配置 zookeeper service

$ cat /etc/solr/conf/solr-env.sh
export SOLR_ZK_ENSEMBLE=zk01.example.com:2181,zk02.example.com:2181,zk03.example.com:2181/solr

配置 solr use hdfs

$ cat /etc/default/solr
//地址nn01.example.com:8020 是hdfs name node的地址
SOLR_HDFS_HOME=hdfs://nn01.example.com:8020/solr

//To create the /solr directory in HDFS,需要创建/solr hdfs目录:
$ sudo -u hdfs hdfs dfs -mkdir /solr
$ sudo -u hdfs hdfs dfs -chown solr /solr

initializing the ZooKeeper Namespace

$ sudo service solr-server restart

启动solr

$ sudo service solr-server restart

solr collection 配置

solr 通过 collection 来组织逻辑数据,所以你需要创建collection,每个collection有自己的配置,文档上已经讲的比较清楚了,而且也不多,这里不再赘述

Generating Collection Configuration

下面是的collection是用来存储上面收集到的日志:

// 使用默认模版创建instancedir
$ solrctl instancedir --generate $HOME/weblogs_config

// upload instancedir to zookeeper,上传配置
$ solrctl instancedir --create weblogs_config $HOME/weblogs_config

//verify instance
$ solrctl instancedir --list

// create collection  -s shard_count, collection 和config 关联
$ solrctl collection --create weblogs_collection -s 2 -c weblogs_config

A SolrCloud collection is the top-level object for indexing documents and providing a query interface. Each collection must be associated with an instance directory. Different collections can use the same instance directory. Each collection is typically replicated among several SolrCloud instances. Each replica is called a core and is assigned to an individual Solr service. The assignment process is managed automatically, although you can apply fine-grained control over each individual core using the solrctl core command . 这是 collection 和instance之间关系的介绍

成功创建之后如何修改和扩展,请参考这里solectl usage

Morphline (ETL)

创建好 collection 之后,我们就需要将日志解析存储到solr里,方便检索。Morphline 就是这个中间过程的ETL工具(extracting, transforming and loading data), Flume 提供了Morphlion Solr Sink, 从 log flume的source中读取event,经过ETL导入到solr中。

配置flume

继续上面的flume,中 example.conf 的配置

a1.sources = r1
a1.sinks = k1
a1.channels = c1

# Describe/configure the source
a1.sources.r1.type = avro
a1.sources.r1.bind = 0.0.0.0
a1.sources.r1.port = 4444

# Describe the sink
a1.sinks.k1.type = org.apache.flume.sink.solr.morphline.MorphlineSolrSink
a1.sinks.k1.morphlineFile=morphlines.conf
a1.sinks.k1.morphlineId = morphline_log4j2

# Use a channel which buffers events in memory
a1.channels.c1.type = memory
a1.channels.c1.capacity = 1000
a1.channels.c1.transactionCapacity = 1000

# Bind the source and sink to the channel
a1.sources.r1.channels = c1
a1.sinks.k1.channel = c1

配置Morphline

我们的日志格式文件如下:

[INFO ] 2017-07-14 11:40:51.556 [main] RequestMappingHandlerAdapter - Detected ResponseBodyAdvice bean in apiResponseAdvice

需要解析成:

level: INFO
create_time: 2017-07-14 11:40:51.556
thread: main
class:  RequestMappingHandlerAdapter
 -    //这里有个短横线
message: Detected ResponseBodyAdvice bean in apiResponseAdvice

所以我们使用grok
在线调试工具online tools

 # grok get data from unstructured line
     {
        grok {
          dictionaryFiles : [grok-dictionary.conf]
          expressions : {
            message : """\[%{LOGLEVEL:level} \] %{SC_LOGDATETIME:create_time} \[%{DATA:thread}\] %{WORD:class} [-] %{GREEDYDATA:message}"""
          }
        }

      }

      # Consume the output record of the previous command and pipe another
      # record downstream.
      #
      # convert timestamp field to native Solr timestamp format
      # e.g.  2017-07-14 11:40:52.512 to 2012-09-06T07:14:34.000Z
      {
        convertTimestamp {
          field : create_time
          inputFormats : ["yyyy-MM-dd HH:mm:ss.SSS", "yyyy-MM-dd"]
          inputTimezone : America/Los_Angeles
          outputFormat : "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
          outputTimezone : UTC
        }
      }

配置 schema.xml

在上一节,配置solr的时候,我们生成了默认的模版,我们需要根据实际的需求修改schema.xml,在$HOME/weblogs/conf 下

The schema.xml file contains all of the details about which fields your documents can contain, and how those fields should be dealt with when adding documents to the index, or when querying those fields.

schema.xml
solrconfig.xml

   <field name="level" type="text_general" indexed="true" stored="true" multiValued="true"/>
   <field name="create_time" type="date" indexed="true" stored="true"/>
   <field name="thread" type="text_general" indexed="true" stored="true"/>
   <field name="class" type="text_general" indexed="true" stored="true"/>
   <field name="message" type="text_general" indexed="true" stored="true"/>

重新上传配置到zookeeper

$ solrctl instancedir --update weblogs_config $HOME/weblogs_config
$ solrctl collection --reload weblogs_collection

总结

到此为止,我们完成了日志的收集,解析,索引,你可以通过 Hue来进行搜索和查询了,或者自己定义UI。这个教程比较基础也相对简单,但是可以完成基本的需求,也把日志处理流程走了一遍,剩下的大家自定义即可。

文章来源:https://my.oschina.net/tigerlene/blog/1475239

时间: 2024-09-30 03:32:52

Flume + Solr + log4j搭建web日志采集系统的相关文章

Flume日志采集系统——初体验(Logstash对比版)

这两天看了一下Flume的开发文档,并且体验了下Flume的使用. 本文就从如下的几个方面讲述下我的使用心得: 初体验--与Logstash的对比 安装部署 启动教程 参数与实例分析 Flume初体验 Flume的配置是真繁琐,source,channel,sink的关系在配置文件里面交织在一起,没有Logstash那么简单明了. Flume与Logstash相比,我个人的体会如下: Logstash比较偏重于字段的预处理:而Flume偏重数据的传输: Logstash有几十个插件,配置灵活:F

log4j直接输出日志到flume

log4j直接输出日志到flume         此jar是由Cloudera的CDH发行版提供的一个工具类,通过配置,可以将log4j的日志直接输出到flume,方便日志的采集.         在CDH5.3.0版本中是:flume-ng-log4jappender-1.5.0-cdh5.3.0-jar-with-dependencies.jar         所在目录是:/opt/cloudera/parcels/CDH/lib/flume-ng/tools/ 具体使用示例 log4j

flume学习(一):log4j直接输出日志到flume

log4j.properties配置: log4j.rootLogger=INFOlog4j.category.com.besttone=INFO,flumelog4j.appender.flume = org.apache.flume.clients.log4jappender.Log4jAppenderlog4j.appender.flume.Hostname = localhostlog4j.appender.flume.Port = 44444 log4j.appender.flume.

flume学习(三):flume将log4j日志数据写入到hdfs

在第一篇文章中我们是将log4j的日志输出到了agent的日志文件当中.配置文件如下: [plain] view plaincopy tier1.sources=source1   tier1.channels=channel1   tier1.sinks=sink1      tier1.sources.source1.type=avro   tier1.sources.source1.bind=0.0.0.0   tier1.sources.source1.port=44444   tier

使用Apache搭建Web服务(一)

在当今的互联网中常用的搭建web服务器的方法有两种,一种是IIS.一种是Apache.大家都知道IIS是微软的产品,只支持在windows系统上使用.那么我们想在Linux系统中搭建web服务器该怎么办呢?没错我们使用Apache.Apache因是开源软件,又可以跨平台使用,还支持多种网页格式,因此被使用在众多的Linux系统中. Apache的特点:开放软代码.可以跨平台使用.支持多种网页语言.可以模块化部署. 安装httpd服务器软件 在配置Apache网站服务之前,需要正确安装httpd服

使用elk+redis搭建nginx日志分析平台

elk+redis 搭建nginx日志分析平台 logstash,elasticsearch,kibana 怎么进行nginx的日志分析呢?首先,架构方面,nginx是有日志文件的,它的每个请求的状态等都有日志文件进行记录.其次,需要有个队列,redis的list结构正好可以作为队列使用.然后分析使用elasticsearch就可以进行分析和查询了. 我们需要的是一个分布式的,日志收集和分析系统.logstash有agent和indexer两个角色.对于agent角色,放在单独的web机器上面,

elk+redis 搭建nginx日志分析平台

elk+redis 搭建nginx日志分析平台 logstash,elasticsearch,kibana 怎么进行nginx的日志分析呢?首先,架构方面,nginx是有日志文件的,它的每个请求的状态等都有日志文件进行记录.其次,需要有个队列,redis的list结构正好可以作为队列使用.然后分析使用elasticsearch就可以进行分析和查询了. 我们需要的是一个分布式的,日志收集和分析系统.logstash有agent和indexer两个角色.对于agent角色,放在单独的web机器上面,

采用Serverless架构搭建Web应用

本文会向你介绍一种新的可能,一种无服务器的方案来搭建Web应用.使用这个方案大部分运维方面的问题就不需要你自己操心了,而且也省去运行服务器的费用.本文从无服务的优势与限制两方面带您初识Serverless设计. 在传统Web应用中,服务器是系统不可缺少的组成部分.尽管有时候服务器的前面还有负载均衡器或者专用Web服务器,但完成大部分工作的还是应用服务器.它完成一个应用所有的必要功能,包括存储用户数据.进行安全认证.控制流程等.应用的页面大部分仅仅只是为后端提供界面而已,尽管也会涉及一些控制导航的

log4j,slf4j (日志记录工具)

一个logger对应着若干个appender和一个日志级别. 一个appender对应着一个输出位置与格式. 1.获取 <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> 需要的jar包.log4j.properties文件等项目结构见图1. 图1