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

15

我想直接将Python日志文件写入S3,而不是先保存到标准输出(stdout)。我希望程序运行结束时,日志文件可以自动写入S3。我想使用boto3的put_object方法:

Translated text:

我想直接将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()

上传到S3时会出现错误。如果我没记错的话,它要求上传到S3的对象必须类似于字节。一旦我有时间重新创建这个问题,我将更新问题并提供确切的错误信息。

1个回答

21

你需要在这里添加两个东西。首先,创建一个StringIO对象。然后,使用logging StreamHandler将日志写入StringIO对象中。将处理程序添加到记录器中。最后,在StringIO对象上调用getvalue()方法。您可以将其写入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()

6
atexit ... TIL - Shadi
1
顺便提一下,它是 log.addHandler(handler)(没有 self.)。 - Shadi
2
如果您在上面的代码中没有看到任何输出,正如doco所指出的那样,默认情况下日志级别设置为warning。因此,除非通过logging.basicConfig(level=logging.INFO)将日志级别更改为info,否则log.info("Hello S3")不会输出任何内容。 - Tomking Chen
5
当我尝试将 log_stringio.getvalue() 注册到 atexit 时,它对我没有起作用。因此我只是注册了 log_stringio,然后在 write_log 函数中调用 get_value() 方法 -> s3.put_object(Body=body.getvalue(), Bucket=bucket, Key=key) - hru_d
4
好的,目前在使用Python 3.9.9和boto 1.21.42时存在问题。请参阅https://github.com/boto/boto3/issues/3221。 - medley56
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接