Skip to content

Commit e41eaf9

Browse files
committed
refactor:
- add more specific init method for each framework - minor correct for ENABLE_JSON_LOGGING_DEBUG - update code comments
1 parent de7876a commit e41eaf9

File tree

12 files changed

+66
-45
lines changed

12 files changed

+66
-45
lines changed

README.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Install by running this command:
3131
3232
By default log will be emitted in normal format to ease the local development. To enable it on production set either **json_logging.ENABLE_JSON_LOGGING** or **ENABLE_JSON_LOGGING environment variable** to true.
3333

34-
To configure, call **json_logging.init(framework_name)**. Once configured library will try to configure all loggers (existing and newly created) to emit log in JSON format.
34+
To configure, call **json_logging.init_< framework_name >()**. Once configured library will try to configure all loggers (existing and newly created) to emit log in JSON format.
3535
See following use cases for more detail.
3636

3737
TODO: update guide on how to use ELK stack to view log
@@ -43,7 +43,7 @@ import json_logging, logging, sys
4343

4444
# log is initialized without a web framework name
4545
json_logging.ENABLE_JSON_LOGGING = True
46-
json_logging.init()
46+
json_logging.init_non_web()
4747

4848
logger = logging.getLogger("test-logger")
4949
logger.setLevel(logging.DEBUG)
@@ -60,7 +60,7 @@ import datetime, logging, sys, json_logging, flask
6060

6161
app = flask.Flask(__name__)
6262
json_logging.ENABLE_JSON_LOGGING = True
63-
json_logging.init(framework_name='flask')
63+
json_logging.init_flask()
6464
json_logging.init_request_instrument(app)
6565

6666
# init the logger as usual
@@ -83,7 +83,7 @@ import logging, sys, json_logging, sanic
8383

8484
app = sanic.Sanic()
8585
json_logging.ENABLE_JSON_LOGGING = True
86-
json_logging.init(framework_name='sanic')
86+
json_logging.init_sanic()
8787
json_logging.init_request_instrument(app)
8888

8989
# init the logger as usual
@@ -107,7 +107,7 @@ import asyncio, logging, sys, json_logging, quart
107107

108108
app = quart.Quart(__name__)
109109
json_logging.ENABLE_JSON_LOGGING = True
110-
json_logging.init(framework_name='quart')
110+
json_logging.init_quart()
111111
json_logging.init_request_instrument(app)
112112

113113
# init the logger as usual
@@ -133,7 +133,7 @@ import datetime, logging, sys, json_logging, connexion
133133

134134
app = connexion.FlaskApp(__name__)
135135
json_logging.ENABLE_JSON_LOGGING = True
136-
json_logging.init(framework_name='connexion', specification_dir='openapi/')
136+
json_logging.init_connexion()
137137
json_logging.init_request_instrument(app)
138138

139139
app.add_api('api.yaml')
@@ -163,8 +163,7 @@ Extra property can be added to logging statement as follow:
163163
logger.info("test log statement", extra = {'props' : {'extra_property' : 'extra_value'}})
164164
```
165165
## 2.5 Root logger
166-
If you want to use root logger as main logger to emit log. Made sure you call **config_root_logger()** after initialize root logger (by
167-
logging.basicConfig() or logging.getLogger('root')) [\[2\]](#2-python-logging-propagate)
166+
If you want to use root logger as main logger to emit log. Made sure you call **config_root_logger()** after initialize root logger (by logging.basicConfig() or logging.getLogger('root')) [\[2\]](#2-python-logging-propagate)
168167
```python
169168
logging.basicConfig()
170169
json_logging.config_root_logger()

example/connexion-example/hello.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def post_greeting(name: str) -> str:
1111
def create():
1212
app = connexion.FlaskApp(__name__, port=9090, specification_dir='openapi/')
1313
json_logging.ENABLE_JSON_LOGGING = True
14-
json_logging.init(framework_name='connexion')
14+
json_logging.init_connexion()
1515
json_logging.init_request_instrument(app)
1616

1717
app.add_api('helloworld-api.yaml', arguments={'title': 'Hello World Example'})

example/custom_log_format.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def format(self, record):
5656

5757

5858
def logger_init():
59-
json_logging.init(custom_formatter=CustomJSONLog)
59+
json_logging.__init(custom_formatter=CustomJSONLog)
6060

6161
# You would normally import logger_init and setup the logger in your main module - e.g.
6262
# main.py

example/flask_sample_app.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77

88
app = flask.Flask(__name__)
99
json_logging.ENABLE_JSON_LOGGING = True
10-
# json_logging.CREATE_CORRELATION_ID_IF_NOT_EXISTS = False
11-
json_logging.init(framework_name='flask')
10+
json_logging.init_flask()
1211
json_logging.init_request_instrument(app)
1312

