flume工作记录

启动flume

flume启动master 日志输出路径

starting master, logging to/home/demo/flume_output/log/flume/flume-demo-master-master.out

 

如果将master,node,和collector分出来的话,需要按照功能区分的服务器上启动不同的命令,具体命令如下:

Flume master //启动master

Flume node //启动node Flumenode_nowatch //启动node 但不启动watchdog。

Flume node/node_nowatch –n collector //启动collector

 

1.在远程登录服务器的时候,开了3个ssh客户端

分别启动master,node,最后一个负责执行flume shell(用于连接master[flume是基于zookeeper文件系统的分布式日志采集器,所以flume shell操作跟zookeeper非常相似])

2.执行启动 flume master 和 flume node报错。(已解决)[原因是未设置环境变量]

设置环境变量为:flume-env.sh

内容如下:

export FLUME_HOME=/opt/flume

export FLUME_CONF_DIR=/opt/flume/conf

exportFLUME_LOG_DIR=/home/demo/flume_output/log/flume

exportFLUME_PID_DIR=/home/demo/flume_output/run/flume

Flume web页面查看端口号

http://localhost:35871/flumemaster.jsp  // 访问主机页面

http://localhost:35862/flumeagent.jsp   // 访问node管理界面

http://localhost:35863/flumeagent.jsp   // 访问collector

 

监听、收集文件

exec mapDataNode1(物理节点名称) fooNode1(逻辑节点名称) //首先映射物理节点和逻辑节点,也就是先将要给搜集日志的物理节点设置一个逻辑节点名称

 

//然后设置逻辑节点要搜集日志的文件夹或者文件

exec configfooNode1 fooflow'tail("/opt/flume/testFlumeFileInfo/testAgentLog")'  'agentE2EChain("node1")'


exec config fooNode1 fooflow'tailDir("/home/hadoop/system/logs/flume")''agentE2EChain("DataNode1","DataNode2","DataNode3")'

 

//最后把搜集到的日志发送到目标文件夹或者hdfs

exec configDataNode1 fooflow collectorSource 'collectorSink("hdfs://NameNode:9000/flume/collected","foo")'

 

备注:一个物理节点可以映射多个逻辑节点,也就是说一个服务器上可以采集多块日志文件目录。然后到具体的跟踪日志文件的时候就能同时进行对多个agent节点进行日志采集。最后执行收集文件,就可以把搜集的日志文件汇总到最终的目标地点。

 

值得注意的是。在没有更改配置文件的时候,默认导入hdfs的格式是非常乱的。里面有很多暂时用不上的参数,比如说要采集的原日志文件中只有nihao这几个字母,但是导入到hdfs中后就会出现一大堆东西,比如说: /u000,…body….timestamp…

如果只想在hdfs中写入原有日志的内容,就把collector format的参数改成”raw”即可

 

如果要取消getconfigs里面的agent collector上的映射。执行 exec decommission node1

即可

flume日志动态跟踪

当被监控的日志文件夹里新增一个文件的时候:

如果该文件内容为空,那么将不写入最终的目标路径(hdfs)

如果创建了一个新文件,并且新文件里有内容的话,那么最终collector将收集被监控的文件夹里的新文件,然后将文件以数据流的形式做传递agent->collector->hdfs

 

 

跟踪写入到hdfs时的状态发现:

当被跟踪的文件夹里有新文件的时候,hdfs没有创建文件,当新创建的文件夹写入内容后,hdfs状态开始发生变化,首先观察到hdfs会新增一个tmp临时文件,当文件写入完成后,tmp文件会被移除,那么hdfs里将出现一个新增的hdfs文件。

Flume格式化输入的日志文件

参考过有关博客资料后,发现如果想要格式化输入的日志文件信息导入到hdfs中,需要修改配置文件,并且自己手写格式化jar包,并将jar包相应的部署到服务器上。

 

以下是参考的资料:

 

提取tailSrcFile中字串,将其添加到Event的元数据中,在Hadoop中建立符合Hive分区规范的目录层次。

PaserTailFile为例:

1Hive创建表指定Hadoop中文件目录(分区上层目录),设置好分区信息

eg:

create table if not exists test(

     id int,

     name string

)
partitioned by(school string,class int ) 
row format delimited fields terminated by "\t" 
location "/data/hivedata/student/";

2collector配置
exec config ******* 'collectorSource''{ParserTailFileDecorator("(.+)_(.+)_(.+)_(") =>collectorSink("hdfs://*****:9000/******/%{gameName}/%{logType}/rid=%{serverId}/logdate=%{dateStr}","%{tailSrcFile}-")}'

