将防火墙日志字段加载到配置单元表

nr7wwzry  于 2021-06-02  发布在  Hadoop
关注(0)|答案(2)|浏览(341)

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

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日志字段)?

bkkx9g8r

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。
我希望这有帮助。

i7uaboj4

i7uaboj42#

dst_ip=(.*?) 正在消耗剩余的文本,因此第一行之后的所有内容都为空
是否有其他hadoop生态系统工具允许我在将日志加载到hive表之前格式化(或根据表字段Map日志字段)?
Hive可以工作,但你的serde需要更好的测试。如果你坚持使用regex,pig和spark会有同样的问题。
不过,您不需要regex。使用管道作为分隔符

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

不过,在使用之前,您需要清理数据,使其具有一致的分隔符。例如,你需要 || 划定空白区域。
您可以使用regex捕获缺少的字段,例如,

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

但你总是希望列的顺序很严格
就我个人而言,spark将是我的选择,至少在管道上拆分每一行,然后有条件地将每一列解析为一个class对象,从中定义一个数据集并将其写入hive

相关问题