要想很好的监控hadoop集群的状态,hadoop打印的log是很重要的。我们的思路是使用部门研发的log appender将hadoop的数据append到我们自己的central logging数据库中(其实就是存在hbase中)。
说起来简单,实际操作起来也花了一天多的时间,下面记录下整个过程。
首先要明确hadoop使用的log机制。hadoop使用了slf4j,log4j,apache的common-logging。slf4j是纯的log接口,common-logging和log4j既是接口也有实现。而common-logging在检查到classpath下有log4j存在时会默认用log4j吐出log,classpath里有slf4j-log4j12-xxx.jar时slf4j也通过log4j吐出log。这样hadoop的所有log都通过一个log4j.properties配置即可管理log的吐出。关系图如下:
但。。。我们自己的central logging系统只有logback的appender。因此需要把这些logging的家伙都转到logback里再通过logback里的logAppender存到我们自己的log系统里。
了解了原理,我们看下如何让logback一统天下,把他们全收拾了。
原理:
在classpath中加上log4j-over-slf4j jar包,这样log4j就会进入slf4j,在classpath中加入jcl-over-slf4j jar包,common-logging的log就也会进入slf4j。此时只要再加上logback的jar包,slf4j是纯接口,此时只有logback一条路可以走,这样所有的log就会乖乖的都从logback里吐出来了。下面看下实际配置的步骤:
1.创建需要lib的文件夹:
sudo mkdir /logback
2.放入我们所需的lib:
3.由于我们用的cdh系列,需要让lib目录能够让hdfs用户能访问:
sudo chmod 777 -R /logback
sudo chown -R hdfs:hdfs /logback
4.修改hadoop的启动脚本,添加我们的lib到classpath下:
sudo vim /etc/hadoop/conf/hadoop-env.sh
添加以下内容
修改classpath
LOGBACK_HOME=/logback
for i in "$LOGBACK_HOME"/*.jar; do
HADOOP_CLASSPATH="$i":"$HADOOP_CLASSPATH"
done
export HADOOP_CLASSPATH
5.添加我们的logback.xml配置文件到hadoop的配置目录下:
sudo mv ~/logback/logback.xml /etc/hadoop/conf/
配置文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_DIR" value="${hadoop.log.dir}"/>
<property name="LOG_FILE_NAME" value="${hadoop.log.file}"/>
<!-- Output to File and Rotate if it's necessary -->
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/${LOG_FILE_NAME}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${LOG_DIR}/${LOG_FILE_NAME}-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- or whenever the file size reaches 100MB -->
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%date %level [%thread] %10logger [%file:%line] %msg%n</pattern>
</encoder>
</appender>
<!--Output to central logging-->
<appender name="CentralLogging" class="com.ctrip.freeway.appender.CentralLoggingAppender">
<appId>901240</appId>
<serverIp>192.168.82.58</serverIp>
<serverPort>63100</serverPort>
</appender>
<root level="INFO">
<appender-ref ref="ROLLING"/>
<appender-ref ref="CentralLogging"/>
</root>
</configuration>
可以看到我们添加了自己的CentralLogging的Appender。
6.把slf4j-log4j12-1.6.1这个jar包注释掉!因为如果保留,log4j和logback会竞争,而不幸的是logback比log4j晚加载,所以log还会走log4j。。。此坑搞了半天
sudo mv /usr/lib/hadoop/lib/slf4j-log4j12-1.6.1.jar /usr/lib/hadoop/lib/slf4j-log4j12-1.6.1.jar.bak
ok,配置完后,重启hadoop机器,搞定。但我们还是不满足,hbase的log也搞进来多好啊。
1.添加logback配置到hbase配置目录:
类似上面步骤5
2.注释掉thrift的jar包。此步不是必须的!因为我们的central logging系统会用到thrift的jar包,而hbase也有thrift。hbase的thrift版本比较低,我们的central logging会报错。因此注释掉hbase的thrift即可。
sudo mv /usr/lib/hbase/lib/libthrift-0.7.0.jar /usr/lib/hbase/lib/libthrift-0.7.0.jar.bak
重启hbase。搞定。下面看下成果吧: