Flume Source对多行的处理

ExecSource会readLine()读取日志中的每一行,把其作为每一个flume event的body放进去,这对于大部分这种每行就可以结束的日志记录,是完全可以的:

1
2
2016-03-18 17:53:48,374 INFO namenode.FSNamesystem (FSNamesystem.java:listCorruptFileBlocks(7217)) - there are no corrupt file blocks.
2016-03-18 17:53:48,278 INFO namenode.FSNamesystem (FSNamesystem.java:listCorruptFileBlocks(7217)) - there are no corrupt file blocks.

但是,对于有stacktraceERROR日志记录,如果把一行的内容当作一个flume event会有很大的问题,直观上来看,肯定需要把若干行看作是一个flume event,比如下面这样的日志记录,要作为一个flume event,而不是27个(一共27行):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2016-03-18 17:53:40,278 ERROR [HiveServer2-Handler-Pool: Thread-26]: Error occurred during processing of message.
java.lang.RuntimeException: org.apache.thrift.transport.TTransportException: java.net.SocketException: Connection reset
at org.apache.thrift.transport.TSaslServerTransport$Factory.getTransport(TSaslServerTransport.java:219)
at org.apache.thrift.server.TThreadPoolServer$WorkerProcess.run(TThreadPoolServer.java:268)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.thrift.transport.TTransportException: java.net.SocketException: Connection reset
at org.apache.thrift.transport.TIOStreamTransport.read(TIOStreamTransport.java:129)
at org.apache.thrift.transport.TTransport.readAll(TTransport.java:86)
at org.apache.thrift.transport.TSaslTransport.receiveSaslMessage(TSaslTransport.java:178)
at org.apache.thrift.transport.TSaslServerTransport.handleSaslStartMessage(TSaslServerTransport.java:125)
at org.apache.thrift.transport.TSaslTransport.open(TSaslTransport.java:271)
at org.apache.thrift.transport.TSaslServerTransport.open(TSaslServerTransport.java:41)
at org.apache.thrift.transport.TSaslServerTransport$Factory.getTransport(TSaslServerTransport.java:216)
... 4 more
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:196)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:275)
at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
at org.apache.thrift.transport.TIOStreamTransport.read(TIOStreamTransport.java:127)
... 10 more

我这里的实现方式是:识别每行的开头部分,如果满足某种条件,就当作一条日志,否则,视作是上一条的日志的一部分。

比如:

对于上面举的例子来说(即符合标准log4j的日志),如果每一行开头满足下面这条正则表达式:

1
\s?\d\d\d\d-\d\d-\d\d\s\d\d:\d\d:\d\d,\d\d\d

就当作一条新的日志,如果不满足,就说明该行内容是上一条日志(已规定格式开头的那条)的一部分。

当然,我增加了可以自定义配置以哪种方式开头视为一条日志的regex配置,可以对不通的source进行不通的配置,已满足要求。

有了这样的约束,就可以写出将某些多行看作一个flume event的ExecSource,我把它开源到了github上,如有兴趣,欢迎前去试用,如有任何建议,欢迎提出与指正:MultiLineExecSource

1
github.com/qwurey/flume-source-multiline

该版本基于flume-ng-core 1.6.0

<think>好的,我现在需要帮助用户配置Flume,使用spooldir作为source监控指定目录,并将内容通过file_roll sink写入另一个目录。用户提到目录是C:/mylogs/和C:/backup/,系统是Windows 10,Flume 1.9.0。 首先,我得回忆一下Flume的基本组件结构,Agent由Source、Channel、Sink组成。spooldir source用于监控一个目录,当有新文件时读取,处理完成后会标记文件为完成,通常是添加.COMPLETED后缀。而file_roll sink则是将数据写入本地文件系统,可以指定目录,并且支持滚动生成新文件。 接下来,用户需要具体的配置文件。我应该先确定各个组件的配置参数。spooldir source需要指定spoolDir属性为C:/mylogs/,还要注意是否忽略隐藏文件,比如以.tmp开头的临时文件。可能需要设置fileHeader为true,这样在event的头信息中包含文件名,但用户的需求只是传输内容,可能不需要这个。不过根据经验,spooldir默认会添加文件头,但用户可能不需要,所以可能需要设置fileHeader为false? 然后是Channel的选择。用户没有特别要求,通常使用内存Channel,但要注意如果数据量较大可能会有丢数据的风险。不过对于测试环境,memory channel是合适的,所以配置type为memory,capacity和transactionCapacity根据默认值设置即可。 接下来是sink部分。file_roll sink需要指定sink.directory为C:/backup/,同时要配置滚动策略。默认情况下,file_roll会在指定时间间隔或达到一定大小后滚动文件,但用户可能需要自定义这些参数,比如设置rollInterval为0表示不按时间滚动,而是每个批次写入一个文件。不过需要查阅Flume文档确认参数的有效性。例如,sink.rollInterval单位是秒,设置为0可能禁用时间滚动,而sink.batchSize可能控制每个事务处理的事件数,影响写入频率。 另外,文件名的生成可能需要配置sink.pathManager,默认是默认的路径管理,但用户可能希望自定义文件名,不过file_roll sink默认会生成带有时间戳的文件名,或者按序列递增。这里可能需要进一步确认配置选项,比如是否支持自定义前缀或后缀。 还需要考虑文件编码和格式,比如是否以文本形式写入,是否需要序列化。spooldir source默认将文件内容作为event的body,每行一个event,还是整个文件作为一个event?哦,spooldir source会将整个文件内容作为单个event,或者按行分割,这取决于配置。默认情况下,spooldir会将整个文件作为一个event,但如果文件很大,可能需要拆分成多行,但通常spooldir适合处理不可变的、完整的文件,比如日志文件被移动进来后不再修改。因此,可能需要使用line deserializer来按行处理,但用户的需求是传输整个文件内容,可能需要使用默认的deserializer,即读取整个文件内容作为一个event。 然后,配置文件中需要将source、channel、sink连接起来。确保source的channel和sink的channel名称一致。例如,agent.sources = spoolSource,agent.channels = fileChannel,agent.sinks = fileSink,然后绑定各自的channel。 还需要注意Windows路径的写法,应该使用正斜杠或者双反斜杠。比如C:/mylogs/或C:\\mylogs\\,但在Flume配置中通常使用正斜杠即可,因为Java可以处理。 可能的问题点包括:spooldir监控的目录是否有权限,文件是否被其他进程占用,处理后的文件是否被正确重命名,避免重复处理。需要提醒用户将文件放入监控目录后,Flume会立即处理处理后的文件会被加上.COMPLETED后缀,因此用户不应手动修改或删除这些文件,否则可能导致错误。 此外,file_roll sink的目录需要存在吗?可能Flume不会自动创建目录,所以用户需要确保C:/backup/存在,否则会报错。同时,检查sink的配置参数是否正确,比如sink.directory是否写对了路径。 最后,启动Flume的命令需要正确指定配置文件名称和agent名称,例如: flume-ng agent --conf conf --conf-file spooldir-to-fileroll.conf --name agent -Dflume.root.logger=INFO,console 这样可以在控制台看到日志,方便调试。 总结步骤:编写配置文件,设置spooldir source监控C:/mylogs/,使用memory channel,file_roll sink写入C:/backup/,配置相关参数如批处理大小、滚动间隔,确保路径正确,启动Flume并测试。</think>--- ### Flume Spooldir + File Roll 配置详解 #### 一、配置文件 `spooldir-to-fileroll.conf` ```properties # 定义Agent组件 agent.sources = spoolSource agent.channels = memChannel agent.sinks = fileSink # 配置Spooldir Source(监控C:/mylogs/) agent.sources.spoolSource.type = spooldir agent.sources.spoolSource.spoolDir = C:/mylogs/ agent.sources.spoolSource.fileHeader = false # 不添加文件名头信息 agent.sources.spoolSource.ignorePattern = ^\\..*$ # 忽略隐藏文件(如.tmp临时文件) # 配置Memory Channel agent.channels.memChannel.type = memory agent.channels.memChannel.capacity = 1000 # 最大事件数 agent.channels.memChannel.transactionCapacity = 100 # 单次事务处理量 # 配置File Roll Sink(写入C:/backup/) agent.sinks.fileSink.type = file_roll agent.sinks.fileSink.sink.directory = C:/backup/ # 输出目录 agent.sinks.fileSink.sink.rollInterval = 0 # 关闭时间滚动 agent.sinks.fileSink.sink.batchSize = 10 # 每10个事件写入一次 agent.sinks.fileSink.sink.filePrefix = log # 文件名前缀 agent.sinks.fileSink.sink.fileSuffix = .dat # 文件名后缀 # 绑定组件 agent.sources.spoolSource.channels = memChannel agent.sinks.fileSink.channel = memChannel ``` --- #### 二、关键参数说明 1. **Spooldir Source**: - `spoolDir`:被监控的输入目录(文件移入后会被自动处理) - `ignorePattern`:通过正则表达式忽略临时文件 - **文件处理规则**: - 文件名不能重复(建议使用唯一标识如时间戳) - 文件处理完成后添加`.COMPLETED`后缀[^1] 2. **File Roll Sink**: - `rollInterval`:文件滚动时间间隔(秒),设为0表示禁用时间触发 - `batchSize`:控制写入频率(每N个事件触发一次写入) - **输出文件示例**:`C:/backup/log.1712345678.dat` --- #### 三、操作流程 1. **准备目录**: ```bash mkdir C:\mylogs # 监控目录 mkdir C:\backup # 输出目录 ``` 2. **启动Flume Agent**: ```bash flume-ng agent --conf conf --conf-file spooldir-to-fileroll.conf --name agent -Dflume.root.logger=INFO,console ``` 3. **测试验证**: ```bash # 将测试文件复制到监控目录 copy test.log C:\mylogs\data_20240520.log # 观察输出目录生成文件 dir C:\backup ``` --- #### 四、故障排查指南 | 现象 | 可能原因 | 解决方案 | |---------------------|-------------------------|----------------------------| | 文件未处理 | 文件名重复或正在写入 | 确保文件完全生成后再移入监控目录 | | 输出目录无文件 | 路径权限问题 | 以管理员身份运行Flume Agent | | 出现`.COMPLETED`文件但无输出 | Channel容量不足 | 增大`memoryChannel.capacity` | --- #### 五、性能优化建议 1. **提升吞吐量**: ```properties agent.channels.memChannel.capacity = 50000 # 增大Channel容量 agent.sources.spoolSource.batchSize = 500 # 增大批处理量 ``` 2. **文件滚动策略**: ```properties agent.sinks.fileSink.sink.rollInterval = 3600 # 每小时生成新文件 agent.sinks.fileSink.sink.maxFileSize = 1048576 # 文件最大1MB ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值