跳转到主要内容

概述

在 PPIO Agent 沙箱中执行代码后,通常需要获取运行日志进行调试和分析。本文档介绍如何将代码的日志重定向到文件,并从沙箱下载到客户端(本地)。详细文件系统操作可参考 下载文件 涵盖两种场景:
  1. 代码本身没有日志配置 — 通过 stdout/stderr 重定向捕获日志
  2. 代码本身已有日志配置(如 Python logging 输出到文件) — 直接下载已有的日志文件

场景一:代码无日志配置,通过重定向捕获日志

方案 A:使用 commands.run() + Shell 重定向

通过 Shell 的 > / 2>&1 将 stdout 和 stderr 重定向到沙箱内的日志文件,然后下载。
import os
from ppio_sandbox.code_interpreter import Sandbox

os.environ["PPIO_API_KEY"] = "YOUR API KEY"

sandbox = Sandbox.create()

# 定义沙箱内的日志文件路径
log_file = "/tmp/app.log"

code = """
import sys

print('这是标准输出日志')
print('处理中...', file=sys.stderr)
print('执行完成')
"""

# 上传代码到沙箱
sandbox.files.write("/home/user/test.py", code)

# 执行代码,将 stdout 和 stderr 都重定向到日志文件
# 使用 2>&1 将 stderr 合并到 stdout,再通过 > 重定向到文件
try:
    result = sandbox.commands.run(f'python3 /home/user/test.py > {log_file} 2>&1')
except Exception as e:
    print(e)

# 从沙箱读取日志文件
log_content = sandbox.files.read(log_file)

# 保存到本地
with open('./app.log', 'w') as f:
    f.write(log_content)

print("日志已下载到 ./app.log")

sandbox.kill()

方案 B:使用 run_code() 捕获执行结果中的日志

run_code() 返回的执行结果中自带 logs,可以直接写入文件,无需额外的 Shell 重定向。
import os
from ppio_sandbox.code_interpreter import Sandbox

os.environ["PPIO_API_KEY"] = "YOUR API KEY"

sandbox = Sandbox.create()

# 执行 Python 代码
execution = sandbox.run_code("""
import sys

print("这是标准输出日志")
print("处理中...", file=sys.stderr)
print("执行完成")
""")

# execution.logs 包含了 stdout 的输出
log_content = str(execution.logs)

# 保存到本地
with open('./app.log', 'w') as f:
    f.write(log_content)

print("日志已保存到 ./app.log")

sandbox.kill()

场景二:代码已有日志配置,日志输出到指定目录

很多项目代码中已经配置了日志框架(如 Python 的 logging 模块),日志会输出到指定的文件路径。此时只需要知道日志文件的位置,直接从沙箱下载即可。
import os
from ppio_sandbox.code_interpreter import Sandbox

os.environ["PPIO_API_KEY"] = "YOUR API KEY"

sandbox = Sandbox.create()
print(f"Sandbox created: {sandbox.sandbox_id}")

# 步骤 1:上传应用代码到沙箱
app_code = """\
import logging
import sys

logging.basicConfig(
    filename='/home/user/logs/app.log',
    level=logging.DEBUG,
    format='%(asctime)s [%(levelname)s] %(message)s',
)

logger = logging.getLogger(__name__)

logger.info('Application started')
logger.debug('Loading configuration...')
logger.warning('Memory usage is high')
logger.error('Failed to connect to database')

print('stdout: all tasks completed')
print('stderr: a warning message', file=sys.stderr)
"""

sandbox.commands.run("mkdir -p /home/user/logs")
sandbox.files.write("/home/user/main.py", app_code)
print("Code uploaded to /home/user/main.py")

# 步骤 2:执行应用代码
print("Running application...")
result = sandbox.commands.run("cd /home/user && python3 main.py")
print(f"stdout: {result.stdout}")
print(f"stderr: {result.stderr}")

# 步骤 3:下载日志文件
log_content = sandbox.files.read("/home/user/logs/app.log")

with open("./app.log", "w") as f:
    f.write(log_content)

print(f"Log downloaded to ./app.log ({len(log_content)} bytes)")
print("--- Log content ---")
print(log_content)

sandbox.kill()
print("Sandbox destroyed")

注意事项

  1. 文件大小:沙箱存储空间为 20 GB,注意日志文件不要太大。
  2. 编码问题sandbox.files.read() 返回的是字符串,如果日志包含二进制内容,可能需要特殊处理。
  3. 沙箱生命周期:日志下载要在 sandbox.kill() 之前完成,沙箱销毁后文件不可恢复。
  4. 并发写入:如果代码有多进程/多线程写日志,建议各自写入不同文件,避免写入冲突。