首先说明,“抄”是一把双刃剑,日常工作中“抄”得好会极大的提升工作效率,但如果只是一味的享受随之带来的快餐文化,会让我们变得非常混沌,从而在追求进步的路上原地打转。
此次搭建的项目是使用Hive作为执行引擎去接收并执行hql任务,依赖如下:
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-yarn-api</artifactId>
<version>${hadoop.version}</version>
</dependency>
<!--hive-jdbc-->
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-jdbc</artifactId>
<version>${hive.version}</version>
</dependency>
<dependecy>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependecy>
也就是说,我的log4j显式指定了为1.2.17版本,然后我在需要打印日志的类里,抄过来这么一句:
Log log = LogFactory.getLog(this.getClass());
再然后,我在resources贴了一个别人写好的xml文件,名字叫做,log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="WARN">
<Properties>
<Property name="basePath">D:/log</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<pattern>%d{yyyy-MM-dd HH:mm:ss,SSS}%trace %level %F [%l] %message%n</pattern>
</PatternLayout>
</Console>
<RollingFile name="bigData" fileName="${basePath}/Running.log" filePattern="%d{yyyy-MM-dd}.%i.log">
<PatternLayout>
<pattern>%d{yyyy-MM-dd HH:mm:ss,SSS}%trace %level %F [%l] %message%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<root level="all">
<AppenderRef ref="bigData"/>
<AppenderRef ref="Console"/>
</root>
</Loggers>
</configuration>
因为我对log4j完全不懂,这里出现了一些状况,但左抄右抄,都成功规避了,至此,算是比较顺利,程序中埋的log也全都打印出来并生成都对应日志文件了。
但我在抄作业的时候觉得不太对劲儿,具体来说就是各位大神都说了,log4j 版本1默认去读的是log4j.properties这个配置文件,版本2去读的,才是log4j2.xml。我觉得很奇怪,开始了各种尝试:改配置文件名,改log4j版本。结果陷入了持久的迷惑状态中:一会儿报找不到配置文件,一会儿报属性项未知。于是,我干脆注释掉pom中log4j的依赖。返回我的类,发现LogFactory面不改色,并没有报红。我睁大了眼睛,表示maven可能又在戏弄我了。于是我又reimport了一下(可以看出我是多么的菜到抠脚了。),然后我当然就醒悟过来,LogFactory并不是log4j里面的了。我忙活了一个小时,原来是这个家伙来历不对,ctrl+鼠标左键,看出它来自于org.apache.commons.logging
原来是这样。。
这里使用的是apache commons里面的log工具,它并没有被显式的列在pom文件中,而是作为hadoop或者hive之下依赖的日志包而存在。我在hive-jdbc下找到了它:
没错,正是log4j2的两个包,显式的在pom中出现时,它们是这样的:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.6.2</version>
</dependency>
所以,通过这样的方式获取的句柄,根本就没有调用log4j自身的类。
Log log = LogFactory.getLog(this.getClass());
在log4j 1.x中,需要这样:
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
class MyLogger{
private Logger logger1 = Logger.getLogger(this.getClass());
// 或者
private Logger logger2 = LogManager.getLogger(this.getClass());
}
在log4j 2.x中,需要这样:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
class MyLogger{
private Logger logger = LogManager.getLogger(this.getClass());
}
配置文件方面:
log4j2.properties优先级高于log4j2.xml,用于log4j 2.x;
log4j.properties优先级高于log4j.xml,用于log4j 1.x。
maven项目中,这些文件都是放在resources中。