Spark Application日志输出的问题 2015-01-17 12:49:40 在本机开发的Spark Application,如果用到了log4j作为日志记录组件,本机调试时,日志输出都是正常的,如果部署到Spark集群上,你会发现日志不输出了,即便是应用log4j.properties文件。 原因是Spark本身就是用的log4j来记录日志的,他的配置位于`{SPARK_HOME}/conf/log4j.properties`下,默认的配置如下: ``` log4j.rootCategory=WARN, 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 # Settings to quiet third party logs that are too verbose log4j.logger.org.eclipse.jetty=WARN log4j.logger.org.apache.spark.repl.SparkIMain$exprTyper=INFO log4j.logger.org.apache.spark.repl.SparkILoop$SparkILoopInterpreter=INFO ``` 使用spark-submit提交应用时,spark使用的就是此配置,可以看到只有WARN以上级别的日志才会输出。 所以如果你的应用中记录的是INFO日志,是看不到任何输出的。 ## 使用自己的log4j配置并隔离Spark日志 一个系统如果没有日志记录,是不完整的。 我们开发的Spark Application依赖spark-core,日志记录方面,需要跟spark的隔离开,又不能影响spark默认记录的日志的行为。 为了达到以上目的,可以单独创建一个log4j的配置文件,假设为`log4j.properties`,添加以下配置内容: ``` # Set everything to be logged to the console log4j.rootCategory=WARN,console log4j.logger.stan=INFO,file,console,e # don't log to rootCategory log4j.additivity.stan=false 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=%p %d{yy/MM/dd HH:mm:ss} %c{1}: %m%n # info log file log4j.appender.file=org.apache.log4j.DailyRollingFileAppender log4j.appender.file.Encoding=UTF8 log4j.appender.file.Threshold=INFO log4j.appender.file.File=logs/stan.log log4j.appender.file.DatePattern='_'yyyyMMdd'.log' log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=[%p] [%d{yy/MM/dd HH:mm:ss}] [%c{1}]: %m%n # error log file log4j.appender.e=org.apache.log4j.DailyRollingFileAppender log4j.appender.e.Encoding=UTF8 log4j.appender.e.Threshold=ERROR log4j.appender.e.File=logs/stan_error.log log4j.appender.e.DatePattern='_'yyyyMMdd'.log' log4j.appender.e.layout=org.apache.log4j.PatternLayout log4j.appender.e.layout.ConversionPattern=[%p] [%d{yy/MM/dd HH:mm:ss}] [%c{1}]: %m%n # Settings to quiet third party logs that are too verbose log4j.logger.org.eclipse.jetty=WARN log4j.logger.org.apache.spark.repl.SparkIMain$exprTyper=INFO log4j.logger.org.apache.spark.repl.SparkILoop$SparkILoopInterpreter=INFO ``` 假设stan是我们专用的日志记录器,通过`log4j.logger.stan=INFO,file,console,e`指定专用的appender,使用过程中还会发现,记录到console中的日志会出现两次,原因是rootCategory也是会输出console日志的。 可以通过`log4j.additivity.stan=false`,设定stan的日志不会输出到rootCategory中。 为了使用我们自定义的篇日志,需要在应用入口添加以下代码: ``` PropertyConfigurator.configure("log4j.properties") ``` 通过以下代码构建日志记录器: ``` // Scala代码 val logger: Logger = LoggerFactory.getLogger("stan") ``` 这样我们的日志系统就算完备了,记录关键日志到我们指定的文件中,同时还能隔离Spark的日志,互不影响。 参考: <http://lvqionghua.blog.163.com/blog/static/1852774201193161946939/> 非特殊说明,均为原创,原创文章,未经允许谢绝转载。 原始链接:Spark Application日志输出的问题 赏 Prev Spark中使用UDF遇到的一个奇怪的问题 Next Python Pickup