Skip to content

Commit a60ad7f

Browse files
committedJul 4, 2017
Use mozlog for application logging
Configure the application to use the mozlog structured log format for application-level log messages (log messages from libraries and frameworks still go through the Python Standard Library string logger).
1 parent 0023c26 commit a60ad7f

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed
 

‎landoapi/app.py

+42
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,20 @@
55

66
import click
77
import connexion
8+
import logging
89

910
from connexion.resolver import RestyResolver
1011
from landoapi.dockerflow import dockerflow
1112
from landoapi.models.storage import alembic, db
13+
from mozlogging import MozLogFormatter
14+
15+
logger = logging.getLogger(__name__)
1216

1317

1418
def create_app(version_path):
1519
"""Construct an application instance."""
20+
initialize_logging()
21+
1622
app = connexion.App(__name__, specification_dir='spec/')
1723
app.add_api('swagger.yml', resolver=RestyResolver('landoapi.api'))
1824

@@ -36,6 +42,42 @@ def create_app(version_path):
3642
return app
3743

3844

45+
def initialize_logging():
46+
"""Initialize application-wide logging."""
47+
mozlog_handler = logging.StreamHandler()
48+
mozlog_handler.setFormatter(MozLogFormatter())
49+
50+
# We need to configure the logger just for our application code. This is
51+
# because the MozLogFormatter changes the signature of the standard
52+
# library logging functions. Any code that tries to log a message assuming
53+
# the standard library's formatter is in place, such as the code in the
54+
# libraries we use, with throw an error if the MozLogFormatter tries to
55+
# handle the message.
56+
app_logger = logging.getLogger('landoapi')
57+
58+
app_logger.addHandler(mozlog_handler)
59+
60+
app_logger.setLevel(log_level_from_environ())
61+
62+
logger.debug({'msg': 'logging initialized'}, 'debug')
63+
64+
65+
def log_level_from_environ():
66+
"""Read the operator's desired log level from the LOG_LEVEL env var.
67+
68+
The log level string can be lowercase or uppercase. The string must be
69+
one of the levels from the Python Standard Library's logging library.
70+
Defaults to logging.INFO if the environment variable is not set.
71+
72+
Returns the logging.LEVEL object for the level that was read. Raises an
73+
exception if the given log level is not one of the Python Standard
74+
Library's log levels.
75+
"""
76+
level_str = os.environ.get('LOG_LEVEL', 'INFO')
77+
# getattr() raises an exception if the requested log level doesn't exist.
78+
return getattr(logging, level_str.upper())
79+
80+
3981
@click.command()
4082
@click.option('--debug', envvar='DEBUG', is_flag=True)
4183
@click.option('--port', envvar='PORT', default=8888)

‎requirements.txt

+3
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,6 @@ Flask-Alembic==2.0.1 \
7272
--hash=sha256:7e67740b0b08d58dcae0c701d56b56e60f5fa4af907bb82b4cb0469229ba94ff
7373
uWSGI==2.0.15 \
7474
--hash=sha256:572ef9696b97595b4f44f6198fe8c06e6f4e6351d930d22e5330b071391272ff
75+
mozlogging==0.1.0 \
76+
--hash=sha256:2fc3d520a17b048c8723abdba19f6c01f2bcaf4182944aaac5906f28bd5b7d77 \
77+
--hash=sha256:2e1362b80418b845164d8d47337da838dade05720dbaf17956d1cafebc511b94

0 commit comments

Comments
 (0)
Failed to load comments.