Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add more configurable JSON logging (#246)
* add JSON formatter by @zblevins * add json logging to config generator, clean up init * change run instructions to use pip install * flake8 fixes * clean up * more cleanup and simplification * add a couple of tests, update requirements, fix warnings * the time is gone, the song is over * cleanup, flake8 * one more flake8 fix * formatting fixes from black * add caller information in log emissions
- Loading branch information
1 parent
7ab4fbc
commit 51698c7
Showing
8 changed files
with
103 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from mock import patch | ||
from repokid.utils.logging import JSONFormatter | ||
|
||
|
||
class MockRecord(object): | ||
def __init__(self, message): | ||
self.created = 1579129029 | ||
self.levelname = "INFO" | ||
self.name = "repokid_test" | ||
self.message = message | ||
self.process = 12345 | ||
self.threadName = "MainThread" | ||
self.exc_info = None | ||
self.filename = "hack_the_planet.py" | ||
self.funcName = "exploit" | ||
self.lineno = 42 | ||
|
||
def getMessage(self): | ||
return self.message | ||
|
||
|
||
class TestLogging(object): | ||
formatter = JSONFormatter() | ||
formatter.hostname = "test_host" | ||
|
||
def test_format(self): | ||
record = MockRecord("Hi there!") | ||
result = self.formatter.format(record) | ||
expected = """{"time": "2020-01-15T22:57:09", "level": "INFO", "name": "repokid_test", "message": "Hi there!", "process": 12345, "thread": "MainThread", "hostname": "test_host", "filename": "hack_the_planet.py", "function": "exploit", "lineNo": 42}""" # noqa: E501 | ||
assert result == expected | ||
|
||
def test_format_with_exception(self): | ||
record = MockRecord("Hi there!") | ||
record.exc_info = ( | ||
AttributeError, | ||
AttributeError("you did a wrong thing"), | ||
None, | ||
) | ||
with patch("traceback.format_exc", return_value="this is totally a traceback"): | ||
result = self.formatter.format(record) | ||
expected = """{"time": "2020-01-15T22:57:09", "level": "INFO", "name": "repokid_test", "message": "Hi there!", "process": 12345, "thread": "MainThread", "hostname": "test_host", "filename": "hack_the_planet.py", "function": "exploit", "lineNo": 42, "exception": "AttributeError: you did a wrong thing", "traceback": "this is totally a traceback"}""" # noqa: E501 | ||
assert result == expected |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
from datetime import datetime | ||
import json | ||
import logging | ||
from socket import gethostname | ||
import traceback | ||
|
||
|
||
class JSONFormatter(logging.Formatter): | ||
"""Custom formatter to output log records as JSON.""" | ||
|
||
hostname = gethostname() | ||
|
||
def format(self, record): | ||
"""Format the given record into JSON.""" | ||
message = { | ||
"time": datetime.utcfromtimestamp(record.created).isoformat(), | ||
"level": record.levelname, | ||
"name": record.name, | ||
"message": record.getMessage(), | ||
"process": record.process, | ||
"thread": record.threadName, | ||
"hostname": self.hostname, | ||
"filename": record.filename, | ||
"function": record.funcName, | ||
"lineNo": record.lineno, | ||
} | ||
|
||
if record.exc_info: | ||
message[ | ||
"exception" | ||
] = f"{record.exc_info[0].__name__}: {record.exc_info[1]}" | ||
message["traceback"] = traceback.format_exc() | ||
|
||
return json.dumps(message, ensure_ascii=False) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,6 @@ boto3 | |
cloudaux | ||
docopt | ||
import_string | ||
logmatic-python | ||
marshmallow<3 | ||
policyuniverse | ||
requests | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters