Skip to content

Commit

Permalink
Issues/91 - BYO logger (#93)
Browse files Browse the repository at this point in the history
What:
- add ability to bring your own logger

Why:
- closes: #91
- give people more options
  • Loading branch information
komuw authored Feb 2, 2019
1 parent 02c091f commit dbc7d0f
Show file tree
Hide file tree
Showing 15 changed files with 444 additions and 159 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ script:
git remote set-branches --add origin master # https://github.com/travis-ci/travis-ci/issues/6069
git fetch
printf "\n current branch is $TRAVIS_BRANCH \n"
git branch -a
if [ "$TRAVIS_BRANCH" == "master" ]; then
printf "\n $TRAVIS_BRANCH branch, ignoring check for relese notes \n"
else
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
- Add sphinx documentation: https://github.com/komuw/naz/pull/92
- Start tracking changes in a changelog
- Add more type hints and also run `mypy` across the entire repo: https://github.com/komuw/naz/pull/92
- It's now possible to bring your own logger: https://github.com/komuw/naz/pull/93
37 changes: 15 additions & 22 deletions cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,8 @@ def main():
"""
"""
_client_id = "".join(random.choices(string.ascii_uppercase + string.digits, k=17))
logger = logging.getLogger("naz.cli")
handler = logging.StreamHandler()
formatter = logging.Formatter("%(message)s")
handler.setFormatter(formatter)
if not logger.handlers:
logger.addHandler(handler)
logger.setLevel("DEBUG")
logger.info({"event": "naz.cli.main", "stage": "start", "client_id": _client_id})
logger = naz.logger.SimpleBaseLogger("naz.cli")
logger.log(logging.INFO, {"event": "naz.cli.main", "stage": "start", "client_id": _client_id})

loop = asyncio.get_event_loop()
try:
Expand All @@ -129,7 +123,6 @@ def main():
loglevel = (
kwargs.get("loglevel").upper() if kwargs.get("loglevel") else args.loglevel.upper()
)
logger.setLevel(loglevel)
log_metadata = kwargs.get("log_metadata")
if not log_metadata:
log_metadata = {}
Expand All @@ -144,15 +137,15 @@ def main():
"client_id": client_id,
}
)
extra_log_data = {"log_metadata": log_metadata}
logger = naz.NazLoggingAdapter(logger, extra_log_data)
logger.bind(loglevel=loglevel, log_metadata=log_metadata)

logger.info("\n\n\t {} \n\n".format("Naz: the SMPP client."))
logger.log(logging.INFO, "\n\n\t {} \n\n".format("Naz: the SMPP client."))
if dry_run:
logger.warn(
logger.log(
logging.WARN,
"\n\n\t {} \n\n".format(
"Naz: Caution; You have activated dry-run, naz may not behave correctly."
)
),
)

# Load custom classes
Expand All @@ -167,7 +160,7 @@ def main():
if inspect.isclass(outboundqueue):
# DO NOT instantiate class instance, fail with appropriate error instead.
msg = "outboundqueue should be a class instance."
logger.exception({"event": "naz.cli.main", "stage": "end", "error": msg})
logger.log(logging.ERROR, {"event": "naz.cli.main", "stage": "end", "error": msg})
sys.exit(77)

sequence_generator = kwargs.get("sequence_generator")
Expand All @@ -177,7 +170,7 @@ def main():
kwargs["sequence_generator"] = sequence_generator
if inspect.isclass(sequence_generator):
msg = "sequence_generator should be a class instance."
logger.exception({"event": "naz.cli.main", "stage": "end", "error": msg})
logger.log(logging.ERROR, {"event": "naz.cli.main", "stage": "end", "error": msg})
sys.exit(77)

