Skip to content
This repository was archived by the owner on Dec 21, 2024. It is now read-only.

Commit bad134f

Browse files
committed
Merge pull request #11 from novapost/master
Some contributions
2 parents 21538d3 + 9bcdb0b commit bad134f

File tree

2 files changed

+43
-19
lines changed

2 files changed

+43
-19
lines changed

src/jsonlogger.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
RESERVED_ATTR_HASH = dict(zip(RESERVED_ATTRS, RESERVED_ATTRS))
2525

26+
2627
def merge_record_extra(record, target, reserved=RESERVED_ATTR_HASH):
2728
"""
2829
Merges extra attributes from LogRecord object into target dictionary
@@ -34,11 +35,12 @@ def merge_record_extra(record, target, reserved=RESERVED_ATTR_HASH):
3435
for key, value in record.__dict__.items():
3536
#this allows to have numeric keys
3637
if (key not in reserved
37-
and not (hasattr(key,"startswith") and key.startswith('_'))
38-
):
38+
and not (hasattr(key, "startswith")
39+
and key.startswith('_'))):
3940
target[key] = value
4041
return target
4142

43+
4244
class JsonFormatter(logging.Formatter):
4345
"""
4446
A custom formatter to format logging records as json strings.
@@ -51,17 +53,24 @@ def __init__(self, *args, **kwargs):
5153
:param json_default: a function for encoding non-standard objects
5254
as outlined in http://docs.python.org/2/library/json.html
5355
:param json_encoder: optional custom encoder
56+
:param prefix: an optional string prefix added at the beggining of
57+
the formatted string
5458
"""
5559
self.json_default = kwargs.pop("json_default", None)
5660
self.json_encoder = kwargs.pop("json_encoder", None)
57-
super(JsonFormatter, self).__init__(*args, **kwargs)
61+
self.prefix = kwargs.pop("prefix", "")
62+
#super(JsonFormatter, self).__init__(*args, **kwargs)
63+
logging.Formatter.__init__(self, *args, **kwargs)
5864
if not self.json_encoder and not self.json_default:
5965
def _default_json_handler(obj):
6066
'''Prints dates in ISO format'''
6167
if isinstance(obj, datetime.datetime):
68+
if obj.year < 1900:
69+
# strftime do not work with date < 1900
70+
return obj.isoformat()
6271
return obj.strftime(self.datefmt or '%Y-%m-%dT%H:%M')
6372
elif isinstance(obj, datetime.date):
64-
return obj.strftime('%Y-%m-%d')
73+
return obj.isoformat()
6574
elif isinstance(obj, datetime.time):
6675
return obj.strftime('%H:%M')
6776
return str(obj)
@@ -98,6 +107,7 @@ def format(self, record):
98107
log_record.update(extras)
99108
merge_record_extra(record, log_record, reserved=self._skip_fields)
100109

101-
return json.dumps(log_record,
102-
default=self.json_default,
103-
cls=self.json_encoder)
110+
return "%s%s" % (self.prefix,
111+
json.dumps(log_record,
112+
default=self.json_default,
113+
cls=self.json_encoder))

tests/tests.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import unittest, logging, json, sys
1+
import unittest
2+
import logging
3+
import json
4+
import sys
25

36
try:
47
import xmlrunner
@@ -15,12 +18,13 @@
1518
import jsonlogger
1619
import datetime
1720

21+
1822
class TestJsonLogger(unittest.TestCase):
1923
def setUp(self):
2024
self.logger = logging.getLogger('logging-test')
2125
self.logger.setLevel(logging.DEBUG)
2226
self.buffer = StringIO()
23-
27+
2428
self.logHandler = logging.StreamHandler(self.buffer)
2529
self.logger.addHandler(self.logHandler)
2630

@@ -55,7 +59,7 @@ def testFormatKeys(self):
5559
'threadName'
5660
]
5761

58-
log_format = lambda x : ['%({0:s})'.format(i) for i in x]
62+
log_format = lambda x: ['%({0:s})'.format(i) for i in x]
5963
custom_format = ' '.join(log_format(supported_keys))
6064

6165
fr = jsonlogger.JsonFormatter(custom_format)
@@ -69,7 +73,7 @@ def testFormatKeys(self):
6973
for supported_key in supported_keys:
7074
if supported_key in log_json:
7175
self.assertTrue(True)
72-
76+
7377
def testUnknownFormatKey(self):
7478
fr = jsonlogger.JsonFormatter('%(unknown_key)s %(message)s')
7579

@@ -84,7 +88,7 @@ def testLogADict(self):
8488
fr = jsonlogger.JsonFormatter()
8589
self.logHandler.setFormatter(fr)
8690

87-
msg = {"text":"testing logging", "num": 1, 5: "9",
91+
msg = {"text": "testing logging", "num": 1, 5: "9",
8892
"nested": {"more": "data"}}
8993
self.logger.info(msg)
9094
logJson = json.loads(self.buffer.getvalue())
@@ -98,8 +102,8 @@ def testLogExtra(self):
98102
fr = jsonlogger.JsonFormatter()
99103
self.logHandler.setFormatter(fr)
100104

101-
extra = {"text":"testing logging", "num": 1, 5: "9",
102-
"nested": {"more": "data"}}
105+
extra = {"text": "testing logging", "num": 1, 5: "9",
106+
"nested": {"more": "data"}}
103107
self.logger.info("hello", extra=extra)
104108
logJson = json.loads(self.buffer.getvalue())
105109
self.assertEqual(logJson.get("text"), extra["text"])
@@ -112,27 +116,37 @@ def testJsonDefaultEncoder(self):
112116
fr = jsonlogger.JsonFormatter()
113117
self.logHandler.setFormatter(fr)
114118

115-
msg = {"adate": datetime.datetime(1999, 12, 31, 23, 59)}
119+
msg = {"adate": datetime.datetime(1999, 12, 31, 23, 59),
120+
"otherdate": datetime.date(1789, 7, 14),
121+
"otherdatetime": datetime.datetime(1789, 7, 14, 23, 59),
122+
"otherdatetimeagain": datetime.datetime(1900, 1, 1)}
116123
self.logger.info(msg)
117124
logJson = json.loads(self.buffer.getvalue())
118125
self.assertEqual(logJson.get("adate"), "1999-12-31T23:59")
126+
self.assertEqual(logJson.get("otherdate"), "1789-07-14")
127+
self.assertEqual(logJson.get("otherdatetime"), "1789-07-14T23:59:00")
128+
self.assertEqual(logJson.get("otherdatetimeagain"),
129+
"1900-01-01T00:00")
119130

120131
def testJsonCustomDefault(self):
121132
def custom(o):
122133
return "very custom"
123134
fr = jsonlogger.JsonFormatter(json_default=custom)
124135
self.logHandler.setFormatter(fr)
125136

126-
msg = {"adate": datetime.datetime(1999, 12, 31, 23, 59), "normal": "value"}
137+
msg = {"adate": datetime.datetime(1999, 12, 31, 23, 59),
138+
"normal": "value"}
127139
self.logger.info(msg)
128140
logJson = json.loads(self.buffer.getvalue())
129141
self.assertEqual(logJson.get("adate"), "very custom")
130142
self.assertEqual(logJson.get("normal"), "value")
131143

132-
if __name__=='__main__':
133-
if len(sys.argv[1:]) > 0 :
144+
145+
if __name__ == '__main__':
146+
if len(sys.argv[1:]) > 0:
134147
if sys.argv[1] == 'xml':
135-
testSuite = unittest.TestLoader().loadTestsFromTestCase(testJsonLogger)
148+
testSuite = unittest.TestLoader().loadTestsFromTestCase(
149+
testJsonLogger)
136150
xmlrunner.XMLTestRunner(output='reports').run(testSuite)
137151
else:
138152
unittest.main()

0 commit comments

Comments
 (0)