You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Databricks Python notebook无需挂载将日志写入ADLS Gen2的实现方法

问题根因

原生Python的FileHandler仅支持本地文件系统路径,无法识别ADLS Gen2的abfss://协议路径,因此运行时会将abfss路径误识别为本地相对路径,拼接在Driver节点默认工作目录/databricks/driver/后,触发路径不存在报错。

无挂载点解决方案

不需要挂载ADLS到Databricks文件系统,可通过自定义Logging Handler适配ADLS写入逻辑实现需求,对原有代码侵入极小。

前置配置

首先确保你已配置好ADLS Gen2的访问权限,示例使用存储账户密钥认证(也可替换为SAS、服务主体等认证方式):

spark.conf.set(
    f"fs.azure.account.key.{storageAccount}.dfs.core.windows.net",
    "<你的存储账户访问密钥>"
)

代码实现

1. 自定义ADLS Gen2日志Handler

import logging

class ADLSGen2Handler(logging.Handler):
    def __init__(self, adls_log_path):
        super().__init__()
        self.adls_path = adls_log_path
        # 自动创建日志父目录,避免路径不存在报错
        parent_dir = "/".join(adls_log_path.split("/")[:-1])
        dbutils.fs.mkdirs(parent_dir)
        
    def emit(self, record):
        # 格式化日志内容
        log_msg = self.format(record) + "\n"
        # 追加写入ADLS路径
        dbutils.fs.put(self.adls_path, log_msg, append=True)

2. 改造原有日志创建函数

def create_logger(name, log_path=None):
    logger = logging.getLogger(name)
    # 避免重复运行cell时重复添加Handler导致日志重复
    if logger.handlers:
        return logger
    logger.setLevel(logging.DEBUG)
    formatter = logging.Formatter("%(asctime)s - %(levelname)-8s - %(message)s")
    
    # 保留控制台流输出
    stream_handler = logging.StreamHandler()
    stream_handler.setFormatter(formatter)
    logger.addHandler(stream_handler)
    
    if log_path is not None:
        # 替换原生FileHandler为自定义ADLS Handler
        adls_handler = ADLSGen2Handler(log_path)
        adls_handler.setFormatter(formatter)
        logger.addHandler(adls_handler)
    return logger

3. 调用方式和原有逻辑完全一致

from datetime import date, datetime
current_date = date.today()
current_timestamp = datetime.strftime(datetime.now(),"%Y%m%d%H%M%S")

name = "temp_logs"
log_path = f"abfss://{storageContainer}@{storageAccount}.dfs.core.windows.net/{target_dir}/logs/{current_date}/{name}_{current_timestamp}.txt"

logger = create_logger(name = name,log_path = log_path)
# 测试写入
logger.info("测试日志写入成功")
可选优化方案

如果日志写入量很大,单条追加写入ADLS会产生额外开销,可使用更轻量的本地暂存后批量上传方案:

  • 先将日志写入Driver本地临时路径/tmp/,使用原生FileHandler即可
  • 任务运行完成后调用dbutils.fs.cp("file:/tmp/本地日志文件名.txt", adls_log_path)一次性上传到ADLS,适合不需要实时同步日志的场景。

内容的提问来源于stack exchange,提问作者user16714516

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 16:12:00