In C# I use Serilog to create structured log messages and the Seq log server to analyse them. Let us figure out how this setup works in Python (and if it works at all).
This post is part of my journey to learn Python. You can find the other parts of this series here.
Get Seq
It is a long time since I wrote in 2014 about Seq and how to work with it . Since then it got many more great features, yet the basic concepts are the same. You can download Seq from datalust.co/seq and install it with the default settings.
Install SeqLog
SeqLog is a plugin for Python that allows us to send log messages to Seq. We can install SeqLog with PIP:
1 |
pip install seqlog |
Configure the SeqLog logger
Since SeqLog is a plugin for the Python logging system, we only need to configure the logger and otherwise can reuse all our existing log messages. That is a quick way to get our log messages into Seq.
The most important configuration part is the server_url, in which we need to tell SeqLog where our Seq server runs. The api_key is optional, but it helps to create one for every application that logs to Seq:
1 2 3 4 5 6 7 8 9 10 |
import seqlog seqlog.log_to_seq( server_url="http://127.0.0.1:5341/", api_key="RK**********sttQJA9F", level=logging.NOTSET, batch_size=10, auto_flush_timeout=1, # seconds override_root_logger=True ) |
SeqLog in action
We can extend our logging script from the previous post configuration into this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
import logging import seqlog import time seqlog.log_to_seq( server_url="http://127.0.0.1:5341/", api_key="RK**********sttQJA9F", level=logging.NOTSET, batch_size=10, auto_flush_timeout=1, # seconds override_root_logger=True ) logging.debug("A log message in level debug") logging.info("A log message in level info") logging.warning("A log message in level warning") logging.error("A log message in level error") logging.critical("A log message in level critical") logging.info("Hello, {name}!", name="World") logging.info("Processed order {orderId} by {customer}", orderId = 15, customer = "Johnny") try: result = 2 / 0 except Exception as exception: logging.exception("We got an exception") time.sleep(2) # sleep for 2 seconds to give seqlog time to write to Seq |
Be aware of the last line (and the import time at the beginning). This call to time.sleep() slows my script down long enough so that SeqLog can send its messages to Seq. Without that delay the script ends before the batch size and auto_flush time trigger the transfer of the log messages.
If your configuration is correct, you see your log messages in Seq:
The log message about the processed order is a good example of the benefit structured logging brings. In Seq you can see what the numbers are about and filter for orderId or customer:
The logged exceptions keep their stack trace and you can find that in Seq as well:
Next
SeqLog allows us to keep our log server Seq and makes Python log messages as searchable as the ones from C#. Next week I want to integrate SeqLog with Flask to get the log messages of all my applications to Seq.
1 thought on “Python Friday #64: Structured Log Messages for Seq”