一、Hive日志介紹
Hive日志記錄了程序運行的過程,在Hive中,日志分為兩種:
- 系統日志。記錄了Hive的運行情況,錯誤狀況。
- Job日志。記錄了Hive中Job的執行過程。
1、系統日志存儲在什么地方呢?
在 ${HIVE_HOME}/conf/hive-log4j.properties 文件中記錄了Hive日志的存儲情況,
默認的存儲情況:
hive.root.logger=WARN,DRFA hive.log.dir=/tmp/${user.name}/ # 默認的存儲位置 hive.log.file=hive.log # 默認的文件名
Hive日志默認存儲在以下目錄中: /tmp/${user.name}/hive.log。當然,也可以設置一個不同的hive日志位置,有兩種方式:
(1)Hive啟動時指定日志目錄。
hive --hiveconf hive.log.dir=/tmp/ --hiveconf hive.log.file=tmp.log
(2)通過在 $HIVE_HOME/conf/hive-log4j.properties文件中設置hive.log.dir參數。
hive.log.dir=/tmp/
2、Job日志又存儲在什么地方呢 ?
# 源碼加載方式 HIVEHISTORYFILELOC("hive.querylog.location", "/tmp/" + System.getProperty("user.name"))
默認存儲在 /tmp/${user.name} 目錄下,和系統日志默認存儲路徑相同。
二、Hive日志調試
Hive默認的日志級別是WARN,不能將DEBUG信息輸出,但在進行進行問題定位時,可以修改日志級別,利用調試日志進行錯誤定位。具體設置方法有兩種:
1、啟動Hive客戶端時添加參數進入DEBUG模式(定位問題的常用方式)
hive --hiveconf hive.root.logger=DEBUG,console
2、在${HIVE_HOME}/conf/hive-log4j.properties文件中找到 hive.root.logger 屬性,並將其修改為下面的設置
hive.root.logger=DEBUG,console
方法一的設定只對本次會話有效,下次如果還想繼續修改日志輸出級別需要重新設定,這種設定適合臨時需要查看更多日志的用戶。方法二將日志輸出級別設定到文件里,這個設定對所有用戶都生效,而且每次執行HQL都會輸出一大堆日志,這種情況適合那些無時無刻都需要HQL運行日志的用戶。
注:針對兩個方法的綜合,還有一種實現方式,既可以不用每次設定日志級別,也能長期生效,就是設定自己的log4j配置文件,在啟動Hive的時候指定自己的配置文件,如下:
hive --hiveconf hive.log4j.file=/home/kwang/hive-log4j.properties
三、如何查看實際環境中Hive的日志級別?
最直接的方式是啟動hive cli客戶端,可以看到日志文件加載的具體配置文件:
可以看到,hive cli加載的配置文件是 /opt/cloudera/parcels/CDH-5.14.4-1.cdh5.14.4.p0.3/jars/hive-common-1.1.0-cdh5.14.4.jar!/hive-log4j.properties,日志級別默認是 WARN 級別,這個配置的文件的日志級別可以在 hive-common 源碼模塊的資源文件 hive-log4j.properties 中看到:
# Define some default values that can be overridden by system properties hive.log.threshold=ALL hive.root.logger=WARN,DRFA hive.log.dir=${java.io.tmpdir}/${user.name} hive.log.file=hive.log
在這里我們就能看到Hive任務執行時的日志級別。
接下來我們看看Hive是如何加載日志配置文件的。我們知道hive cli啟動時主要依賴 hive-common 模塊和 hive-exec 模塊,在上面介紹的 hive-common 源碼模塊的資源文件是日志級別是WARN級別的,而在 hive-exec 源碼模塊的資源文件 hive-exec-log4j.properties 中日志級別是 INFO級別:
hive.log.threshold=ALL hive.root.logger=INFO,FA hive.log.dir=${java.io.tmpdir}/${user.name} hive.query.id=hadoop hive.log.file=${hive.query.id}.log
這里提到的兩個日志文件也就對應前面介紹的系統級別日志與任務級別日志。清楚了這兩個日志配置文件,我們再來看看Hive在啟動客戶端時是如何加載日志的。
首先,Hive客戶端啟動的入庫類是 CliDriver.java,啟動時會去加載日志配置。
public int run(String[] args) throws Exception { OptionsProcessor oproc = new OptionsProcessor(); if (!oproc.process_stage1(args)) { return 1; } // NOTE: It is critical to do this here so that log4j is reinitialized // before any of the other core hive classes are loaded boolean logInitFailed = false; String logInitDetailMessage; try { // 加載日志配置 logInitDetailMessage = LogUtils.initHiveLog4j(); } catch (LogInitializationException e) { logInitFailed = true; logInitDetailMessage = e.getMessage(); } ... }
而真正加載日志的邏輯在 LogUtils.initHiveLog4j( ) 方法里:
/** * Initialize log4j. * * @return an message suitable for display to the user * @throws LogInitializationException if log4j fails to initialize correctly */ public static String initHiveLog4j() throws LogInitializationException { return initHiveLog4jCommon(HiveConf.ConfVars.HIVE_LOG4J_FILE); } private static String initHiveLog4jCommon(ConfVars confVarName) throws LogInitializationException { HiveConf conf = new HiveConf(); // HiveConf初始化時會初始化配置參數(具體加載哪些參數還有待研究) if (HiveConf.getVar(conf, confVarName).equals("")) { // if log4j configuration file not set, or could not found, use default setting return initHiveLog4jDefault(conf, "", confVarName); } else { //真正邏輯是進入到這里 // if log4j configuration file found successfully, use HiveConf property value String log4jFileName = HiveConf.getVar(conf, confVarName); File log4jConfigFile = new File(log4jFileName); boolean fileExists = log4jConfigFile.exists(); // 判斷 /etc/hive/con/ 目錄下是否存在 hive-log4j.properties 日志文件(線上環境默認是沒有的) if (!fileExists) { // if property specified file not found in local file system // use default setting // 線上環境 /etc/hive/conf/ 目錄下加載不到文件,此時初始化默認參數,即hive-exec和hive-common模塊的日志參數 return initHiveLog4jDefault( conf, "Not able to find conf file: " + log4jConfigFile, confVarName); } else { // property speficied file found in local file system // use the specified file // 從指定文件加載,也就是加載jar包對應文件 // 線上啟動Hive加載的日志文件 (Logging initialized using configuration in jar:file:/opt/cloudera/parcels/CDH-5.14.4-1.cdh5.14.4.p0.3/jars/hive-common-1.1.0-cdh5.14.4.jar!/hive-log4j.properties) if (confVarName == HiveConf.ConfVars.HIVE_EXEC_LOG4J_FILE) { String queryId = HiveConf.getVar(conf, HiveConf.ConfVars.HIVEQUERYID); if(queryId == null || (queryId = queryId.trim()).isEmpty()) { queryId = "unknown-" + System.currentTimeMillis(); } System.setProperty(HiveConf.ConfVars.HIVEQUERYID.toString(), queryId); } LogManager.resetConfiguration(); PropertyConfigurator.configure(log4jFileName); logConfigLocation(conf); return ("Logging initialized using configuration in " + log4jConfigFile); } } }
至此,也就是Hive客戶端啟動時會去加載 hive-log4j.properties 日志文件,先從 /etc/hive/conf/ 目錄中加載,然后再從jar中去加載。
【參考資料】