我目前正在分析一个定制的nginx日志,并使用当前的配置单元脚本:
add jar s3://my-bucket-foo/hive-serde-0.13.1.jar;
SET hive.mapred.supports.subdirectories=true;
SET mapred.input.dir.recursive=true;
set hive.exec.compress.intermediate=true;
set mapred.compress.map.output=true;
set hive.exec.parallel=true;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.BZip2Codec;
DROP TABLE nginx_logs ;
CREATE EXTERNAL TABLE nginx_logs (
IP STRING,
`Timestamp` STRING,
Verb STRING,
URL STRING,
HTTPVersion STRING,
RequestProcessingTime STRING,
ReceivedBytes STRING,
URLReferer STRING,
UserAgent STRING,
MSISDN STRING,
XCALL STRING,
ResponseCode STRING
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
“输入.regex”=“输入.输入.REGEEX”““=“(\d{1,3}.{1,3}.{1,3}{1,3代理[\”([^\”]+)\“]\s+-\s+。\s+msisdn[([^]+)]\s+xcall[([^]+)]\s+(\d{1,})/gmi”
"input.regex" = "(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})\\s+-\\s+-\\s+\\[(\\d{2}\\/[a-z]{3}\\/\\d{4}:\\d{2}:\\d{2}:\\d{2}\\s+)-\\d{4}\\]\\s+\"(GET)(.+)(http\\/1\\.1\")\\s+(\\d{1,}\\.\\d{3})\\s+(\\d+)\\s+\"([^\"]+)\"\\s+agent\\[\"([^\"]+)\"\\]\\s+-\\s+\\.\\s+msisdn\\[([^\\]]+)\\]\\s+xcall\\[([^\\]]+)\\]\\s+(\\d{1,}).*"
)
LOCATION 's3n://my-bucket/EMRInput/';
下面是一些日志行和使用浏览器的示例:http://regex101.com/r/tw8yt5/1 采样线:
192.168.0.143 - - [25/Sep/2014:19:17:40 -0300] "GET /adserver/www/delivery/lg.php?bannerid=4512&campaignid=374&zoneid=40&loc=1&cb=2b674aefb7 HTTP/1.1" 0.000 43 "http://wap.tim.com.br/html5/" Agent["Mozilla/5.0 (Linux; U; Android 4.1.2; pt-br; LG-E467f Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30"] - . msisdn[-] xcall[552199999955] 200
根据regexp101,有12个匹配组:
但每当我执行查询时:
从nginx\u logs limit 10中选择*;
我收到一个错误,告诉我匹配组的数量与列的数量不匹配。
hive> select * from nginx_logs limit 10;
OK
Failed with exception java.io.IOException:org.apache.hadoop.hive.serde2.SerDeException: Number of matching groups doesn't match the number of columns
Time taken: 0.036 seconds
我刚刚对\(反斜杠)进行了双转义,现在得到的不是错误而是:
hive> select * from nginx_logs limit 1;
OK
NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL
Time taken: 0.037 seconds, Fetched: 1 row(s)
有什么想法吗?
1条答案
按热度按时间w41d8nur1#
在进一步了解了serde和hive如何处理regex之后,我只考虑了第一个匹配组的一个ip:
这将适用于大多数情况,除了那些有两个或多个ip(代理等),所以
不管用而且让我们头痛。解决方案来得很快,从一开始到破折号(-)都要用一组人来匹配:
在java主程序中进行测试,它的工作方式很有魅力:
匹配?是的
瞧á, 我现在可以查询了。