我正在尝试使用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。
答案 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@@@@