Hive Regex无法正常工作

时间:2015-09-29 19:32:02

标签: regex hadoop hive

我正在尝试使用org.apache.hadoop.hive.serde2.RegexSerDe创建一个hive外部表来分析一些Log4J日志。

然而,即使在http://www.regexr.com/中进行测试时,regex也无法正常工作。

我的问题是当我有多行日志时,例如,带有相应StackTrace的异常日志。

以下是一个例子:

@@@@ 2015-09-29T11:20:45,549 INFO MYHOSTNAME my-app org.hibernate.jpa.internal.util.LogHelper HHH000204: Processing PersistenceUnitInfo [
    name: name
    ...] @@@@

我在日志的开头和结尾添加了一个模式,以便在存在多行时帮助提取它。

这是我的正则表达式:

@@@@ (.{23}) ([\\w]+) ([\\w]+) ([\\w\\-]+) ([\\w\\.$]+) ([\\s\\S]+) @@@@

这是我的表:

CREATE EXTERNAL TABLE log4j(
    dt STRING,
    level STRING,
    host STRING,
    app_name STRING,
    clazz STRING,
    message STRING)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES ("input.regex" = "@@@@ (.{23}) ([\\w]+) ([\\w]+) ([\\w\\-]+) ([\\w\\.$]+) ([\\s\\S]+) @@@@")
STORED AS TEXTFILE
LOCATION 'hdfs://localhost:9000/logs/';

使用单行日志可以正常工作,但是对于多行,例如示例中的多行,它会提取多行,所有列都为null。

1 个答案:

答案 0 :(得分:0)

如果您使用:

STORED AS TEXTFILE

然后Hadoop将首先逐行(\r\n\r\n)以及第二分解输入将每个输入行送入 RegexSerDe 。这就是您无法使用TEXTFILE将多行输入转换为单行输出的原因。相反,请尝试使用:

STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'

将Hadoop配置属性textinputformat.record.delimiter设置为任意字符串可以分隔输入中的两个记录。对于您的数据,一个样本分隔符可能是@@@@\n@@@@@@@@\r\n@@@@。请注意,设置此分隔符会从数据中删除匹配的文本,因此您处理的记录中不会包含@@@@

在更改任何配置文件之前测试它的一种方法是在运行查询之前在Hive shell会话中设置它:

set textinputformat.record.delimiter=@@@@\n@@@@