其中ParserTailFileDecorator第一个参数为正则表达式,其余参数为对应元组的名字

3agent配置

exec config *******'tailDir("*******","(.+)_(.+)_(.+)_(.+)('{value("gameName","******") =>agentE2EChain("******","*****","******")}'

4plugin

build.xml:

<?xml version="1.0"?>
<project name="flume-ParserTailFile" default="jar">
    <property name="javac.debug"value="on"/>
    <property name="flume.base"value="/home/hadoop/flume"/>

    <pathid="classpath">
        <pathelementlocation="${flume.base}/build/classes"/>
        <filesetdir="${flume.base}/lib">
            <includename="**/guava*.jar"/>
            <includename="**/log4j-*.jar"/>
            <includename="**/slf4j-*.jar"/>
        </fileset>

        <filesetdir="${flume.base}">
            <includename="flume-*.jar"/>
        </fileset>
        <pathelementlocation="${flume.base}/lib/"/>
    </path>

    <targetname="jar">
        <mkdir dir="build"/>
        <mkdirdir="build/classes"/>

       <javac srcdir="./src" destdir="build/classes"debug="${javac.debug}">
           <classpath refid="classpath"/>
        </javac>

        <jarjarfile="ParserTailFile.jar" basedir="build/classes"/>
     </target>

     <targetname="clean">
         <echo message="Cleaninggenerated files and stuff"/>
         <deletedir="build"/>
         <deletefile="ParserTailFile.jar"/>
     </target>
</project>

src\ParserTailFile\ParserTailFileDecorator.java

package ParserTailFile;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.*;
import java.util.HashMap; 
import java.util.Map;

import com.cloudera.flume.conf.Context;
import com.cloudera.flume.conf.SinkFactory.SinkDecoBuilder;
import com.cloudera.flume.core.Event;
import com.cloudera.flume.core.EventImpl;
import com.cloudera.flume.core.EventSink;
import com.cloudera.flume.core.EventSinkDecorator;
import com.cloudera.util.Pair;
import com.google.common.base.Preconditions;

public class ParserTailFileDecorator<S extendsEventSink> extends EventSinkDecorator<S> {
  public ParserTailFileDecorator(S s,String ...argvs) {
    super(s);
    _valArr = argvs.clone();
  }

  @Override
  public void append(Event e) throws IOException, InterruptedException {
     Map<String,byte[]> parserAttrs = newHashMap<String,byte[]>();  //
创建一个新的Map,
     parserAttrs.putAll(e.getAttrs()); // e.getAttrs
为只读
        
     if (e.getAttrs().containsKey("tailSrcFile"))
     {
         String tailSrcFile = newString(parserAttrs.get("tailSrcFile"));
         int len = _valArr.length;
         Pattern pattern =Pattern.compile(_valArr[0]);
         Matcher matcher =pattern.matcher(tailSrcFile);
        
         if (matcher.matches()&&  matcher.groupCount() >= len - 1)
         {
             for (inti=1; i < len; i++)
             {
                parserAttrs.put(_valArr[i],matcher.group(i).getBytes());
            } 
         } 
     }

     EventImpl e2 = newEventImpl(e.getBody(),
        e.getTimestamp(),e.getPriority(),e.getNanos(), e.getHost(),
        parserAttrs);
     super.append(e2); 
  }

  public static SinkDecoBuilder builder() {
    return new SinkDecoBuilder() {
      @Override
      public EventSinkDecorator<EventSink>build(Context context,
          String... argv) {
        Preconditions.checkArgument(argv.length>= 2,
            "usage:ParserDecorator(\"regex\",[groupName1,[groupName2,...]])");

        returnnew ParserTailFileDecorator<EventSink>(null,argv);
      }
    };
  }
  
  public static List<Pair<String, SinkDecoBuilder>>getDecoratorBuilders() {
    List<Pair<String, SinkDecoBuilder>> builders =
      new ArrayList<Pair<String,SinkDecoBuilder>>();
    builders.add(new Pair<String,SinkDecoBuilder>("ParserTailFileDecorator",
        builder()));
    return builders;
  }
  private String[] _valArr;
}

代码参考HelloWorldflume源码自身相关插件修改

编译后,将得到的ParserTailFile.jar 置于flume/lib下,并修改conf/flume-site.xml文件
  <property>
      <name>flume.plugin.classes</name>
     <value>ParserTailFile.ParserTailFileDecorator</value>
      <description>Comma separated list ofplugins</description>
  </property>

由于插件只在collector中使用,故ParserTailFile.jar 只需放到mastercollector端,而agent端不用放

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值