日志追查总结

今天想统计一下无线的resin日志中rtype的数量和比例,然后看一个月以来的趋势,分析resin代码是否有异常。本来只要在统计平台中写hive脚本,很快就可以跑出来,但是hive仓库中resin日志竟然没有入库,更没有进行解析。于是乎,只能手动从hdfs上拉数据然后分析。
在这个过程中,遇到一些问题,在这总结一下,也把解决方法贴出来。
从日志中总是能发现各种各样的问题,任重而道远,还需要一一进行解决。

先大体列一下用到的知识点:

  1. shell中实现trim, echo " abs ssa " | sed -e 's/\(^ *\)//' -e 's/\( *$\)//',其实就是sed的替换功能,把多个空格替换为空。
  2. nohup时,上一个命令结束后执行下一个命令,使用 &&,不能用;
  3. awk使用shell变量, "'${var}'", 双引号中加单引号,因为awk用单引号。
  4. uniq, sort
  5. hive类型转换: cast(pagesize as int)
  6. hive正则: regexp_extract(str, regexp, [idx])
  7. sql 竖表变横表,横表变竖表


开始呢,还不知道resin日志没有入库,也不知道解析,傻乎乎的写了一个hive脚本,放在统计平台中跑,字段不对,原来没有解析。没解析也没关系,反正暂时只用到一个rtype字段,用正则取到rtype的值进行统计呗。

1
2
--使用到了 regexp_extract(str, regexp, [idx]),idx是正则表达式中第几个参数,idx为0表示整个str。
select regexp_extract(line, "rtype=(\\d),", 1) as rtype from resinlog where ...

然而并没有结果。好吧,可能正则写的不太对,不用了,rtype总共就那么几种,一个一个like出来,然而还是没有结果!嗯,发现有点不对头,hql已经解析成功,就算结果不对,怎么也会有个东西出来吧。去hive仓库一看,果然,本来就没有数据,结果个毛线啊。

那就只能从hdfs拉取数据,用shell grep到这些日志,然后awk把rtype解出来,然后进行统计。幸好hdfs中是有日志的,至少不用从一台台服务器上手动拉取数据。
只是看趋势,没必要一整天数据,只取一个小时的就可以了。为了后面一个月数据的分析,把日期定义成变量了。

1
2
3
4
month=201509
date=$month"10"
time=12
nohup hadoop fs -text hftp://hdfspath/$month/$date/resinlog.$date$time* | fgrep rtype | awk '{split($0, a, "rtype="); split(a[2], b, ","); print b[1] }' > rtype.$date$time.log &

日志来了,此时rtype.time.log中,全是rtype的值,0,10,20,21,30等,先统计一下各种rtype的数量。想要用uniq,先把数据sort一下,uniq只能uniq紧挨着的相同的数据。sort和uniq很有用,可以man一下用法。

1
cat rtype.time.log | sort | uniq -c | sort -k1 -rn > rtype.time.log.sort

Ok,很好,统计出来了,前面是数量,后面是rtype的值。

1
2
3
4
5
6
5340421 0
44159 10
138 20
123 30
14 31
11 21

给一个完整版的shell脚本,对于8月份和9月份手动改一下即可。还得注意seq

1
2
3
4
5
6
month=201508
time=12
for day in $(seq 10 20); do
date=$month$day
nohup hadoop fs -text hftp://hdfspath/$month/$date/resinlog.$date$time* | fgrep rtype | awk '{split($0, a, "rtype="); split(a[2], b, ","); print b[1] }' > rtype.$date$time.log && cat rtype.$date$time.log | sort | uniq -c | sort -k1 -rn > rtype.$date$time.log.sort &
done

跑了一小会儿,咕噜咕噜生成了一堆文件。
现在各天的数据已经有了,怎么看趋势呢?我的经验是在excel中生成图表。
怎么把这么多文件的数据弄到excel中呢?这些数据还得处理一下,最好是生成一张表,这样在excel中生成的图表就更容易对比。
表结构如下:

1
2
3
4
5
date rtype0数量 rtype1数量 rtype2数量 ...
2015-08-20 10000 10000 10000
2015-08-21 10000 10000 10000
2015-08-22 10000 10000 10000
...

那怎么生成这张表呢?我比较喜欢在mysql中处理。嗯,要灵活运用各种工具。虽然shell也能做到,但太繁琐。
怎么处理这些数据呢?把各个sort文件中每一行trim一下,或者换一下格式,方便向mysql中插入数据。并且还需要在各自文件中插入自己的时间。

1
2
3
for day in $(seq 10 20); do
cat rtype.201508${day}12.log.sort | sed 's/ *$//g'|sed 's/^ *//g' | awk '{print "201508"'${day}'"\t"$2"\t"$1}' > 201509${day}.log
done

ok,现在看看处理之后的样子,看起来像一个数据库表了,这就是我们要的结果。

1
2
3
4
5
6
20150910 0 5340421
20150910 10 44159
20150910 20 138
20150910 30 123
20150910 31 14
20150910 21 11

以上数据处理都是在linxu虚机中做的,现在我要把数据拿到windows工作机上处理,主要是为了使用navicat。
把上面的所有文件合并到同一个文件中,然后sz到windows本地。在mysql中新建一个表rtype,有三列,date,rtype,count。然后把这个文件load到msyql中。

1
LOAD DATA INFILE 'rtype.log' INTO TABLE rtype FIELDS TERMINATED BY '\t';

现在看起来是一个竖表,数据比较分散,在excel中不好生成图表,所以将这个表变成上面我们定义的那样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
select date,
sum(rtype21) as rtype21,
sum(rtype30) as rtype30,
sum(rtype31) as rtype31
from
(
select date,
case when rtype=21 then count end as rtype21 ,
case when rtype=30 then count end as rtype30 ,
case when rtype=31 then count end as rtype31
from rtype
) a
group by date
;

生成的数据大约是这个样子的:
rtype数据
然后将数据从mysql中导出到excel,我是用的navicat自带功能。

excel生成图表可以上网查一下,很简单。最终的效果如下:
rtype chart

哈哈哈,大功告成,可以向老大交代了,想想还是有点小激动呢。

哭。我会说方向完全错了吗?

参考