前言
在YARN術語中,執行者和應用程序masters在“容器”內部運行。在應用程序完成后,YARN有兩種處理容器日志的模式。
yarn.log-aggregation-enable
配置),容器日志將復制到HDFS中,而本地計算機上的日志將被刪除。查看日志可以通過
yarn logs
命令從群集中的任何位置查看。
yarn logs -applicationId <app ID>
該命令會將指定的應用程序日志從所有的容器中打印所有的日志內容。您也可以使用HDFS shell 或API直接在HDFS中查看容器日志文件。
他們所在的目錄參考YARN配置(yarn.nodemanager.remote-app-log-dir
和 yarn.nodemanager.remote-app-log-dir-suffix
)。
日志也可以通過Spark Web UI中的Executors 標簽頁查看。你需要運行spark 歷史服務器和MapReduce歷史服務器,並在yarn-site.xml
正確配置yarn.log.server.url
。
Spark歷史記錄服務器UI上的日志URL會將您重定向到MapReduce歷史記錄服務器以顯示聚合日志。
如果日志聚合未打開時,日志將保存在每台計算機上的本地 YARN_APP_LOGS_DIR
,通常配置為 /tmp/logs
或 $HADOOP_HOME/logs/userlogs
,取決於Hadoop版本和安裝配置。
查看容器的日志需要轉到包含它們的主機並查看此目錄。子目錄按應用程序ID和容器ID組織日志文件。日志也可以在執行程序選項卡下的Spark Web UI上使用,並且不需要運行MapReduce歷史記錄服務器。
要查看每個容器的啟動環境,請增加 yarn.nodemanager.delete.debug-delay-sec
一個較大的值(例如36000
),然后通過 yarn.nodemanager.local-dirs
在啟動容器的節點上訪問應用程序緩存。
該目錄包含啟動腳本,JAR以及用於啟動每個容器的所有環境變量。這個過程特別適用於調試類路徑問題。
(請注意,啟用此功能需要具有群集設置的管理權限並重新啟動所有節點管理器。因此,這不適用於托管群集)。
日志參數
yarn-site.xml中有幾個配置項與日志的保存與刪除,本地job執行文件的保留與刪除有關。若不做配置,日志和job.jar會在application執行結束后被直接刪除掉。
yarn.log-aggregation-enable true 執行結束后收集(聚合)各個container本地的日志
yarn.nodemanager.remote-app-log-dir /app-logs 聚合日志后在hdfs的存放地址 yarn.nodemanager.remote-app-log-dir-suffix logs 聚合日志存放的后綴,存放地址由 ${remote-app-log-dir}/${user}/{thisParam}構成
yarn.log-aggregation.retain-seconds 2592000 聚合日志在hdfs上的保留時間,以秒為單位,到時后被刪除,保留30天后刪除
yarn.log.server.url http://hostname:19888/jobhistory/logs log server的地址
yarn.nodemanager.local-dirs /hadoop/yarn/local 存放 application 運行的本地文件(計算過程中的中間數據存儲)的根目錄,執行完畢后刪除,按用戶名存儲
yarn.nodemanager.log-dirs /hadoop/yarn/log 存放 container 運行的本地日志的根目錄,執行完畢后刪除,按用戶名存儲
yarn.nodemanager.log.retain-seconds 604800 本地日志的保留時間,只有aggregation沒有enable時才生效
yarn.nodemanager.delete.debug-delay-sec 600 yarn 的 DeletionService 在任務結束多長時間后,刪除本地化的日志(yarn.nodemanager.local-dirs)
和container的運行日志(yarn.nodemanager.log-dirs)。 這個時間最好設置的大一點。
日志聚合
其中executor日志分為運行時日志以及結束日志,兩種日志分別存放於不同的位置,運行時候的日志文件存放於yarn.nodemanager.log−dirs/{ApplicationID}。
1、比如配置如下:
<property> <!--開啟日志聚合--> <name>yarn.log-aggregation-enable</name> <value>true</value> </property> <property> <!--日志聚合hdfs存儲路徑--> <name>yarn.nodemanager.remote-app-log-dir</name> <value>/tmp/logs</value> </property> <property> <!--hdfs上的日志保留時間--> <name>yarn.log-aggregation.retain-seconds</name> <value>604800</value> </property> <property> <!--應用執行時存儲路徑--> <name>yarn.nodemanager.log-dirs</name> <value>file:/mnt/ddb/2/hadoop/nm</value> </property> <property> <!--應用執行完日志保留的時間,默認0,即執行完立刻刪除--> <name>yarn.nodemanager.delete.debug-delay-sec</name> <value>0</value> </property>
2、運行時候的executor日志存放於:
root@xxx:/mnt/ddb/2/hadoop/nm/application_1471515078641_0007# ls container_1471515078641_0007_01_000001 container_1471515078641_0007_01_000002 container_1471515078641_0007_01_000003
注:其中container_1471515078641_0007_01_000001為RM為application_1471515078641_0007分配的第一個container,即AM所在的container,
第一個container都是運來啟動AM的,containerID形式為,container_APPID_01_000001,你在RM日志文件里面根據container_APPID搜索即可看到為該APPID分配的container的分布情況及生命周期。
3、運行結束以后日志會聚合到HDFS上面去,運行結束的日志文件存入於/tmp/logs/${user}/logs。
drwxrwx--- - root supergroup 0 2016-08-18 18:29 /tmp/logs/root/logs/application_1471515078641_0002 drwxrwx--- - root supergroup 0 2016-08-18 19:10 /tmp/logs/root/logs/application_1471515078641_0003 drwxrwx--- - root supergroup 0 2016-08-18 19:17 /tmp/logs/root/logs/application_1471515078641_0004
4、運行結束后,可以通過以下命令查看日志:
yarn logs --applicationId <id>
統一配置log4j
spark中提供了log4j的方式記錄日志。可以在$SPARK_HOME/conf/下,將 log4j.properties.template 文件copy為 log4j.properties 來啟用log4j配置。但這個配置為全局配置,不能單獨配置某個job的運行日志。
在Spark的conf目錄下,把log4j.properties.template修改為log4j.properties,原來的內容如下:
# Set everything to be logged to the console log4j.rootCategory=INFO, console log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.target=System.err log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{1}: %m%n # Set the default spark-shell log level to WARN. When running the spark-shell, the # log level for this class is used to overwrite the root logger's log level, so that # the user can have different defaults for the shell and regular Spark apps. log4j.logger.org.apache.spark.repl.Main=WARN # Settings to quiet third party logs that are too verbose log4j.logger.org.spark_project.jetty=WARN log4j.logger.org.spark_project.jetty.util.component.AbstractLifeCycle=ERROR log4j.logger.org.apache.spark.repl.SparkIMain$exprTyper=INFO log4j.logger.org.apache.spark.repl.SparkILoop$SparkILoopInterpreter=INFO log4j.logger.org.apache.parquet=ERROR log4j.logger.parquet=ERROR # SPARK-9183: Settings to avoid annoying messages when looking up nonexistent UDFs in SparkSQL with Hive support log4j.logger.org.apache.hadoop.hive.metastore.RetryingHMSHandler=FATAL log4j.logger.org.apache.hadoop.hive.ql.exec.FunctionRegistry=ERROR
比如:可以把log4j.rootCategory=INFO, console,改為log4j.rootCategory=WARN, console,即可抑制Spark把INFO級別的日志打到控制台上。如果要顯示全面的信息,則把INFO改為DEBUG。
獨立配置log4j
如果想要使用自定義的log4j日志配置,需要下面幾個步驟:
1、使用spark-submit的--files參數,上傳自定義 log4j-driver.properties和log4j-executor.properties;
2、使用 --conf參數,增加 -Dlog4j.configuration配置:
-
- 用於驅動程序:spark.driver.extraJavaOptions = -Dlog4j.configuration = <配置文件的位置>
- 用於執行者:spark.executor.extraJavaOptions= -Dlog4j.configuration = <配置文件的位置>
方案一:使用 spark-submit的 --files 參數將自定義的配置文件上傳到應用程序的文件列表中。
spark-submit --class com.hm.spark.Application --master yarn --deploy-mode cluster --driver-cores 1 --driver-memory 1G --num-executors 2 --executor-cores 1 --executor-memory 1G --driver-java-options "-Dlog4j.configuration=log4j-driver.properties" --conf spark.executor.extraJavaOptions="-Dlog4j.configuration=log4j-executor.properties" --files /home/hadoop/spark-workspace/log4j-driver.properties,/home/hadoop/spark-workspace/log4j-executor.properties /home/hadoop/spark-workspace/my-spark-etl-assembly-1.0-SNAPSHOT.jar
注:這里沒有使用spark.driver.extraJavaOptions參數去配置,而是使用spark-submit的--driver-java-options參數進行設置的。
方案二:不使用 spark-submit的 --files 參數上傳文件,直接使用文件。
spark-submit --class com.hm.spark.Application --master yarn --deploy-mode cluster --driver-cores 1 --driver-memory 1G --num-executors 2 --executor-cores 1 --executor-memory 1G --driver-java-options "-Dlog4j.configuration=file:/home/hadoop/spark-workspace/log4j-driver.properties " --conf spark.executor.extraJavaOptions="-Dlog4j.configuration=file:/home/hadoop/spark-workspace/log4j-executor.properties" /home/hadoop/spark-workspace/my-spark-etl-assembly-1.0-SNAPSHOT.jar
注:如果使用文件,file: 則應明確提供配置文件的,並且文件需要在所有節點上本地存在。
Log4j配置示例
- driver日志配置
控制台不打印日志,采用Rolling模式按天切割日志和滾動刪除,保留最新7天日志數據,輸出到指定文件(spark-driver.log),
日志存放目錄和yarn日志一樣,以便YARN可以正確顯示並聚合它們(在開始日志聚合的前提下).
# Set everything to be logged to the console log4j.rootCategory=INFO, rolling log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.target=System.out log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{1}: %m%n # Set the default spark-shell log level to WARN. When running the spark-shell, the # log level for this class is used to overwrite the root logger's log level, so that # the user can have different defaults for the shell and regular Spark apps. log4j.logger.org.apache.spark.repl.Main=WARN # Settings to quiet third party logs that are too verbose log4j.logger.org.spark_project.jetty=WARN log4j.logger.org.spark_project.jetty.util.component.AbstractLifeCycle=ERROR log4j.logger.org.apache.spark.repl.SparkIMain$exprTyper=INFO log4j.logger.org.apache.spark.repl.SparkILoop$SparkILoopInterpreter=INFO log4j.logger.org.apache.parquet=ERROR log4j.logger.parquet=ERROR # SPARK-9183: Settings to avoid annoying messages when looking up nonexistent UDFs in SparkSQL with Hive support log4j.logger.org.apache.hadoop.hive.metastore.RetryingHMSHandler=FATAL log4j.logger.org.apache.hadoop.hive.ql.exec.FunctionRegistry=ERROR # rolling log4j.appender.rolling=org.apache.log4j.DailyRollingFileAppender log4j.appender.rolling.file=${spark.yarn.app.container.log.dir}/spark-driver.log log4j.appender.rolling.DatePattern='.'yyyy-MM-dd log4j.appender.rolling.layout=org.apache.log4j.PatternLayout log4j.appender.rolling.layout.ConversionPattern=%d{ISO8601} [%20.20t] [%-5p] [%50.50l] %-40m %n log4j.appender.rolling.Append=true log4j.appender.rolling.Encoding=UTF-8 log4j.appender.rolling.MaxBackupIndex=7 log4j.logger.org.apache.spark=INFO log4j.logger.org.eclipse.jetty=WARN
如果希望一方面打印到控制台,另一方面又保留spark本身輸出的日志到日志文件中,配置內容如下:
log4j.rootCategory=INFO, console, rolling
............
- executor日志配置
控制台不打印日志,采用Rolling模式按天切割日志和滾動刪除,保留最新7天日志數據,輸出到指定文件(spark-executor.log),
日志存放目錄和yarn日志一樣,以便YARN可以正確顯示並聚合它們(在開始日志聚合的前提下).
# Set everything to be logged to the console log4j.rootCategory=INFO, rolling log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.target=System.out log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{1}: %m%n # Set the default spark-shell log level to WARN. When running the spark-shell, the # log level for this class is used to overwrite the root logger's log level, so that # the user can have different defaults for the shell and regular Spark apps. log4j.logger.org.apache.spark.repl.Main=WARN # Settings to quiet third party logs that are too verbose log4j.logger.org.spark_project.jetty=WARN log4j.logger.org.spark_project.jetty.util.component.AbstractLifeCycle=ERROR log4j.logger.org.apache.spark.repl.SparkIMain$exprTyper=INFO log4j.logger.org.apache.spark.repl.SparkILoop$SparkILoopInterpreter=INFO log4j.logger.org.apache.parquet=ERROR log4j.logger.parquet=ERROR # SPARK-9183: Settings to avoid annoying messages when looking up nonexistent UDFs in SparkSQL with Hive support log4j.logger.org.apache.hadoop.hive.metastore.RetryingHMSHandler=FATAL log4j.logger.org.apache.hadoop.hive.ql.exec.FunctionRegistry=ERROR # rolling log4j.appender.rolling=org.apache.log4j.DailyRollingFileAppender log4j.appender.rolling.file=${spark.yarn.app.container.log.dir}/spark-executor.log log4j.appender.rolling.DatePattern='.'yyyy-MM-dd log4j.appender.rolling.layout=org.apache.log4j.PatternLayout log4j.appender.rolling.layout.ConversionPattern=%d{ISO8601} [%20.20t] [%-5p] [%50.50l] %-40m %n log4j.appender.rolling.Append=true log4j.appender.rolling.Encoding=UTF-8 log4j.appender.rolling.MaxBackupIndex=7 log4j.logger.org.apache.spark=INFO log4j.logger.org.eclipse.jetty=WARN
如果希望輸出的日志文件跟默認的(stdout)一樣,配置內容如下:
.....................
# rolling log4j.appender.rolling=org.apache.log4j.DailyRollingFileAppender log4j.appender.rolling.file=${spark.yarn.app.container.log.dir}/stdout.log log4j.appender.rolling.DatePattern='.'yyyy-MM-dd log4j.appender.rolling.layout=org.apache.log4j.PatternLayout log4j.appender.rolling.layout.ConversionPattern=%d{ISO8601} [%20.20t] [%-5p] [%50.50l] %-40m %n log4j.appender.rolling.Append=true log4j.appender.rolling.Encoding=UTF-8 log4j.appender.rolling.MaxBackupIndex=7
......................
引用:
- https://www.jianshu.com/p/e7838e9e5c44
- https://blog.csdn.net/ZMC921/article/details/80238392
- https://www.cnblogs.com/163yun/p/9882530.html
- https://zhuanlan.zhihu.com/p/150078020
- https://www.jianshu.com/p/0fe51185eeba
- http://bcxw.net/article/118.html
- https://hadoop.apache.org/docs/r2.4.1/hadoop-yarn/hadoop-yarn-common/yarn-default.xml