flume自带很长多的source,如:exe、kafka...其中有一个非常简单的source——httpsource,使用httpSource,flume启动后会拉起一个web服务来监听指定的ip和port。常用的使用场景:对于有些应用环境中,不能部署Flume SDK及其依赖项,可以在代码中通过HTTP而不是Flume的PRC发送数据的情况,此时HTTP SOURCE可以用来将数据接收到Flume中。

1、httpsource 参数:

配置参数 默认值 描述
type   http (org.apache.fluem.source.httpSource)
bind   绑定的IP地址或主机名
port   绑定的端口号
enableSSL false  
keystore   使用的keystore文件的路径
keystorePassword   能够进入keystore的密码
handler JSONHandler HTTP SOURCE使用的处理程序类
handler.*   传给处理程序类的任何参数 可以 通过使用此参数(*)配置传入

1)handler:

Flume使用一个可插拔的“handler”程序来实现转换,如果不指定默认是:JSONHandler,它能处理JSON格式的事件,格式如下。此外用户可以自定义handler,必须实现HTTPSourceHandler接口。

json数据格式:

  1. [ { "headers":{"":"","":""
  2. },
  3. "body":"the first event"
  4. },
  5. { "headers":{"":"","":""
  6. },
  7. "body":"the second event"
  8. }
  9. ]

2、简单介绍一下flume的logger sink:

记录INFO级别的日志,一般用于调试。本文将使用这种类型的sink,配置的属性:

  • type  logger
  • maxBytesToLog    16    Maximum number of bytes of the Event body to log

注意:要求必须在 --conf 参数指定的目录下有 log4j的配置文件,可以通过-Dflume.root.logger=INFO,console在命令启动时手动指定log4j参数。

3、简单的httpSource实例:

1)下载flume、解压:

  1. cd /usr/local/
  2. wget http://mirror.bit.edu.cn/apache/flume/1.7.0/apache-flume-1.7.0-bin.tar.gz
  3. tar -xvzf apache-flume-1.7.9-bin.tar.gz

配置flume的环境变量:

  1. vim /etc/profile
  2. export PS1="[\u@`/sbin/ifconfig eth0|grep 'inet '|awk -F'[: ]+' '{print $4}'` \W]"'$ '
  3. export FLUME_HOME=/usr/local/apache-flume-1.6.0-bin
  4. export PATH=$PATH:$FLUME_HOME/bin

2)安装jdk、配置环境变量;

3)配置flume:

  1. cd /usr/local/flume/conf
  2. vim flume-env.sh

指定java_home,同时放入如下log4j.properties

  1. ### set log levels ###
  2. log4j.rootLogger = info,stdout ,  D ,  E
  3. ###
  4. log4j.appender.stdout = org.apache.log4j.ConsoleAppender
  5. log4j.appender.stdout.Target = System.out
  6. log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
  7. log4j.appender.stdout.layout.ConversionPattern =  [%d{MM-dd HH:mm:ss}] [%p] [%c:%L] %m%n
  8. ### 输出到日志文件 ###
  9. log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
  10. log4j.appender.D.File = /data/logs/flume/flume.log
  11. log4j.appender.D.Append = true
  12. log4j.appender.D.Threshold = info
  13. log4j.appender.D.layout = org.apache.log4j.PatternLayout
  14. log4j.appender.D.layout.ConversionPattern = [%d{MM-dd HH:mm:ss}] [%p] [%c:%L] %m%n
  15. ### 保存异常信息到单独文件 ###
  16. log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
  17. log4j.appender.E.File =/data/logs/flume/flume_error.log
  18. log4j.appender.E.Append = true
  19. log4j.appender.E.Threshold = ERROR
  20. log4j.appender.E.layout = org.apache.log4j.PatternLayout
  21. log4j.appender.E.layout.ConversionPattern = [%d{MM-dd HH:mm:ss}] [%p] [%c:%L] %m%n
  22. ### sink
  23. log4j.logger.com.iqiyi.ttbrain.log.flume.sink.MysqlSink= INFO, F, EE
  24. log4j.additivity.com.iqiyi.ttbrain.log.flume.sink.MysqlSink = false
  25. log4j.appender.F= org.apache.log4j.DailyRollingFileAppender
  26. log4j.appender.F.File=/data/logs/flume/flume_sink.log
  27. log4j.appender.F.Append = true
  28. log4j.appender.F.Threshold = info
  29. log4j.appender.F.layout=org.apache.log4j.PatternLayout
  30. log4j.appender.F.layout.ConversionPattern= [%d{MM-dd HH:mm:ss}] [%p] [%c:%L] %m%n
  31. log4j.appender.EE= org.apache.log4j.DailyRollingFileAppender
  32. log4j.appender.EE.File=/data/logs/flume/flume_sink_error.log
  33. log4j.appender.EE.Append = true
  34. log4j.appender.EE.Threshold = ERROR
  35. log4j.appender.EE.layout=org.apache.log4j.PatternLayout
  36. log4j.appender.EE.layout.ConversionPattern= [%d{MM-dd HH:mm:ss}] [%p] [%c:%L] %m%n

4)配置httpSource:

  1. cd /usr/local/flume/conf
  2. vim http_test.conf
  3. a1.sources=r1
  4. a1.sinks=k1
  5. a1.channels=c1
  6. a1.sources.r1.type=http
  7. a1.sources.r1.bind=localhost
  8. a1.sources.r1.port=50000
  9. a1.sources.r1.channels=c1
  10. a1.sinks.k1.type=logger
  11. a1.sinks.k1.channel=c1
  12. a1.channels.c1.type=memory
  13. a1.channels.c1.capacity=1000
  14. a1.channels.c1.transactionCapacity=100

5)启动flume:

  1. flume-ng agent -c /usr/local/flume/conf/ -f /usr/local/flume/conf/http_test.conf -n a1

6)测试:

开一个shell窗口,输入命令:

  1. curl -X POST -d'[{"headers":{"h1":"v1","h2":"v2"},"body":"hello body"}]'  http://localhost:50000

在/data/log/flume/flume.log 文件中可以看到:

  1. [09-29 10:31:12] [INFO] [org.apache.flume.sink.LoggerSink:94] Event: { headers:{h1=v1, h2=v2} body: 68 65 6C 6C 6F 20 62 6F 64 79                   hello body }

4、自定义handler:

假定xml请求格式,期望格式如下:

  1. <events>
  2. <event>
  3. <headers><header1>value1</header1></headers>
  4. <body>test</body>
  5. </event>
  6. <event>
  7. <headers><header1>value1</header1></headers>
  8. <body>test2</body>
  9. </event>
  10. </events>

1)pom.xml

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  3. <modelVersion>4.0.0</modelVersion>
  4. <groupId>org.pq</groupId>
  5. <artifactId>flume-demo</artifactId>
  6. <packaging>jar</packaging>
  7. <version>1.0</version>
  8. <name>flume-demo Maven jar</name>
  9. <url>http://maven.apache.org</url>
  10. <dependencies>
  11. <dependency>
  12. <groupId>junit</groupId>
  13. <artifactId>junit</artifactId>
  14. <version>4.8.2</version>
  15. <scope>test</scope>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.slf4j</groupId>
  19. <artifactId>slf4j-log4j12</artifactId>
  20. <version>1.7.7</version>
  21. <scope>compile</scope>
  22. </dependency>
  23. <dependency>
  24. <groupId>org.apache.flume</groupId>
  25. <artifactId>flume-ng-core</artifactId>
  26. <version>1.6.0</version>
  27. <scope>compile</scope>
  28. </dependency>
  29. </dependencies>
  30. <build>
  31. <finalName>flume-demo</finalName>
  32. </build>
  33. </project>

