|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
# Copyright 2010 - 2017 RhodeCode GmbH and the AppEnlight project authors
|
|
|
#
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
# You may obtain a copy of the License at
|
|
|
#
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
#
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
# See the License for the specific language governing permissions and
|
|
|
# limitations under the License.
|
|
|
|
|
|
import json
|
|
|
import logging
|
|
|
|
|
|
ignored_keys = [
|
|
|
"args",
|
|
|
"asctime",
|
|
|
"created",
|
|
|
"exc_info",
|
|
|
"exc_text",
|
|
|
"filename",
|
|
|
"funcName",
|
|
|
"levelname",
|
|
|
"levelno",
|
|
|
"lineno",
|
|
|
"message",
|
|
|
"module",
|
|
|
"msecs",
|
|
|
"msg",
|
|
|
"name",
|
|
|
"pathname",
|
|
|
"process",
|
|
|
"processName",
|
|
|
"relativeCreated",
|
|
|
"stack_info",
|
|
|
"thread",
|
|
|
"threadName",
|
|
|
]
|
|
|
|
|
|
|
|
|
class JSONFormatter(logging.Formatter):
|
|
|
def format(self, record):
|
|
|
"""
|
|
|
Format the specified record as text.
|
|
|
|
|
|
The record's attribute dictionary is used as the operand to a
|
|
|
string formatting operation which yields the returned string.
|
|
|
Before formatting the dictionary, a couple of preparatory steps
|
|
|
are carried out. The message attribute of the record is computed
|
|
|
using LogRecord.getMessage(). If the formatting string uses the
|
|
|
time (as determined by a call to usesTime(), formatTime() is
|
|
|
called to format the event time. If there is exception information,
|
|
|
it is formatted using formatException() and appended to the message.
|
|
|
"""
|
|
|
record.message = record.getMessage()
|
|
|
log_dict = vars(record)
|
|
|
keys = [k for k in log_dict.keys() if k not in ignored_keys]
|
|
|
payload = {"message": record.message}
|
|
|
payload.update({k: log_dict[k] for k in keys})
|
|
|
record.message = json.dumps(payload, default=lambda x: str(x))
|
|
|
|
|
|
if self.usesTime():
|
|
|
record.asctime = self.formatTime(record, self.datefmt)
|
|
|
s = self.formatMessage(record)
|
|
|
if record.exc_info:
|
|
|
# Cache the traceback text to avoid converting it multiple times
|
|
|
# (it's constant anyway)
|
|
|
if not record.exc_text:
|
|
|
record.exc_text = self.formatException(record.exc_info)
|
|
|
if record.exc_text:
|
|
|
if s[-1:] != "\n":
|
|
|
s = s + "\n"
|
|
|
s = s + record.exc_text
|
|
|
if record.stack_info:
|
|
|
if s[-1:] != "\n":
|
|
|
s = s + "\n"
|
|
|
s = s + self.formatStack(record.stack_info)
|
|
|
return s
|
|
|
|