1413
# init the logger as usual
@@ -35,4 +34,4 @@ def exception():
3534

3635

3736
if __name__ == "__main__":
38-
app.run(host='0.0.0.0', port=int(5000), use_reloader=True)
37+
app.run(host='0.0.0.0', port=int(5000), use_reloader=False)

example/non_web.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
# log is initialized without a web framework name
77
json_logging.ENABLE_JSON_LOGGING = True
8-
json_logging.init()
8+
json_logging.init_non_web()
99

1010
logger = logging.getLogger("test logger")
1111
logger.setLevel(logging.DEBUG)

example/quart_sample_app.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
app = quart.Quart(__name__)
1010
json_logging.ENABLE_JSON_LOGGING = True
11-
json_logging.init(framework_name='quart')
11+
json_logging.init_quart()
1212
json_logging.init_request_instrument(app)
1313

1414
# init the logger as usual
@@ -26,4 +26,4 @@ async def home():
2626

2727
if __name__ == "__main__":
2828
loop = asyncio.get_event_loop()
29-
app.run(host='0.0.0.0', port=int(5000), use_reloader=False, loop=loop)
29+
app.run(host='0.0.0.0', port=int(5001), use_reloader=False, loop=loop)

example/sanic_sample_app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
app = sanic.Sanic()
88
json_logging.ENABLE_JSON_LOGGING = True
9-
json_logging.init(framework_name='sanic')
9+
json_logging.__init(framework_name='sanic')
1010
json_logging.init_request_instrument(app)
1111

1212
# init the logger as usual

