hadoop - 将防火墙日志字段加载到 Hive 表

标签 hadoop logging hive apache-pig

我有来自防火墙的日志文件,但有些日志没有所有的列,或者它们以不同的顺序出现。

日志示例:

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

我已使用此脚本将日志字段加载到 Hive 表:

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 |
+---------------------+---------------+-------+----------------+--------------+-------------+

但是,我需要以这种格式将日志字段加载到 Hive 表中:

+---------------------+---------------+-------+----------------+--------------+-------------+
| 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 |
+---------------------+---------------+-------+----------------+--------------+-------------+

但是,Hive SerDe (Regex) 有此限制(根据 GitHub 中的文档):

"RegexSerDe使用正则表达式(regex)反序列化数据,不支持数据序列化。 它可以使用正则表达式反序列化数据并将组提取为列。 在反序列化阶段,如果一行与正则表达式不匹配,则该行中的所有列都将为 NULL。如果一行与正则表达式匹配但包含的组少于预期的组,则缺少的组将为 NULL。如果一行与正则表达式匹配但包含的组多于预期,则其他组将被忽略。”

如何将日志中不可用的字段加载到表中,其值等于NULL

是否有任何其他 Hadoop 生态系统工具允许我在将日志加载到 Hive 表之前格式化(或根据表字段映射日志字段)?

最佳答案

dst_ip=(.*?) 正在消耗文本的其余部分,因此第一行之后的所有内容都是 NULL

是否有任何其他 Hadoop 生态系统工具允许我在将日志加载到 Hive 表之前格式化(或根据表字段映射日志字段)?

Hive 可以工作,但您的 SerDe 需要更好地测试。如果你坚持使用 Regex,Pig 和 Spark 也会有同样的问题。

不过,您不需要正则表达式。使用竖线作为分隔符

ROW FORMAT DELIMITED 
FIELDS TERMINATED BY '|' 
LINES TERMINATED BY '\n' 
STORED AS TEXTFILE;

不过,在使用它之前,您需要清理数据以使其始终如一地分隔。例如,您需要 || 来分隔空字段。

您可以使用正则表达式来捕获缺失的字段,例如,

(?:application=(.*?)\\|)?

但是你总是希望列有严格的顺序

就我个人而言,Spark 是我的选择,它至少会在管道中拆分每一行,然后有条件地将每一列解析为一个类对象,从中定义一个数据集并将其写入 Hive

关于hadoop - 将防火墙日志字段加载到 Hive 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46722408/

相关文章:

hadoop - HDFS 中的文本文件未正确压缩

java.lang.Exception : java. io.IOException:设置 hadoop 和 hbase 时值类错误

apache-spark - Spark magic 输出提交器设置无法识别

hadoop - HDFS 名称节点 HA : Why use NFS rather than simply replicate between the two?

java - 为 JAVA CONSOLE CLIENT 打印 SOAP 消息

scala - 如何以惯用的方式向 Akka 流添加错误日志记录?

logging - Logstash 输入文件 - 从桌面文件读取

hadoop - 在配置单元中更改列名后,列的值变为 NULL

hive - 无法删除包含特殊字符等号(=)的hive表分区

sql - 在配置单元中拆分列