【发布时间】:2019-03-31 15:55:32
【问题描述】:
我需要以 JSON 格式将 Apache Airflow 日志记录到标准输出。 Airflow 似乎并没有开箱即用地投射出这种能力。我找到了几个能够完成这项任务的 python 模块,但我无法让实现工作。
目前我在airflow/utils/logging.py中应用一个类来修改记录器,如下图:
from pythonjsonlogger import jsonlogger
class StackdriverJsonFormatter(jsonlogger.JsonFormatter, object):
def __init__(self, fmt="%(levelname) %(asctime) %(nanotime) %(severity) %(message)", style='%', *args, **kwargs):
jsonlogger.JsonFormatter.__init__(self, fmt=fmt, *args, **kwargs)
def process_log_record(self, log_record):
if log_record.get('level'):
log_record['severity'] = log_record['level']
del log_record['level']
else:
log_record['severity'] = log_record['levelname']
del log_record['levelname']
if log_record.get('asctime'):
log_record['timestamp'] = log_record['asctime']
del log_record['asctime']
now = datetime.datetime.now().strftime('%Y-%m-%dT%H:%M:%S.%fZ')
log_record['nanotime'] = now
return super(StackdriverJsonFormatter, self).process_log_record(log_record)
我在/airflow/settings.py中实现了这段代码,如下所示:
from airflow.utils import logging as logconf
def configure_logging(log_format=LOG_FORMAT):
handler = logconf.logging.StreamHandler(sys.stdout)
formatter = logconf.StackdriverJsonFormatter()
handler.setFormatter(formatter)
logging = logconf.logging.getLogger()
logging.addHandler(handler)
''' code below was original airflow source code
logging.root.handlers = []
logging.basicConfig(
format=log_format, stream=sys.stdout, level=LOGGING_LEVEL)
'''
我尝试了几种不同的变体,但无法让 python-json-logger 将日志转换为 JSON。也许我没有进入根记录器?我考虑过的另一个选择是将日志手动格式化为 JSON 字符串。也没有运气。感谢您提供任何替代的想法、提示或支持。
干杯!
【问题讨论】:
-
不清楚是否需要自己创建一个 Airflow 进程来将日志输出到标准输出,或者它是否可以是任何其他进程将 Airflow 的日志输出到标准输出。
-
@SergiyKolesnikov - 最好的解决方案是在没有额外的日志记录层的情况下处理这个问题。想将此流发布到标准输出并由 fluentd 直接读取。在 Airflow 中实现任何自定义处理程序(以及格式化程序)时遇到问题。每当我这样做(如上面的 sn-p 中)时,它似乎都拆除了整个日志记录设置。有小费吗?我可以让
configure_logging()方法工作的唯一方法是使用logging.basicConfig(...方法,它需要一个字符串作为格式而不是其他方法传入。
标签: python logging airflow python-jsonschema