How to use logging library in Python to create HTML log files with embedded plots?

I want to create HTML log files with embedded plots using the logging library in Python. For this purpose, I found a code that helps in creating and configuring a logger object that will write the log messages to an HTML file. It is using Matplotlib to create the plot and then embed it in the HTML log file and log messages, as usual, using the logger object created. In addition to logging messages, it can also include the plot in the log message.
Here is the code:

import logging
from logging.handlers import RotatingFileHandler
import matplotlib.pyplot as plt
import base64
from io import BytesIO
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

# define a rotating file handler
handler = RotatingFileHandler('example.log', maxBytes=100000, 
                        backupCount=1)
handler.setLevel(logging.INFO)

# define a formatter
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)

# add the handler to the logger
logger.addHandler(handler)
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [4, 5, 6])
ax.set_title('Example plot')
ax.set_xlabel('X label')
ax.set_ylabel('Y label')

# Convert plot to base64 string
buf = BytesIO()
fig.savefig(buf, format='png')
buf.seek(0)
plot_data = base64.b64encode(buf.read()).decode('utf8')
plt.close()

# Embed plot in HTML log message
plot_html = '<img src="data:image/png;base64,{}">'.format(plot_data)
logger.info(plot_html)
logger.info('This is a log message with an embedded plot: {}'
                    .format(plot_html))

Apart from the above code, Iā€™m curious are there many other methods available for creating HTML log files with embedded plots using the logging library in Python? Can someone share any alternative code with me that helps me in logging messages in HTML files with embedded plots?

1 Like

Hi, @safa The code you provided is a great example of how to use the logging library in Python to create HTML log files with embedded plots. It creates a logger object that writes log messages to an HTML file and includes a plot in the log message.

There are other ways to create HTML log files with embedded plots using the logging library in Python. One alternative method is to use the loguru library, which provides an easy-to-use interface for logging messages and supports adding rich data like plots and tables to the logs.

Here is an example code snippet that demonstrates how to use loguru to create an HTML log file with an embedded plot:

import loguru
import matplotlib.pyplot as plt
import base64
from io import BytesIO

# Create a logger object
logger = loguru.logger

# Create a plot and save to a buffer
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [4, 5, 6])
ax.set_title('Example plot')
ax.set_xlabel('X label')
ax.set_ylabel('Y label')

buf = BytesIO()
fig.savefig(buf, format='png')
buf.seek(0)
plot_data = base64.b64encode(buf.read()).decode('utf8')
plt.close()

# Add the plot to a log message
logger.add('example.html', format='<b>{time}</b> {level}: {message}',
           level='DEBUG', compression='zip',
           serialize=True, rotation='10 MB',
           enqueue=True)

logger.debug('This is a log message with an embedded plot',
             plot='<img src="data:image/png;base64,{}">'.format(plot_data))

In this example, loguru is used to create a logger object that writes log messages to an HTML file. The logger.debug method is used to log a message with an embedded plot. The plot argument contains an HTML img tag that displays the plot in the log message. I hope this helps!

1 Like

Hello @safa, there are many alternatives to achieve the task you accomplished with your code. I faced a similar issue some time ago and used the following code to solve it:

import datetime
import matplotlib.pyplot as plt
import base64
from io import BytesIO

# Create a plot and save to a buffer
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [4, 5, 6])
ax.set_title('Example plot')
ax.set_xlabel('X label')
ax.set_ylabel('Y label')

buf = BytesIO()
fig.savefig(buf, format='png')
buf.seek(0)
plot_data = base64.b64encode(buf.read()).decode('utf8')
plt.close()

# Create the HTML log file with the embedded plot
timestamp = datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
filename = f'example_{timestamp}.html'
with open(filename, 'w') as f:
    f.write(f'<html><head><title>Example log file with plot</title></head><body>')
    f.write(f'<h1>Example log file with plot</h1>')
    f.write(f'<p>This is a log message with an embedded plot:</p>')
    f.write(f'<img src="data:image/png;base64,{plot_data}">')
    f.write('</body></html>')

Here is how this code works:

  • It creates a plot using the matplotlib library and saves it to a buffer using a BytesIO object.
  • It then encodes the plot data as base64 and stores it in a variable.
  • After encoding, the code generates a timestamp for the log file name using datetime.datetime.now() and formats it appropriately.
  • Lastly, the code opens a file with the generated filename and writes the HTML code to it, including the embedded plot. The HTML code is written manually instead of using a library or formatter.

I hope this helps you, too!