如何在不先写入stdout的情况下将日志直接从内存直接写入AWS S3?(Python,boto3)

RNH*_*TTR 4 amazon-s3 python-3.x boto3

我正在尝试将Python日志文件直接写入S3,而不先将它们保存到stdout。我希望在程序运行完毕后将日志文件自动写入S3。我想使用boto3 put_object方法:

import atexit
import logging

import boto3  


def write_logs(body, bucket, key):
    s3 = boto3.client("s3")
    s3.put_object(Body=body, Bucket=bucket, Key=key)

log = logging.getLogger("some_log_name")
log.info("Hello S3")

atexit.register(write_logs, body=log, bucket="bucket_name", key="key_name")

quit()
Run Code Online (Sandbox Code Playgroud)

上载到S3时会引发错误。如果我没记错的话,它要求上传到S3的对象必须是字节状的。我有时间重新创建问题后,将使用确切的错误来更新问题。

RNH*_*TTR 7

您需要在此处添加一些内容。首先,创建一个StringIO对象。然后,使用日志记录StreamHandler将日志写入StringIO对象。将处理程序添加到记录器中。最后,getvalue()在StringIO对象上调用该方法。您可以将其写入S3。

import atexit
import io
import logging

import boto3  


def write_logs(body, bucket, key):
    s3 = boto3.client("s3")
    s3.put_object(Body=body, Bucket=bucket, Key=key)  


log = logging.getLogger("some_log_name")
log_stringio = io.StringIO()
handler = logging.StreamHandler(log_stringio)
log.addHandler(handler)

atexit.register(write_logs, body=log_stringio.getvalue(), bucket="bucket_name", key="key_name")

log.info("Hello S3")

quit()
Run Code Online (Sandbox Code Playgroud)

  • `atexit` ... 直到 (4认同)
  • 好的。目前,此问题在 Python 3.9.9 和 boto 1.21.42 上已被破坏。请参阅 https://github.com/boto/boto3/issues/3221 (4认同)
  • 如果您没有看到上面代码的任何输出,如 [doco](https://docs.python.org/3/howto/logging.html#a-simple-example) 所示,默认情况下设置了日志记录级别来警告。所以 log.info("Hello S3") 不会输出任何内容,除非通过 `logging.basicConfig(level=logging.INFO)` 将日志级别更改为 info (2认同)
  • 当我将 `log_stringio.getvalue()` 注册到 `atexit` 时,它对我不起作用。所以我只是注册了 `log_stringio` 并在 `write_log` 函数中调用了 `get_value()` -> `s3.put_object(Body=body.getvalue(), Bucket=bucket, Key=key)` (2认同)