77import re
88from datetime import date , datetime , time
99import traceback
10+ import importlib
1011
1112from inspect import istraceback
1213
13- #Support order in python 2.7 and 3
14+ # Support order in python 2.7 and 3
1415try :
1516 from collections import OrderedDict
1617except ImportError :
@@ -34,7 +35,7 @@ def merge_record_extra(record, target, reserved):
3435 :param reserved: dict or list with reserved keys to skip
3536 """
3637 for key , value in record .__dict__ .items ():
37- #this allows to have numeric keys
38+ # this allows to have numeric keys
3839 if (key not in reserved
3940 and not (hasattr (key , "startswith" )
4041 and key .startswith ('_' ))):
@@ -46,6 +47,7 @@ class JsonEncoder(json.JSONEncoder):
4647 """
4748 A custom encoder extending the default JSONEncoder
4849 """
50+
4951 def default (self , obj ):
5052 if isinstance (obj , (date , datetime , time )):
5153 return self .format_datetime_obj (obj )
@@ -100,17 +102,17 @@ def __init__(self, *args, **kwargs):
100102 to log record using string as key. If True boolean is passed, timestamp key
101103 will be "timestamp". Defaults to False/off.
102104 """
103- self .json_default = kwargs .pop ("json_default" , None )
104- self .json_encoder = kwargs .pop ("json_encoder" , None )
105- self .json_serializer = kwargs .pop ("json_serializer" , json .dumps )
105+ self .json_default = self . _str_to_fn ( kwargs .pop ("json_default" , None ) )
106+ self .json_encoder = self . _str_to_fn ( kwargs .pop ("json_encoder" , None ) )
107+ self .json_serializer = self . _str_to_fn ( kwargs .pop ("json_serializer" , json .dumps ) )
106108 self .json_indent = kwargs .pop ("json_indent" , None )
107109 self .json_ensure_ascii = kwargs .pop ("json_ensure_ascii" , True )
108110 self .prefix = kwargs .pop ("prefix" , "" )
109111 reserved_attrs = kwargs .pop ("reserved_attrs" , RESERVED_ATTRS )
110112 self .reserved_attrs = dict (zip (reserved_attrs , reserved_attrs ))
111113 self .timestamp = kwargs .pop ("timestamp" , False )
112114
113- #super(JsonFormatter, self).__init__(*args, **kwargs)
115+ # super(JsonFormatter, self).__init__(*args, **kwargs)
114116 logging .Formatter .__init__ (self , * args , ** kwargs )
115117 if not self .json_encoder and not self .json_default :
116118 self .json_encoder = JsonEncoder
@@ -120,6 +122,21 @@ def __init__(self, *args, **kwargs):
120122 self ._required_fields ))
121123 self ._skip_fields .update (self .reserved_attrs )
122124
125+ def _str_to_fn (self , fn_as_str ):
126+ """
127+ If the argument is not a string, return whatever was passed in.
128+ Parses a string such as package.module.function, imports the module
129+ and returns the function.
130+
131+ :param fn_as_str: The string to parse. If not a string, return it.
132+ """
133+ if not isinstance (fn_as_str , str ):
134+ return fn_as_str
135+
136+ path , _ , function = fn_as_str .rpartition ('.' )
137+ module = importlib .import_module (path )
138+ return getattr (module , function )
139+
123140 def parse (self ):
124141 """
125142 Parses format string looking for substitutions
0 commit comments