我有来自防火墙的日志文件,但是有些日志没有所有的列,或者它们以不同的顺序出现。
日志示例:
time=2013-08-07 15:00:38|log_component=Firewall Rule|status=Allow|application=Skype Services|src_ip=172.16.16.79|dst_ip=192.168.2.4
time=2013-08-07 15:00:39|log_component=Firewall Rule|status=Allow|src_ip=172.16.16.80
time=2013-08-07 15:00:40|status=Allow|src_ip=172.16.16.81|dst_ip=192.168.2.6
time=2013-08-07 15:00:41|log_component=Firewall Rule|status=Allow|application=Gmail Services|src_ip=172.16.16.82|dst_ip=192.168.2.7
我已使用此脚本将日志字段加载到配置单元表:
DROP TABLE IF EXISTS firewall_logs;
CREATE TABLE firewall_logs(
time STRING,
log_component STRING,
status STRING,
application STRING,
src_ip STRING,
dst_ip STRING
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "time=(.*?)\\|log_component=(.*?)\\|status=(.*?)\\|application=(.*?)\\|src_ip=(.*?)\\|dst_ip=(.*?)",
"output.format.string" = "%1$s %2$s %3$s %4$s %5$s %6$s"
)
STORED AS TEXTFILE;
LOAD DATA LOCAL INPATH "/home/hadoop/firewall.log" INTO TABLE firewall_logs;
SELECT * FROM firewall_logs;
这是查询的结果:
+---------------------+---------------+-------+----------------+--------------+-------------+
| 2013-08-07 15:00:38 | Firewall Rule | Allow | Skype Services | 172.16.16.79 | 192.168.2.4 |
| NULL | NULL | NULL | NULL | NULL | NULL |
| NULL | NULL | NULL | NULL | NULL | NULL |
| 2013-08-07 15:00:41 | Firewall Rule | Allow | Gmail Services | 172.16.16.82 | 192.168.2.7 |
+---------------------+---------------+-------+----------------+--------------+-------------+
但是,我需要使用以下格式将日志字段加载到配置单元表:
+---------------------+---------------+-------+----------------+--------------+-------------+
| 2013-08-07 15:00:38 | Firewall Rule | Allow | Skype Services | 172.16.16.79 | 192.168.2.4 |
| 2013-08-07 15:00:39 | Firewall Rule | Allow | *NULL* | 172.16.16.80 | *NULL* |
| 2013-08-07 15:00:40 | *NULL* | Allow | *NULL* | 172.16.16.81 | 192.168.2.6 |
| 2013-08-07 15:00:41 | Firewall Rule | Allow | Gmail Services | 172.16.16.82 | 192.168.2.7 |
+---------------------+---------------+-------+----------------+--------------+-------------+
但是,hiveserde(regex)有这个限制(根据github中的文档):
“regexserde使用正则表达式(regex)反序列化数据。它不支持数据序列化。它可以使用regex反序列化数据,并将组提取为列。在反序列化阶段,如果一行与regex不匹配,那么该行中的所有列都将为null。如果一行与regex匹配,但包含的组少于预期的组,则缺少的组将为null。如果一行与regex匹配,但有多于预期的组,则会忽略其他组。”
如何使日志中不可用的字段以等于null的值加载到表中。
是否有其他hadoop生态系统工具允许我在将日志加载到hive表之前格式化(或根据表字段Map日志字段)?
2条答案
按热度按时间bkkx9g8r1#
创建表temp(行字符串);
将数据加载到表temp中
插入到主表中,作为select spilt(regexp\u extract(line,“((time=?)[0-9](-)[0-9](\s)[0-9](:)[0-9](:)[0-9](-)[0-9](-)(-)”,=”)[1]作为临时页
我为一列编写regex,你为所有列编写regex
从temp中选择regex()作为col1,regex()作为col2。
我希望这有帮助。
i7uaboj42#
dst_ip=(.*?)
正在消耗剩余的文本,因此第一行之后的所有内容都为空是否有其他hadoop生态系统工具允许我在将日志加载到hive表之前格式化(或根据表字段Map日志字段)?
Hive可以工作,但你的serde需要更好的测试。如果你坚持使用regex,pig和spark会有同样的问题。
不过,您不需要regex。使用管道作为分隔符
不过,在使用之前,您需要清理数据,使其具有一致的分隔符。例如,你需要
||
划定空白区域。您可以使用regex捕获缺少的字段,例如,
但你总是希望列的顺序很严格
就我个人而言,spark将是我的选择,至少在管道上拆分每一行,然后有条件地将每一列解析为一个class对象,从中定义一个数据集并将其写入hive