codec_class = kwargs.get("codec_class")
Expand All @@ -186,31 +179,31 @@ def main():
kwargs["codec_class"] = codec_class
if inspect.isclass(codec_class):
msg = "codec_class should be a class instance."
logger.exception({"event": "naz.cli.main", "stage": "end", "error": msg})
logger.log(logging.ERROR, {"event": "naz.cli.main", "stage": "end", "error": msg})
sys.exit(77)
rateLimiter = kwargs.get("rateLimiter")
if rateLimiter:
rateLimiter = load_class(rateLimiter)
kwargs["rateLimiter"] = rateLimiter
if inspect.isclass(rateLimiter):
msg = "rateLimiter should be a class instance."
logger.exception({"event": "naz.cli.main", "stage": "end", "error": msg})
logger.log(logging.ERROR, {"event": "naz.cli.main", "stage": "end", "error": msg})
sys.exit(77)
hook = kwargs.get("hook")
if hook:
hook = load_class(hook)
kwargs["hook"] = hook
if inspect.isclass(hook):
msg = "hook should be a class instance."
logger.exception({"event": "naz.cli.main", "stage": "end", "error": msg})
logger.log(logging.ERROR, {"event": "naz.cli.main", "stage": "end", "error": msg})
sys.exit(77)
throttle_handler = kwargs.get("throttle_handler")
if throttle_handler:
throttle_handler = load_class(throttle_handler)
kwargs["throttle_handler"] = throttle_handler
if inspect.isclass(throttle_handler):
msg = "throttle_handler should be a class instance."
logger.exception({"event": "naz.cli.main", "stage": "end", "error": msg})
logger.log(logging.ERROR, {"event": "naz.cli.main", "stage": "end", "error": msg})
sys.exit(77)

if dry_run:
Expand All @@ -234,10 +227,10 @@ def main():
loop.run_until_complete(cli.unbind())
cli.writer.close()
except Exception as e:
logger.exception({"event": "naz.cli.main", "stage": "end", "error": str(e)})
logger.log(logging.ERROR, {"event": "naz.cli.main", "stage": "end", "error": str(e)})
sys.exit(77)
finally:
logger.info({"event": "naz.cli.main", "stage": "end"})
logger.log(logging.INFO, {"event": "naz.cli.main", "stage": "end"})


if __name__ == "__main__":
Expand Down
1 change: 1 addition & 0 deletions documentation/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ encoding | encoding<sup>1</sup> used to encode messages been sent to SMSC | gsm0
sequence_generator | python class instance used to generate sequence_numbers| naz.sequence.SimpleSequenceGenerator
outboundqueue | python class instance implementing some queueing mechanism. messages to be sent to SMSC are queued using the said mechanism before been sent | N/A
client_id | a unique string identifying a naz client class instance | "".join(random.choices(string.ascii_uppercase + string.digits, k=17))
log_handler | python class instance to be used for logging | naz.logger.SimpleBaseLogger
loglevel | the level at which to log | DEBUG
log_metadata | metadata that will be included in all log statements | {"smsc_host": smsc_host, "system_id": system_id}
codec_class | python class instance to be used to encode/decode messages | naz.nazcodec.SimpleNazCodec
Expand Down
3 changes: 2 additions & 1 deletion documentation/sphinx-docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ API reference
ratelimiter
sequence
throttle
state
state
logger
30 changes: 30 additions & 0 deletions documentation/sphinx-docs/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,36 @@ So, for example if you wanted to annotate all log-events with a release version
and then these will show up in all log events.
by default, naz annotates all log events with smsc_host, system_id and client_id

``naz`` also gives you the ability to supply your own logger.
For example if you wanted ``naz`` to use key=value style of logging, then just create a logger that does just that:

.. code-block:: python
import naz
class KVlogger(naz.logger.BaseLogger):
def __init__(self):
self.logger = logging.getLogger("myKVlogger")
handler = logging.StreamHandler()
formatter = logging.Formatter("%(message)s")
handler.setFormatter(formatter)
if not self.logger.handlers:
self.logger.addHandler(handler)
self.logger.setLevel("DEBUG")
def bind(self, loglevel, log_metadata):
pass
def log(self, level, log_data):
# implementation of key=value log renderer
message = ", ".join("{0}={1}".format(k, v) for k, v in log_data.items())
self.logger.log(level, message)
kvLog = KVlogger()
cli = naz.Client(
...
log_handler=kvLog,
)
3.2.2 hooks
=====================
a hook is a class with two methods request and response, ie it implements naz's BaseHook interface as defined here.
Expand Down
7 changes: 7 additions & 0 deletions documentation/sphinx-docs/logger.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
logger
---------------

.. automodule:: naz.logger
:members: BaseLogger, SimpleBaseLogger
:show-inheritance:

2 changes: 1 addition & 1 deletion naz/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from . import q # noqa: F401
from . import throttle # noqa: F401
from . import sequence # noqa: F401
from . import logger # noqa: F401
from . import nazcodec # noqa: F401
from . import correlater # noqa: F401
from . import ratelimiter # noqa: F401
Expand All @@ -15,6 +16,5 @@
DataCoding,
SmppDataCoding,
)
from .logger import NazLoggingAdapter # noqa: F401

from . import __version__ # noqa: F401
Loading

0 comments on commit dbc7d0f

Please sign in to comment.