2)自定义handler:

  1. package org.pq.flumeDemo.sources;
  2. import com.google.common.base.Preconditions;
  3. import org.apache.flume.Context;
  4. import org.apache.flume.Event;
  5. import org.apache.flume.event.EventBuilder;
  6. import org.apache.flume.source.http.HTTPBadRequestException;
  7. import org.apache.flume.source.http.HTTPSourceHandler;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10. import org.w3c.dom.Document;
  11. import org.w3c.dom.Element;
  12. import org.w3c.dom.Node;
  13. import org.w3c.dom.NodeList;
  14. import org.xml.sax.SAXException;
  15. import javax.servlet.http.HttpServletRequest;
  16. import javax.xml.parsers.DocumentBuilder;
  17. import javax.xml.parsers.DocumentBuilderFactory;
  18. import java.util.ArrayList;
  19. import java.util.HashMap;
  20. import java.util.List;
  21. import java.util.Map;
  22. public class HTTPSourceXMLHandler implements HTTPSourceHandler {
  23. private final String ROOT = "events";
  24. private final String EVENT_TAG = "event";
  25. private final String HEADERS_TAG = "headers";
  26. private final String BODY_TAG = "body";
  27. private final String CONF_INSERT_TIMESTAMP = "insertTimestamp";
  28. private final String TIMESTAMP_HEADER = "timestamp";
  29. private final DocumentBuilderFactory documentBuilderFactory
  30. = DocumentBuilderFactory.newInstance();
  31. // Document builders are not thread-safe.
  32. // So make sure we have one for each thread.
  33. private final ThreadLocal<DocumentBuilder> docBuilder
  34. = new ThreadLocal<DocumentBuilder>();
  35. private boolean insertTimestamp;
  36. private static final Logger LOG = LoggerFactory.getLogger(HTTPSourceXMLHandler.class);
  37. public List<Event> getEvents(HttpServletRequest httpServletRequest) throws HTTPBadRequestException, Exception {
  38. if (docBuilder.get() == null) {
  39. docBuilder.set(documentBuilderFactory.newDocumentBuilder());
  40. }
  41. Document doc;
  42. final List<Event> events;
  43. try {
  44. doc = docBuilder.get().parse(httpServletRequest.getInputStream());
  45. Element root = doc.getDocumentElement();
  46. root.normalize();
  47. // Verify that the root element is "events"
  48. Preconditions.checkState(
  49. ROOT.equalsIgnoreCase(root.getTagName()));
  50. NodeList nodes = root.getElementsByTagName(EVENT_TAG);
  51. LOG.info("get nodes={}",nodes);
  52. int eventCount = nodes.getLength();
  53. events = new ArrayList<Event>(eventCount);
  54. for (int i = 0; i < eventCount; i++) {
  55. Element event = (Element) nodes.item(i);
  56. // Get all headers. If there are multiple header sections,
  57. // combine them.
  58. NodeList headerNodes
  59. = event.getElementsByTagName(HEADERS_TAG);
  60. Map<String, String> eventHeaders
  61. = new HashMap<String, String>();
  62. for (int j = 0; j < headerNodes.getLength(); j++) {
  63. Node headerNode = headerNodes.item(j);
  64. NodeList headers = headerNode.getChildNodes();
  65. for (int k = 0; k < headers.getLength(); k++) {
  66. Node header = headers.item(k);
  67. // Read only element nodes
  68. if (header.getNodeType() != Node.ELEMENT_NODE) {
  69. continue;
  70. }
  71. // Make sure a header is inserted only once,
  72. // else the event is malformed
  73. Preconditions.checkState(
  74. !eventHeaders.containsKey(header.getNodeName()),
  75. "Header expected only once " + header.getNodeName());
  76. eventHeaders.put(
  77. header.getNodeName(), header.getTextContent());
  78. }
  79. }
  80. Node body = event.getElementsByTagName(BODY_TAG).item(0);
  81. if (insertTimestamp) {
  82. eventHeaders.put(TIMESTAMP_HEADER, String.valueOf(System
  83. .currentTimeMillis()));
  84. }
  85. events.add(EventBuilder.withBody(
  86. body.getTextContent().getBytes(
  87. httpServletRequest.getCharacterEncoding()),
  88. eventHeaders));
  89. }
  90. } catch (SAXException ex) {
  91. throw new HTTPBadRequestException(
  92. "Request could not be parsed into valid XML", ex);
  93. } catch (Exception ex) {
  94. throw new HTTPBadRequestException(
  95. "Request is not in expected format. " +
  96. "Please refer documentation for expected format.", ex);
  97. }
  98. return events;
  99. }
  100. public void configure(Context context) {
  101. insertTimestamp = context.getBoolean(CONF_INSERT_TIMESTAMP,
  102. false);
  103. }
  104. }

打包成dependency,然后放到flume的lib下。

3)flume配置文件:

  1. a1.sources=r1
  2. a1.sinks=k1
  3. a1.channels=c1
  4. a1.sources.r1.type=http
  5. a1.sources.r1.bind=localhost
  6. a1.sources.r1.port=50000
  7. a1.sources.r1.channels=c1
  8. a1.sources.r1.handler=org.pq.flumeDemo.sources.HTTPSourceXMLHandler
  9. a1.sources.r1.insertTimestamp=true
  10. a1.sinks.k1.type=logger
  11. a1.sinks.k1.channel=c1
  12. a1.channels.c1.type=memory
  13. a1.channels.c1.capacity=1000
  14. a1.channels.c1.transactionCapacity=100

4)启动:

    1. $ bin/flume-ng agent -c conf -f conf/http_test.conf  -n a1 -Dflume.root.logger=INFO,console

flume使用之httpSource的更多相关文章

  1. send data to Flume client-sdk flume使用之httpSource

    https://flume.apache.org/FlumeDeveloperGuide.html#client-sdk flume使用之httpSource - CSDN博客 https://blo ...

  2. flume使用示例

    flume的特点: flume是一个分布式.可靠.和高可用的海量日志采集.聚合和传输的系统.支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受 ...

  3. Flume环境部署和配置详解及案例大全

    flume是一个分布式.可靠.和高可用的海量日志采集.聚合和传输的系统.支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受方(比如文本.HDF ...

  4. 常见的几种Flume日志收集场景实战

    这里主要介绍几种常见的日志的source来源,包括监控文件型,监控文件内容增量,TCP和HTTP. Spool类型 用于监控指定目录内数据变更,若有新文件,则将新文件内数据读取上传 在教你一步搭建Fl ...

  5. flume安装及入门实例

    1. 如何安装? 1)将下载的flume包,解压到/home/hadoop目录中 2)修改 flume-env.sh 配置文件,主要是JAVA_HOME变量设置 root@m1:/home/hadoo ...

  6. 【翻译】Flume 1.8.0 User Guide(用户指南) Processors

    翻译自官网flume1.8用户指南,原文地址:Flume 1.8.0 User Guide 篇幅限制,分为以下5篇: [翻译]Flume 1.8.0 User Guide(用户指南) [翻译]Flum ...

  7. Flume配置Multiplexing Channel Selector

    1 官网内容 上面配置的是根据不同的heder当中state值走不同的channels,如果是CZ就走c1 如果是US就走c2 c3 其他默认走c4 2 我的详细配置信息 一个监听http端口 然后 ...

  8. 海量日志采集Flume(HA)

    海量日志采集Flume(HA) 1.介绍: Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据 ...

  9. Flume组件汇总2

    Component Interface Type Alias Implementation Class org.apache.flume.Channel memory org.apache.flume ...

随机推荐

  1. Git图形化界面客户端大汇总

    文,还在不断更新,网上搜到的同名文章都是未经同意就从这里复制过去的) 一.TortoiseGit - The coolest Interface to Git Version Control Tort ...

  2. linux----别名

    经常一些命令太长,输入太麻烦,给该命令起个别名,直接执行,简单又方便. 1.查看别名 alias 2.编辑别名 vi ~/.brashrc 3.添加自己的别名 例如:重启网卡 alias netres ...

  3. 【java多线程】java8的流操作api和fork/join框架

    原文:https://blog.csdn.net/u011001723/article/details/52794455/ 一.测试一个案例,说明java8的流操作是并行操作 1.代码 package ...

  4. golang-test-tool-gotests

    gotests介绍 gotests是一个Golang命令行工具 ,让Go测试变得容易.它根据目标源文件的函数和方法签名生成表驱动的测试(TDD).任何测试文件中新的依赖都会被自动倒入 Demo 下面是 ...

  5. zabbix怎么把英文界面换成中文

    虽然能勉勉强强能看懂大部分英文,但感觉还是直接换中文方便上手一点

  6. mysql(mariadb)新建用户及用户授权管理

    仅新建一个newuser用户 方法一: MariaDB [(none)]> create user newuser@localhost identified by '123456'; Query ...

  7. C++中的抽象类

    一.抽象类学习笔记 1.virtual修饰函数(虚函数)后面加=0就称为一个纯虚函数,一个类中只要有纯虚函数那么它就是一个抽象类.抽象类不能用来实例化对象,是用来给他的派生类定义好这些框架的,给使用这 ...

  8. madlib 集成 hasura graphql-engine 试用

    madlib 可以让我们直接在sql 中进行机器学习,集成了强大的sql 能力,以及分析能力,后边会尝试 集成graphql engine ,让功能更强大 docker 镜像准备 使用了一个别人的写好 ...

  9. 20165308 《Java程序设计》第9周学习总结

    20165308 <Java程序设计>第9周学习总结 教材学习内容总结 13章知识总结 获取地址 1.获取Internet上主机的地址 可以使用InetAddress类的静态方法getBy ...

  10. MySQL 5.7 修改root密码

    更新 MySQL 5.7 以后通过以下方法无法在修改root密码: ') where user='root'; 查看下MySQL的官方文档发现版本更新后原来user里的password字段已经变更为a ...