我正在使用
Azure Databricks
来构建和运行 ETL 管道。对于开发,请使用 Databricks notebooks (Python)
。我的目标是通过 Spark UI 查看驱动程序和执行程序上运行的代码的应用程序日志。
最初,我在查看执行程序日志时遇到问题,但如此处所述https://kb.databricks.com/clusters/set-executor-log-level.html,我可以查看放入其中的应用程序日志在
worker nodes
(executors
) 上运行的代码,例如 forEach
/forEachPartitions
。
正如上面链接中所写,我们需要在所有执行器上设置日志级别。这是否意味着我们需要在每个要在工作节点上运行的代码/方法中设置日志级别,如下所示。那么我是否必须在每个方法中设置日志记录级别,我认为这是多余的,应该避免。
def doSomething():
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
## some operation
df.forEach(lambda x: doSomething())
要设置所有执行器上的日志级别,必须在 JVM 内部设置 每个工人。
有没有更好的方法可以避免每次都设置日志级别?
正如您提到的,您想要在 Spark UI 中查看驱动程序和执行程序的应用程序日志。
捕获驱动程序日志:
import logging
sc = SparkContext.getOrCreate()
log = logging.getLogger('py4j')
log.setLevel(logging.INFO)
def log_executor_operations(iterator):
for x in iterator:
yield x
rdd = sc.parallelize(range(5))
rdd.foreachPartition(log_executor_operations)
在上面使用
logging.getLogger('py4j')
设置驱动程序进程的日志级别。
这将捕获驱动程序代码中生成的日志并将其显示在 Spark UI 中。
定义在 RDD分区上迭代的
log_executor_operations
。
捕获执行器日志:
from pyspark import SparkContext
sc = SparkContext.getOrCreate()
sc.setLogLevel("DEBUG")
def log_executor_operations(iterator):
import logging
executor_log = logging.getLogger("ExecutorLog")
executor_log.setLevel(logging.DEBUG)
executor_log.info("Executor has started processing.")
for x in iterator:
executor_log.debug(f"Processing value: {x}")
rdd = sc.parallelize(range(5))
rdd.foreachPartition(log_executor_operations)
使用 sc.setLogLevel("DEBUG")
将日志级别设置为“
DEBUG”将专门捕获执行程序日志。
结果: