问题现象
hive cli 执行,会首先打印一大段 debug 日志如下:


之前遇到过一次类似的问题,最终发现原因是 HBase 的 log4j 配置文件里配置了一个 DEBUG 级别;这次有点不一样,经检查 hive hbase hadoop 等组件的 log4j 配置,日志级别都不是 debug
解决
从截图日志里的 classpath 入手,检查 classpath 下所有的目录下的配置文件 是否包含 log4j 配置,这个 classpath 实在太长了,肉眼看不过来,借助一个叫脚本,扫描,搜索;代码如下:
#/bin/bash
# 根据日志输出的 classpath 递归搜索 classpath 中的关键字 例如 log4j
findlog4j(){
file=$1
if [ -f $file ];then
# jar 解压 匹配文件名是否有log4j相关的文件
if [[ $file == *.jar ]]; then
jar -tvf $file | grep -i "log4j"
else
# 非jar类的文件 直接 grep
grep -i "log4j" $file
fi
else
for dirfile in $(ls $file)
do
findlog4j $file/$dirfile
done
fi
}
# split classpath to array
arr=($(echo $hadoop_classpath | tr ':' ' '))
for cp in ${arr[@]}
do
echo $cp
# 递归搜
findlog4j $cp
done
原理
hive cli 启动脚本,先拼接 hadoop_classpath,拼接 hbase hadoop hive 等相关的 classpath,再实际启动脚本;
经测试定位在拼接 hive aux
hive 外部引用的 jar ,例如 hive udf 等都放在这个目录 $HIVE_HOME/auxlib
目录下

里面有一个自己开发 hive udf jar 里面包含了 log4j.xml , 说明hive启动前首先加载了这个 log4j,把这个文件加上日志级别就解决此问题;
小技巧
如何在不通过重新编译的情况下更新 jar 包:
-
方法1:
jar zvf xx.jar 解压文件
编辑 log4j.xml
jar cvf xx.jar * 重新压缩 -
方法2:
直接 vim xx.jar 修改里面的文本文件,改完后保存即可
网友评论