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

如何在Azure的Python Azure Function中正常输出paramiko日志

Azure Function 部署后无法输出paramiko日志的解决方法

问题现象

  • 本地运行包含paramiko SFTP操作的Python Azure Function时,可正常获取paramiko库的全量日志
  • 部署到Azure平台后,paramiko相关日志完全不输出
  • 已尝试的配置未生效:
    • 代码中手动设置根日志级别为DEBUG、调用logging.basicConfig()初始化日志
    • host.json中开启全量文件日志,默认日志级别设为Debug
    • 应用配置中添加PYTHON_ENABLE_DEBUG_LOGGING = 1参数

现有实现

函数代码

import datetime
import logging
import azure.functions as func
from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient
import paramiko


def main(mytimer: func.TimerRequest) -> None:
    utc_timestamp = datetime.datetime.utcnow().replace(
        tzinfo=datetime.timezone.utc).isoformat()

    if mytimer.past_due:
        logging.info('The timer is past due!')

    logging.Logger.root.level = 10
    logging.basicConfig()
    logging.getLogger("paramiko").setLevel(logging.DEBUG)
          
    # 从Key Vault获取SFTP认证所需密钥
    credential = DefaultAzureCredential()

    secret_client = SecretClient(vault_url="InsertVaultURL", credential=credential)
    secret_name = secret_client.get_secret("InsertSecretUsernameName")
    secret_pass = secret_client.get_secret("InsertSecretPasswordName")
    secret_host_key = secret_client.get_secret("InsertSecretHostKeyName")
    
    # SFTP服务器地址
    host_name = 'InsertFSTPHostAddress'
          
    # 建立SFTP连接
    ssh = paramiko.SSHClient()
    ssh.get_host_keys().add(hostname = host_name, keytype='ssh-rsa', key = paramiko.PKey(data = secret_host_key.value.encode('ascii')))
    ssh.load_system_host_keys()
    ssh.connect(hostname = host_name, port = 22, username=secret_name.value, password=secret_pass.value)
    sftp = ssh.open_sftp()

    # 执行SFTP操作
    # 省略业务逻辑

    # 关闭连接
    sftp.close()
    ssh.close()

host.json配置

{
  "version":  "2.0",
  "logging": {
    "fileLoggingMode": "always",
    "logLevel": {
      "default": "Debug"
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[2.*, 3.0.0)"
  }
}

根本原因

Azure Functions Python Worker启动时会提前完成日志系统初始化,接管日志收集管道,用户代码中后续调用logging.basicConfig()不会修改已绑定的日志处理器,paramiko库的日志器默认没有绑定Azure Worker的日志处理器,产生的日志无法被平台收集、输出到日志流。

修复步骤

  1. 删除代码中无效的日志初始化逻辑
    移除以下两行代码,避免打断Azure Worker已配置好的日志路由:
    logging.Logger.root.level = 10
    logging.basicConfig()
    
  2. 手动将paramiko日志路由到Azure日志管道
    在函数入口的日志配置区域,添加以下代码,把Azure日志系统的处理器绑定给paramiko日志器:
    # 配置paramiko日志
    paramiko_logger = logging.getLogger("paramiko")
    paramiko_logger.setLevel(logging.DEBUG)
    # 复用Azure平台的日志处理器
    for handler in logging.getLogger().handlers:
        paramiko_logger.addHandler(handler)
    # 关闭日志冒泡,避免重复输出
    paramiko_logger.propagate = False
    
  3. 修正host.json日志配置
    不需要把全局默认日志级别设为Debug(会产生大量冗余系统日志),单独为paramiko指定Debug级别即可,修正后的配置如下:
    {
      "version":  "2.0",
      "logging": {
        "fileLoggingMode": "always",
        "logLevel": {
          "default": "Information",
          "paramiko": "Debug",
          "Function": "Trace"
        },
        "console": {
          "isEnabled": true
        }
      },
      "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[2.*, 3.0.0)"
      }
    }
    
  4. (可选)需要将paramiko日志落盘时使用可写目录
    如果需要实现和paramiko.util.log_to_file("paramiko.log")完全一致的文件日志效果,不要直接写入当前工作目录(Azure沙箱下当前目录多为只读,且临时文件会被定期清理),要写入平台开放的日志目录:
    import os
    # Azure Function可写日志目录
    log_file_path = os.path.join(os.environ["HOME"], "LogFiles", "paramiko.log")
    paramiko.util.log_to_file(log_file_path, level=logging.DEBUG)
    
    生成的日志文件可以在Function的Kudu管理站点的LogFiles目录下直接下载查看。

验证方法

重新发布函数、触发执行后,在Azure门户Function的「日志流」页面即可看到paramiko输出的SSH握手、认证、SFTP操作全量调试日志。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:54:19