Hello community,
here is the log from the commit of package python-python-json-logger for
openSUSE:Factory checked in at 2019-05-10 09:19:35
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-python-json-logger (Old)
and /work/SRC/openSUSE:Factory/.python-python-json-logger.new.5148 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-python-json-logger"
Fri May 10 09:19:35 2019 rev:3 rq:701757 version:0.1.11
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-python-json-logger/python-python-json-logger.changes
2018-12-24 11:42:38.597385556 +0100
+++
/work/SRC/openSUSE:Factory/.python-python-json-logger.new.5148/python-python-json-logger.changes
2019-05-10 09:19:36.928448564 +0200
@@ -1,0 +2,9 @@
+Thu May 9 08:26:21 UTC 2019 - [email protected]
+
+- version update to 0.1.11
+ * no upstream changelog
+- run testsuite
+- run spec cleaner
+- install LICENSE
+
+-------------------------------------------------------------------
Old:
----
python-json-logger-0.1.7.tar.gz
New:
----
python-json-logger-0.1.11.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-python-json-logger.spec ++++++
--- /var/tmp/diff_new_pack.5lHxx5/_old 2019-05-10 09:19:37.460449387 +0200
+++ /var/tmp/diff_new_pack.5lHxx5/_new 2019-05-10 09:19:37.464449393 +0200
@@ -1,7 +1,7 @@
#
# spec file for package python-python-json-logger
#
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,19 +18,17 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-python-json-logger
-Version: 0.1.7
+Version: 0.1.11
Release: 0
Summary: A python library adding a json log formatter
License: BSD-2-Clause
Group: Development/Languages/Python
-Url: http://github.com/madzak/python-json-logger
+URL: http://github.com/madzak/python-json-logger
Source:
https://files.pythonhosted.org/packages/source/p/python-json-logger/python-json-logger-%{version}.tar.gz
BuildRequires: %{python_module setuptools}
BuildRequires: python-rpm-macros
Requires: python-setuptools
-BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildArch: noarch
-
%python_subpackages
%description
@@ -45,8 +43,11 @@
%install
%python_install
+%check
+%python_exec setup.py test
+
%files %{python_files}
-%defattr(-,root,root,-)
+%license LICENSE
%{python_sitelib}/*
%changelog
++++++ python-json-logger-0.1.7.tar.gz -> python-json-logger-0.1.11.tar.gz
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-json-logger-0.1.7/LICENSE
new/python-json-logger-0.1.11/LICENSE
--- old/python-json-logger-0.1.7/LICENSE 1970-01-01 01:00:00.000000000
+0100
+++ new/python-json-logger-0.1.11/LICENSE 2017-08-13 17:28:46.000000000
+0200
@@ -0,0 +1,9 @@
+Copyright (c) 2011, Zakaria Zajac
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-json-logger-0.1.7/MANIFEST.in
new/python-json-logger-0.1.11/MANIFEST.in
--- old/python-json-logger-0.1.7/MANIFEST.in 1970-01-01 01:00:00.000000000
+0100
+++ new/python-json-logger-0.1.11/MANIFEST.in 2017-08-13 17:28:46.000000000
+0200
@@ -0,0 +1,2 @@
+include LICENSE
+recursive-include tests *.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-json-logger-0.1.7/PKG-INFO
new/python-json-logger-0.1.11/PKG-INFO
--- old/python-json-logger-0.1.7/PKG-INFO 2017-03-12 20:48:34.000000000
+0100
+++ new/python-json-logger-0.1.11/PKG-INFO 2019-03-29 20:04:19.000000000
+0100
@@ -1,6 +1,6 @@
-Metadata-Version: 1.1
+Metadata-Version: 1.2
Name: python-json-logger
-Version: 0.1.7
+Version: 0.1.11
Summary: A python library adding a json log formatter
Home-page: http://github.com/madzak/python-json-logger
Author: Zakaria Zajac
@@ -14,11 +14,11 @@
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.1
-Classifier: Programming Language :: Python :: 3.2
-Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
Classifier: Topic :: System :: Logging
+Requires-Python: >=2.7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-json-logger-0.1.7/setup.cfg
new/python-json-logger-0.1.11/setup.cfg
--- old/python-json-logger-0.1.7/setup.cfg 2017-03-12 20:48:34.000000000
+0100
+++ new/python-json-logger-0.1.11/setup.cfg 2019-03-29 20:04:19.000000000
+0100
@@ -1,5 +1,7 @@
+[bdist_wheel]
+universal = 1
+
[egg_info]
tag_build =
tag_date = 0
-tag_svn_revision = 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-json-logger-0.1.7/setup.py
new/python-json-logger-0.1.11/setup.py
--- old/python-json-logger-0.1.7/setup.py 2017-03-12 20:48:18.000000000
+0100
+++ new/python-json-logger-0.1.11/setup.py 2019-03-29 19:31:29.000000000
+0100
@@ -1,37 +1,32 @@
-import sys
-if sys.version_info < (2, 6):
- print(sys.stderr, "{}: need Python 2.6 or later.".format(sys.argv[0]))
- print(sys.stderr, "Your Python is {}".format(sys.version))
- sys.exit(1)
-
from setuptools import setup, find_packages
+
setup(
- name = "python-json-logger",
- version = "0.1.7",
- url = "http://github.com/madzak/python-json-logger",
- license = "BSD",
- description = "A python library adding a json log formatter",
- author = "Zakaria Zajac",
- author_email = "[email protected]",
- package_dir = {'': 'src'},
- packages = find_packages("src", exclude="tests"),
- test_suite = "tests.tests",
- install_requires = ['setuptools'],
- classifiers = [
+ name="python-json-logger",
+ version="0.1.11",
+ url="http://github.com/madzak/python-json-logger",
+ license="BSD",
+ description="A python library adding a json log formatter",
+ author="Zakaria Zajac",
+ author_email="[email protected]",
+ package_dir={'': 'src'},
+ packages=find_packages("src", exclude="tests"),
+ #
https://packaging.python.org/guides/distributing-packages-using-setuptools/#python-requires
+ python_requires='>=2.7',
+ test_suite="tests.tests",
+ classifiers=[
'Development Status :: 3 - Alpha',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
- 'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
- 'Programming Language :: Python :: 3.1',
- 'Programming Language :: Python :: 3.2',
- 'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
+ 'Programming Language :: Python :: 3.5',
+ 'Programming Language :: Python :: 3.6',
+ 'Programming Language :: Python :: 3.7',
'Topic :: System :: Logging',
]
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-json-logger-0.1.7/src/python_json_logger.egg-info/PKG-INFO
new/python-json-logger-0.1.11/src/python_json_logger.egg-info/PKG-INFO
--- old/python-json-logger-0.1.7/src/python_json_logger.egg-info/PKG-INFO
2017-03-12 20:48:34.000000000 +0100
+++ new/python-json-logger-0.1.11/src/python_json_logger.egg-info/PKG-INFO
2019-03-29 20:04:19.000000000 +0100
@@ -1,6 +1,6 @@
-Metadata-Version: 1.1
+Metadata-Version: 1.2
Name: python-json-logger
-Version: 0.1.7
+Version: 0.1.11
Summary: A python library adding a json log formatter
Home-page: http://github.com/madzak/python-json-logger
Author: Zakaria Zajac
@@ -14,11 +14,11 @@
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.6
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.1
-Classifier: Programming Language :: Python :: 3.2
-Classifier: Programming Language :: Python :: 3.3
Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
Classifier: Topic :: System :: Logging
+Requires-Python: >=2.7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-json-logger-0.1.7/src/python_json_logger.egg-info/SOURCES.txt
new/python-json-logger-0.1.11/src/python_json_logger.egg-info/SOURCES.txt
--- old/python-json-logger-0.1.7/src/python_json_logger.egg-info/SOURCES.txt
2017-03-12 20:48:34.000000000 +0100
+++ new/python-json-logger-0.1.11/src/python_json_logger.egg-info/SOURCES.txt
2019-03-29 20:04:19.000000000 +0100
@@ -1,8 +1,12 @@
+LICENSE
+MANIFEST.in
+setup.cfg
setup.py
src/python_json_logger.egg-info/PKG-INFO
src/python_json_logger.egg-info/SOURCES.txt
src/python_json_logger.egg-info/dependency_links.txt
-src/python_json_logger.egg-info/requires.txt
src/python_json_logger.egg-info/top_level.txt
src/pythonjsonlogger/__init__.py
-src/pythonjsonlogger/jsonlogger.py
\ No newline at end of file
+src/pythonjsonlogger/jsonlogger.py
+tests/__init__.py
+tests/tests.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-json-logger-0.1.7/src/python_json_logger.egg-info/requires.txt
new/python-json-logger-0.1.11/src/python_json_logger.egg-info/requires.txt
--- old/python-json-logger-0.1.7/src/python_json_logger.egg-info/requires.txt
2017-03-12 20:48:34.000000000 +0100
+++ new/python-json-logger-0.1.11/src/python_json_logger.egg-info/requires.txt
1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
-setuptools
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-json-logger-0.1.7/src/pythonjsonlogger/jsonlogger.py
new/python-json-logger-0.1.11/src/pythonjsonlogger/jsonlogger.py
--- old/python-json-logger-0.1.7/src/pythonjsonlogger/jsonlogger.py
2017-03-12 20:46:43.000000000 +0100
+++ new/python-json-logger-0.1.11/src/pythonjsonlogger/jsonlogger.py
2019-03-29 19:58:07.000000000 +0100
@@ -5,16 +5,13 @@
import logging
import json
import re
-import datetime
+from datetime import date, datetime, time
import traceback
+import importlib
from inspect import istraceback
-#Support order in python 2.7 and 3
-try:
- from collections import OrderedDict
-except ImportError:
- pass
+from collections import OrderedDict
# skip natural LogRecord attributes
# http://docs.python.org/library/logging.html#logrecord-attributes
@@ -24,10 +21,8 @@
'msecs', 'message', 'msg', 'name', 'pathname', 'process',
'processName', 'relativeCreated', 'stack_info', 'thread', 'threadName')
-RESERVED_ATTR_HASH = dict(zip(RESERVED_ATTRS, RESERVED_ATTRS))
-
-def merge_record_extra(record, target, reserved=RESERVED_ATTR_HASH):
+def merge_record_extra(record, target, reserved):
"""
Merges extra attributes from LogRecord object into target dictionary
@@ -36,7 +31,7 @@
:param reserved: dict or list with reserved keys to skip
"""
for key, value in record.__dict__.items():
- #this allows to have numeric keys
+ # this allows to have numeric keys
if (key not in reserved
and not (hasattr(key, "startswith")
and key.startswith('_'))):
@@ -44,10 +39,41 @@
return target
+class JsonEncoder(json.JSONEncoder):
+ """
+ A custom encoder extending the default JSONEncoder
+ """
+
+ def default(self, obj):
+ if isinstance(obj, (date, datetime, time)):
+ return self.format_datetime_obj(obj)
+
+ elif istraceback(obj):
+ return ''.join(traceback.format_tb(obj)).strip()
+
+ elif type(obj) == Exception \
+ or isinstance(obj, Exception) \
+ or type(obj) == type:
+ return str(obj)
+
+ try:
+ return super(JsonEncoder, self).default(obj)
+
+ except TypeError:
+ try:
+ return str(obj)
+
+ except Exception:
+ return None
+
+ def format_datetime_obj(self, obj):
+ return obj.isoformat()
+
+
class JsonFormatter(logging.Formatter):
"""
A custom formatter to format logging records as json strings.
- extra values will be formatted as str() if nor supported by
+ Extra values will be formatted as str() if not supported by
json default encoder
"""
@@ -58,34 +84,62 @@
:param json_encoder: optional custom encoder
:param json_serializer: a :meth:`json.dumps`-compatible callable
that will be used to serialize the log record.
+ :param json_indent: an optional :meth:`json.dumps`-compatible numeric
value
+ that will be used to customize the indent of the output json.
:param prefix: an optional string prefix added at the beginning of
the formatted string
- """
- self.json_default = kwargs.pop("json_default", None)
- self.json_encoder = kwargs.pop("json_encoder", None)
- self.json_serializer = kwargs.pop("json_serializer", json.dumps)
+ :param json_indent: indent parameter for json.dumps
+ :param json_ensure_ascii: ensure_ascii parameter for json.dumps
+ :param reserved_attrs: an optional list of fields that will be skipped
when
+ outputting json log record. Defaults to all log record attributes:
+ http://docs.python.org/library/logging.html#logrecord-attributes
+ :param timestamp: an optional string/boolean field to add a timestamp
when
+ outputting the json log record. If string is passed, timestamp
will be added
+ to log record using string as key. If True boolean is passed,
timestamp key
+ will be "timestamp". Defaults to False/off.
+ """
+ self.json_default = self._str_to_fn(kwargs.pop("json_default", None))
+ self.json_encoder = self._str_to_fn(kwargs.pop("json_encoder", None))
+ self.json_serializer = self._str_to_fn(kwargs.pop("json_serializer",
json.dumps))
+ self.json_indent = kwargs.pop("json_indent", None)
+ self.json_ensure_ascii = kwargs.pop("json_ensure_ascii", True)
self.prefix = kwargs.pop("prefix", "")
- #super(JsonFormatter, self).__init__(*args, **kwargs)
+ reserved_attrs = kwargs.pop("reserved_attrs", RESERVED_ATTRS)
+ self.reserved_attrs = dict(zip(reserved_attrs, reserved_attrs))
+ self.timestamp = kwargs.pop("timestamp", False)
+
+ # super(JsonFormatter, self).__init__(*args, **kwargs)
logging.Formatter.__init__(self, *args, **kwargs)
if not self.json_encoder and not self.json_default:
- def _default_json_handler(obj):
- '''Prints dates in ISO format'''
- if isinstance(obj, (datetime.date, datetime.time)):
- return obj.isoformat()
- elif istraceback(obj):
- tb = ''.join(traceback.format_tb(obj))
- return tb.strip()
- elif isinstance(obj, Exception):
- return "Exception: %s" % str(obj)
- return str(obj)
- self.json_default = _default_json_handler
+ self.json_encoder = JsonEncoder
+
self._required_fields = self.parse()
self._skip_fields = dict(zip(self._required_fields,
self._required_fields))
- self._skip_fields.update(RESERVED_ATTR_HASH)
+ self._skip_fields.update(self.reserved_attrs)
+
+ def _str_to_fn(self, fn_as_str):
+ """
+ If the argument is not a string, return whatever was passed in.
+ Parses a string such as package.module.function, imports the module
+ and returns the function.
+
+ :param fn_as_str: The string to parse. If not a string, return it.
+ """
+ if not isinstance(fn_as_str, str):
+ return fn_as_str
+
+ path, _, function = fn_as_str.rpartition('.')
+ module = importlib.import_module(path)
+ return getattr(module, function)
def parse(self):
- """Parses format string looking for substitutions"""
+ """
+ Parses format string looking for substitutions
+
+ This method is responsible for returning a list of fields (as strings)
+ to include in all log messages.
+ """
standard_formatters = re.compile(r'\((.+?)\)', re.IGNORECASE)
return standard_formatters.findall(self._fmt)
@@ -98,6 +152,10 @@
log_record.update(message_dict)
merge_record_extra(record, log_record, reserved=self._skip_fields)
+ if self.timestamp:
+ key = self.timestamp if type(self.timestamp) == str else
'timestamp'
+ log_record[key] = datetime.utcnow()
+
def process_log_record(self, log_record):
"""
Override this method to implement custom logic
@@ -109,7 +167,9 @@
"""Returns a json string of the log record."""
return self.json_serializer(log_record,
default=self.json_default,
- cls=self.json_encoder)
+ cls=self.json_encoder,
+ indent=self.json_indent,
+ ensure_ascii=self.json_ensure_ascii)
def format(self, record):
"""Formats a log record and serializes to json"""
@@ -129,6 +189,14 @@
message_dict['exc_info'] = self.formatException(record.exc_info)
if not message_dict.get('exc_info') and record.exc_text:
message_dict['exc_info'] = record.exc_text
+ # Display formatted record of stack frames
+ # default format is a string returned from
:func:`traceback.print_stack`
+ try:
+ if record.stack_info and not message_dict.get('stack_info'):
+ message_dict['stack_info'] =
self.formatStack(record.stack_info)
+ except AttributeError:
+ # Python2.7 doesn't have stack_info.
+ pass
try:
log_record = OrderedDict()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-json-logger-0.1.7/tests/tests.py
new/python-json-logger-0.1.11/tests/tests.py
--- old/python-json-logger-0.1.7/tests/tests.py 1970-01-01 01:00:00.000000000
+0100
+++ new/python-json-logger-0.1.11/tests/tests.py 2018-11-07
14:30:58.000000000 +0100
@@ -0,0 +1,200 @@
+# -*- coding: utf-8 -*-
+import unittest
+import logging
+import json
+import sys
+import traceback
+
+try:
+ import xmlrunner
+except ImportError:
+ pass
+
+try:
+ from StringIO import StringIO
+except ImportError:
+ # Python 3 Support
+ from io import StringIO
+
+sys.path.append('src/python-json-logger')
+from pythonjsonlogger import jsonlogger
+import datetime
+
+
+class TestJsonLogger(unittest.TestCase):
+ def setUp(self):
+ self.logger = logging.getLogger('logging-test')
+ self.logger.setLevel(logging.DEBUG)
+ self.buffer = StringIO()
+
+ self.logHandler = logging.StreamHandler(self.buffer)
+ self.logger.addHandler(self.logHandler)
+
+ def testDefaultFormat(self):
+ fr = jsonlogger.JsonFormatter()
+ self.logHandler.setFormatter(fr)
+
+ msg = "testing logging format"
+ self.logger.info(msg)
+ logJson = json.loads(self.buffer.getvalue())
+
+ self.assertEqual(logJson["message"], msg)
+
+ def testFormatKeys(self):
+ supported_keys = [
+ 'asctime',
+ 'created',
+ 'filename',
+ 'funcName',
+ 'levelname',
+ 'levelno',
+ 'lineno',
+ 'module',
+ 'msecs',
+ 'message',
+ 'name',
+ 'pathname',
+ 'process',
+ 'processName',
+ 'relativeCreated',
+ 'thread',
+ 'threadName'
+ ]
+
+ log_format = lambda x: ['%({0:s})'.format(i) for i in x]
+ custom_format = ' '.join(log_format(supported_keys))
+
+ fr = jsonlogger.JsonFormatter(custom_format)
+ self.logHandler.setFormatter(fr)
+
+ msg = "testing logging format"
+ self.logger.info(msg)
+ log_msg = self.buffer.getvalue()
+ log_json = json.loads(log_msg)
+
+ for supported_key in supported_keys:
+ if supported_key in log_json:
+ self.assertTrue(True)
+
+ def testUnknownFormatKey(self):
+ fr = jsonlogger.JsonFormatter('%(unknown_key)s %(message)s')
+
+ self.logHandler.setFormatter(fr)
+ msg = "testing unknown logging format"
+ try:
+ self.logger.info(msg)
+ except:
+ self.assertTrue(False, "Should succeed")
+
+ def testLogADict(self):
+ fr = jsonlogger.JsonFormatter()
+ self.logHandler.setFormatter(fr)
+
+ msg = {"text": "testing logging", "num": 1, 5: "9",
+ "nested": {"more": "data"}}
+ self.logger.info(msg)
+ logJson = json.loads(self.buffer.getvalue())
+ self.assertEqual(logJson.get("text"), msg["text"])
+ self.assertEqual(logJson.get("num"), msg["num"])
+ self.assertEqual(logJson.get("5"), msg[5])
+ self.assertEqual(logJson.get("nested"), msg["nested"])
+ self.assertEqual(logJson["message"], None)
+
+ def testLogExtra(self):
+ fr = jsonlogger.JsonFormatter()
+ self.logHandler.setFormatter(fr)
+
+ extra = {"text": "testing logging", "num": 1, 5: "9",
+ "nested": {"more": "data"}}
+ self.logger.info("hello", extra=extra)
+ logJson = json.loads(self.buffer.getvalue())
+ self.assertEqual(logJson.get("text"), extra["text"])
+ self.assertEqual(logJson.get("num"), extra["num"])
+ self.assertEqual(logJson.get("5"), extra[5])
+ self.assertEqual(logJson.get("nested"), extra["nested"])
+ self.assertEqual(logJson["message"], "hello")
+
+ def testJsonDefaultEncoder(self):
+ fr = jsonlogger.JsonFormatter()
+ self.logHandler.setFormatter(fr)
+
+ msg = {"adate": datetime.datetime(1999, 12, 31, 23, 59),
+ "otherdate": datetime.date(1789, 7, 14),
+ "otherdatetime": datetime.datetime(1789, 7, 14, 23, 59),
+ "otherdatetimeagain": datetime.datetime(1900, 1, 1)}
+ self.logger.info(msg)
+ logJson = json.loads(self.buffer.getvalue())
+ self.assertEqual(logJson.get("adate"), "1999-12-31T23:59:00")
+ self.assertEqual(logJson.get("otherdate"), "1789-07-14")
+ self.assertEqual(logJson.get("otherdatetime"), "1789-07-14T23:59:00")
+ self.assertEqual(logJson.get("otherdatetimeagain"),
+ "1900-01-01T00:00:00")
+
+ def testJsonCustomDefault(self):
+ def custom(o):
+ return "very custom"
+ fr = jsonlogger.JsonFormatter(json_default=custom)
+ self.logHandler.setFormatter(fr)
+
+ msg = {"adate": datetime.datetime(1999, 12, 31, 23, 59),
+ "normal": "value"}
+ self.logger.info(msg)
+ logJson = json.loads(self.buffer.getvalue())
+ self.assertEqual(logJson.get("adate"), "very custom")
+ self.assertEqual(logJson.get("normal"), "value")
+
+ def testJsonCustomLogicAddsField(self):
+ class CustomJsonFormatter(jsonlogger.JsonFormatter):
+
+ def process_log_record(self, log_record):
+ log_record["custom"] = "value"
+ # Old Style "super" since Python 2.6's logging.Formatter is old
+ # style
+ return jsonlogger.JsonFormatter.process_log_record(self,
log_record)
+
+ self.logHandler.setFormatter(CustomJsonFormatter())
+ self.logger.info("message")
+ logJson = json.loads(self.buffer.getvalue())
+ self.assertEqual(logJson.get("custom"), "value")
+
+ def testExcInfo(self):
+ fr = jsonlogger.JsonFormatter()
+ self.logHandler.setFormatter(fr)
+ try:
+ raise Exception('test')
+ except Exception:
+
+ self.logger.exception("hello")
+
+ expected_value = traceback.format_exc()
+ # Formatter removes trailing new line
+ if expected_value.endswith('\n'):
+ expected_value = expected_value[:-1]
+
+ logJson = json.loads(self.buffer.getvalue())
+ self.assertEqual(logJson.get("exc_info"), expected_value)
+
+ def testEnsureAsciiTrue(self):
+ fr = jsonlogger.JsonFormatter()
+ self.logHandler.setFormatter(fr)
+ self.logger.info('Привет')
+ msg = self.buffer.getvalue().split('"message": "', 1)[1].split('"',
1)[0]
+ self.assertEqual(msg, r"\u041f\u0440\u0438\u0432\u0435\u0442")
+
+ def testEnsureAsciiFalse(self):
+ fr = jsonlogger.JsonFormatter(json_ensure_ascii=False)
+ self.logHandler.setFormatter(fr)
+ self.logger.info('Привет')
+ msg = self.buffer.getvalue().split('"message": "', 1)[1].split('"',
1)[0]
+ self.assertEqual(msg, "Привет")
+
+
+
+if __name__ == '__main__':
+ if len(sys.argv[1:]) > 0:
+ if sys.argv[1] == 'xml':
+ testSuite = unittest.TestLoader().loadTestsFromTestCase(
+ TestJsonLogger)
+ xmlrunner.XMLTestRunner(output='reports').run(testSuite)
+ else:
+ unittest.main()