Flume日志长度2048超长问题解决

最近笔者在使用Flume-1.7进行日志收集的时候,遇到了日志长度超出2048限制等一系列问题,经过一天的排查终于将问题解决,在此将问题记录下来,并提供了修改后的flume-ng-core-1.7.0下载包,供后来的同学参考

问题描述

首先,笔者发现问题是由于发现近期日志总量变少,去排查了Flume的运行日志,发现原因是大量的日志被拦截器干掉了(此处笔者使用了自定义拦截器,对于日志字段不符合长度的进行剔除处理),从日志中能看到以下有用的ERROR信息:Line length exceeds max (2048), truncating line! ,大致意思是单行日志长度超出2048字节,带着问题,我们开始寻求解决方案。

问题解决

按照惯例,先拿着问题上网搜索,网上给出的答案是这个日志长度限制并不能通过修改配置来解决,且看样子是写死在了代码中,ok,去官网拉取了Flume-1.7.0版本的源码,清华镜像地址:https://mirrors.tuna.tsinghua.edu.cn/apache/flume/1.7.0/apache-flume-1.7.0-src.tar.gz
很容易,我们找到了参数写死的地方,在org.apache.flume.serialization.LineDeserializer类中

@InterfaceAudience.Private
@InterfaceStability.Evolving
public class LineDeserializer implements EventDeserializer {

  private static final Logger logger = LoggerFactory.getLogger(LineDeserializer.class);

  private final ResettableInputStream in;
  private final Charset outputCharset;
  private final int maxLineLength;
  private volatile boolean isOpen;

  public static final String OUT_CHARSET_KEY = "outputCharset";
  public static final String CHARSET_DFLT = "UTF-8";

  public static final String MAXLINE_KEY = "maxLineLength";
  public static final int MAXLINE_DFLT = 2048;

  LineDeserializer(Context context, ResettableInputStream in) {
    this.in = in;
    this.outputCharset = Charset.forName(
        context.getString(OUT_CHARSET_KEY, CHARSET_DFLT));
    this.maxLineLength = context.getInteger(MAXLINE_KEY, MAXLINE_DFLT);
    this.isOpen = true;
  }

我们把MAXLINE_DFLT参数从2048改成了20480,编译重新打包上传到flume的lib目录下替换原来的flume-ng-core-1.7.0.jar包,一切看起来都很顺利,我们在测试环境进行了测试,用的干净的Flume,无任何其他自定义包,SpoolDir测了下,果然,2048长度问题解决了,看起来很完美没有任何问题。

紧接着笔者去生产环境实操了一把,诡异的问题出现了,好像替换了jar包后并没有生效,问题依旧啊,后续进过多次分析对比发现问题根源所在,主要是由于笔者使用了自定义的Intercepter拦截器和自定义的Sink,而这两个自定义功能的jar都引用了flume-ng-core-1.7.0, 但是这两个自定义jar引用了原生的flume-ng-core-1.7.0.jar,且在加载的时候先加载进了原生的flume-ng-core-1.7.0.jar,也就是说我们修改后的flume-ng-core-1.7.0.jar并未生效,发现问题后,赶紧重新编译打包两个自定义jar包,至此,2048问题看样子是都解决了,改替换的包全都换了一遍,但是新的问题又出现了

由于笔者的生产环境使用的SyslogUDP的source, 使用中我们发现有很多消息压根就没发完整,而是在2048字节处被截断,带着前面解决问题的经验,我们去看了SyslogUDP的源码,希望能发现点儿什么

public class SyslogUDPSource extends AbstractSource
                             implements EventDrivenSource, Configurable {

  private int port;
  private int maxsize = 1 << 16; // 64k is max allowable in RFC 5426
  private String host = null;
  private Channel nettyChannel;
  private Map<String, String> formaterProp;
  private Set<String> keepFields;

  private static final Logger logger = LoggerFactory.getLogger(SyslogUDPSource.class);

  private SourceCounter sourceCounter;

  // Default Min size
  public static final int DEFAULT_MIN_SIZE = 2048;
  public static final int DEFAULT_INITIAL_SIZE = DEFAULT_MIN_SIZE;

  public class syslogHandler extends SimpleChannelHandler {
    private SyslogUtils syslogUtils = new SyslogUtils(DEFAULT_INITIAL_SIZE, null, true);

    public void setFormater(Map<String, String> prop) {
      syslogUtils.addFormats(prop);
    }

    public void setKeepFields(Set<String> keepFields) {
      syslogUtils.setKeepFields(keepFields);
    }

果然,我们发现SyslogUDP这个source确实对数据长度做了限制,超出的部分会丢弃,问题明了了,修改,编译,打包,替换,所有的问题都得到了解决。

修改后的Jar包如下,替换flume的lib目录下原jar包即可,下载地址:https://download.csdn.net/download/u013716179/11829200

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值