从Heroku高效地收集日志并将其归档到S3

时间:2019-07-03 10:09:34

标签: heroku logging amazon-s3

我有一堆Heroku应用程序(在多个实例上部署了相似的应用程序以服务于不同的客户)。每个应用程序都会生成一些日志,我希望将生成的日志存档到S3。

我尝试使用Heroku附加组件,但过一会儿,这些附加组件服务的价格不足以证明我的用例。

因此,我尝试编写一个非常简单的日志流失,并开始将日志条目转换为文件并将文件发布到S3。

这是示例代码-

else

但是看起来我无法将logplex的摄取率与我的消耗/处理速度相匹配。这是日志行

    now = datetime.datetime.now()
    r = math.floor(random.random() * 10000)

    bucket = 'my-example-bucket'
    key = '/logdrain/raw/{y}/{mon}/{d}/{h}/{h}-{min}-{s}-{ms}-{r}.txt'.format(
        y=now.year, mon=now.month, d=now.day, h=now.hour, min=now.minute, s=now.second, ms=now.microsecond//1000, r=r)

    s3_file_path = 's3://{bucket}/{key}'.format(bucket=bucket, key=key)

    # Append the new content and save the file back to S3
    data = str(request.data)

    if 'l10' in data.lower():
        print('ERROR: ', data)

    with smart_open.open(s3_file_path, 'w') as fout:
        fout.write(data)

    return 'Log write successful', 200

这里的the doc确认相同。只是想知道是否有人想出一种更好的方法来实现日志消耗。

PS:我将其部署在Heroku上的烧瓶应用程序中,该烧瓶应用程序具有2个企业dynos,并且仍然出现消息丢弃问题。

1 个答案:

答案 0 :(得分:0)

我认为,对于每个传入的耗尽请求直接写入S3 永远不会足够快以避免L10错误。我认为您需要两件事:

  1. 缓冲区
  2. 无阻碍地上传到S3

我建议写入本地文件,直到a)达到一定大小,和/或b)经过一定时间。当文件“完成”后,将其上传到S3,而不会阻塞主(侦听)循环。实现非阻塞上传的方法有很多,但是最简单的方法可能是线程化。

由于Heroku的测功机具有ephemeral filesystemcycles,因此您需要捕获 SIGTERM并快速上传之前缓冲的所有内容SIGKILL

当我一直在考虑为自己的Heroku应用实现类似的功能时,我很好奇这对您如何工作。