json_logging/__init__.py

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def register_framework_support(name, app_configurator, app_request_instrumentati
6262

6363
name = name.lower()
6464
if name in _framework_support_map:
65-
_logger.warning("Re-register framework %s", name)
65+
ENABLE_JSON_LOGGING_DEBUG and _logger.warning("Re-register framework %s", name)
6666
_framework_support_map[name] = {
6767
'app_configurator': app_configurator,
6868
'app_request_instrumentation_configurator': app_request_instrumentation_configurator,
@@ -75,10 +75,11 @@ def config_root_logger():
7575
"""
7676
You must call this if you are using root logger.
7777
Make all root logger' handlers produce JSON format
78-
& remove duplicate handlers for request instrumentation logging
78+
& remove duplicate handlers for request instrumentation logging.
79+
Please made sure that you call this after you called "logging.basicConfig() or logging.getLogger('root')
7980
"""
8081
if ENABLE_JSON_LOGGING:
81-
_logger.debug("Update root logger to using JSONLogFormatter")
82+
ENABLE_JSON_LOGGING_DEBUG and _logger.debug("Update root logger to using JSONLogFormatter")
8283
if len(logging.root.handlers) > 0:
8384
if _current_framework is not None or _current_framework != '-':
8485
util.update_formatter_for_loggers([logging.root], JSONLogWebFormatter)
@@ -95,7 +96,11 @@ def config_root_logger():
9596
"logging.basicConfig() or logging.getLogger('root')")
9697

9798

98-
def init(framework_name=None, custom_formatter=None):
99+
def init_non_web():
100+
__init()
101+
102+
103+
def __init(framework_name=None, custom_formatter=None):
99104
"""
100105
Initialize JSON logging support, if no **framework_name** passed, logging will be initialized in non-web context.
101106
This is supposed to be called only one time.
@@ -110,12 +115,16 @@ def init(framework_name=None, custom_formatter=None):
110115
if _current_framework is not None:
111116
raise RuntimeError("Can not call init more than once")
112117

113-
_logger.info("init framework " + str(framework_name))
118+
if custom_formatter:
119+
if not issubclass(custom_formatter, logging.Formatter):
120+
raise ValueError('custom_formatter is not subclass of logging.Formatter', custom_formatter)
121+
122+
ENABLE_JSON_LOGGING_DEBUG and _logger.info("init framework " + str(framework_name))
114123

115124
if framework_name:
116125
framework_name = framework_name.lower()
117126
if framework_name not in _framework_support_map.keys():
118-
raise RuntimeError(framework_name + "is not a supported framework")
127+
raise RuntimeError(framework_name + " is not a supported framework")
119128

120129
_current_framework = _framework_support_map[framework_name]
121130
global _request_util
@@ -125,23 +134,19 @@ def init(framework_name=None, custom_formatter=None):
125134
if ENABLE_JSON_LOGGING and _current_framework['app_configurator'] is not None:
126135
_current_framework['app_configurator']().config()
127136

128-
formatter = JSONLogWebFormatter
129-
elif custom_formatter:
130-
if not issubclass(custom_formatter, logging.Formatter):
131-
raise ValueError('custom_formatter is not subclass of logging.Formatter', custom_formatter)
132-
formatter = custom_formatter
137+
formatter = custom_formatter if custom_formatter else JSONLogWebFormatter
133138
else:
134-
formatter = JSONLogFormatter
139+
formatter = custom_formatter if custom_formatter else JSONLogFormatter
135140

136141
if not ENABLE_JSON_LOGGING:
137142
_logger.warning(
138-
"JSON format is not enable! "
143+
"JSON format is not enable, normal log will be in plain text but request logging still in JSON format! "
139144
"To enable set ENABLE_JSON_LOGGING env var to either one of following values: ['true', '1', 'y', 'yes']")
140145
else:
141146
logging._defaultFormatter = formatter()
142147

143148
# go to all the initialized logger and update it to use JSON formatter
144-
_logger.debug("Update all existing logger to using JSONLogFormatter")
149+
ENABLE_JSON_LOGGING_DEBUG and _logger.debug("Update all existing logger to using JSONLogFormatter")
145150
existing_loggers = list(map(logging.getLogger, logging.Logger.manager.loggerDict))
146151
util.update_formatter_for_loggers(existing_loggers, formatter)
147152

@@ -327,7 +332,12 @@ def format(self, record):
327332
flask_support.FlaskRequestAdapter,
328333
flask_support.FlaskResponseAdapter)
329334

330-
# register flask support
335+
336+
def init_flask(custom_formatter=None):
337+
__init(framework_name='flask', custom_formatter=custom_formatter)
338+
339+
340+
# register sanic support
331341
# noinspection PyPep8
332342
from json_logging.framework.sanic import SanicAppConfigurator, SanicAppRequestInstrumentationConfigurator, \
333343
SanicRequestAdapter, SanicResponseAdapter
@@ -337,18 +347,32 @@ def format(self, record):
337347
SanicRequestAdapter,
338348
SanicResponseAdapter)
339349

350+
351+
def init_sanic(custom_formatter=None):
352+
__init(framework_name='sanic', custom_formatter=custom_formatter)
353+
354+
340355
# register quart support
341356
# noinspection PyPep8
342357
import json_logging.framework.quart as quart_support
343358

344359
register_framework_support('quart', None, quart_support.QuartAppRequestInstrumentationConfigurator,
345-
quart_support.QuartRequestAdapter,
346-
quart_support.QuartResponseAdapter)
360+
quart_support.QuartRequestAdapter,
361+
quart_support.QuartResponseAdapter)
362+
363+
364+
def init_quart(custom_formatter=None):
365+
__init(framework_name='quart', custom_formatter=custom_formatter)
366+
347367

348368
# register connexion support
349369
# noinspection PyPep8
350370
import json_logging.framework.connexion as connexion_support
351371

352372
register_framework_support('connexion', None, connexion_support.ConnexionAppRequestInstrumentationConfigurator,
353-
connexion_support.ConnexionRequestAdapter,
354-
connexion_support.ConnexionResponseAdapter)
373+
connexion_support.ConnexionRequestAdapter,
374+
connexion_support.ConnexionResponseAdapter)
375+
376+
377+
def init_connexion(custom_formatter=None):
378+
__init(framework_name='connexion', custom_formatter=custom_formatter)

json_logging/framework/flask/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import json_logging
66
import json_logging.framework
7-
from json_logging import JSONLogWebFormatter
87
from json_logging.framework_base import AppRequestInstrumentationConfigurator, RequestAdapter, ResponseAdapter
98

109

@@ -36,7 +35,8 @@ def config(self, app):
3635
# Disable standard logging
3736
logging.getLogger('werkzeug').disabled = True
3837

39-
json_logging.util.update_formatter_for_loggers([logging.getLogger('werkzeug')], JSONLogWebFormatter)
38+
json_logging.util.update_formatter_for_loggers([logging.getLogger('werkzeug')],
39+
json_logging.JSONLogWebFormatter)
4040

4141
# noinspection PyAttributeOutsideInit
4242
self.request_logger = logging.getLogger('flask-request-logger')

json_logging/util.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,10 @@ def get_library_logger(logger_name):
2525
return logging.getLogger(logger_name)
2626

2727
logger = logging.getLogger(logger_name)
28-
if json_logging.ENABLE_JSON_LOGGING_DEBUG:
29-
logger.setLevel(logging.DEBUG)
30-
# add stdout output in case parent have no handlers
31-
if len(logger.parent.handlers) == 0:
32-
logger.addHandler(StreamHandler(sys.stdout))
28+
logger.setLevel(logging.DEBUG)
29+
# add stdout output in case parent have no handlers
30+
if len(logger.parent.handlers) == 0:
31+
logger.addHandler(StreamHandler(sys.stdout))
3332

3433
return logger
3534

0 commit comments

Comments
 (0)