Пользовательский файл журнала в Lambda с Python - PullRequest
0 голосов
/ 06 августа 2020

У меня есть некоторые требования, для которых мне нужны мои лямбда-функции для создания текстового файла с журналами в формате json и загрузки его в S3, из S3 у нас есть таблица Spectrum, которая запускает более поздние процессы. Я знаю, что с помощью cloudwatch могут быть разные способы сделать это, но мы должны придерживаться этого из-за более поздних процессов, которые мы запускаем в журналах. Теперь ... проблема в том, что код на моей машине работает нормально. Когда я тестирую функцию, она работает ... только в первый раз. После некоторого устранения неполадок есть способ воспроизвести это:

import json
import os
import os
import platform
from urllib.request import urlopen
import logging
import sys
from datetime import datetime
from os import listdir
from os.path import isfile, join

def log_start(log_prefix):
    now = datetime.now()
    log_id = str(now).replace(':', '').replace(' ', '').replace('.', '').replace('-', '')[:14]
    log_name = '/tmp/{}_{}.txt'.format(log_prefix, log_id)

    root = logging.getLogger()
    if root.handlers:
        for handler in root.handlers:
            root.removeHandler(handler)

    logging.basicConfig(level=logging.INFO, filename=log_name, filemode='a+',
                        format='''{{"log_id":"{}", "created_date":"%(asctime)s.%(msecs)03d", "action_text":"%(message)s"}}'''.format(
                            log_id),
                        datefmt="%Y-%m-%dT%H:%M:%S")
    root = logging.getLogger()
    root.setLevel(logging.INFO)

    handler = logging.StreamHandler(sys.stdout)
    handler.setLevel(logging.INFO)
    formatter = logging.Formatter(
        '''{{"log_id":"{}", "created_date":"%(asctime)s.%(msecs)03d", "action_text":"%(message)s"}}'''.format(
            log_id),
        datefmt="%Y-%m-%dT%H:%M:%S")
    handler.setFormatter(formatter)
    root.addHandler(handler)

    return log_name, log_id

def lambda_handler(event, context):
    
    log_name, log_id = log_start('log_prefix')
    logging.info('test')
    print(log_name)
    print(log_id)
    print(isfile(log_name))

Если вы запустите это несколько раз, вы заметите, что последний оператор печати возвращает истину в первый раз, а затем всегда ложь. Если я запустил его снова, скажем, через час, то же самое, сначала верно, а затем все время ложно. Почему это происходит? Почему это срабатывает только один раз?

EDIT: Это не может быть из-за того, что в / tmp не хватает места. Эта проблема также возникает, если я подключаю диск EFS и пытаюсь направить файл журнала на диск EFS.

1 Ответ

0 голосов
/ 14 августа 2020

После долгого поиска и устранения неисправностей я понял, что проблема здесь:

if root.handlers:
    for handler in root.handlers:
        root.removeHandler(handler)

Причина в том, что removeHandler удаляет элемент из обработчиков (список) в середине l oop. Таким образом, во втором прогоне он не удаляет все обработчики правильно. Решением было изменить его на:

if root.handlers:
    handlers = []

И проблема решена. :)

...