Logging `emit` to display in a text area


I have a complex_function() that emits logs that I would like to view in a st.text_area.

Steps to reproduce

Code snippet:

import logging

class StreamlitHandler(logging.Handler):
    def __init__(self):
        super(StreamlitHandler, self).__init__()

    def emit(self, record):
        new_log = self.format(record) + '\n'
        if 'log_data' not in st.session_state:
            st.session_state.log_data = ""
        st.session_state.log_data += new_log
import streamlit as st
import logging
import time

# Define a complex function that uses logging
def complex_function():
    logger = logging.getLogger(__name__)
    for i in range(5):
        logger.info(f'Processing {i}')
        time.sleep(1)  # simulate some processing time

# Setup streamlit UI
st.title("Display Logger in Streamlit")

# Setup logger
logger = logging.getLogger(__name__)
handler = StreamlitHandler()
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')

if st.button('Run Complex Function'):

# Display the logs
st.text_area("Logs", value=st.session_state.get('log_data', ''), height=200, key="log_area")

Expected behavior:

The expected behavior would be to get a text_area that gets updated every second with

2023-08-09 01:37:08.046 Processing 0
2023-08-09 01:37:09.051 Processing 1
2023-08-09 01:37:10.057 Processing 2
2023-08-09 01:37:11.061 Processing 3
2023-08-09 01:37:12.068 Processing 4

Actual behavior:

I get duplicated log messages, all showing up at once (after 4s) and greyed out duplicates of other streamlit components which disappear after the execution.

Debug info

  • Streamlit version: (get it with $ streamlit version)
  • Python version: Streamlit, version 1.17.0
  • Using PipEnv
  • OS version: MacOS
  • Browser version: Version 115.0.5790.170 (Official Build) (arm64)

Hey @orso135! :wave: Welcome to our community!

I’ve tweaked your code and it seems to be running OK now. Check out the demo below:

Demo GIF

Here’s the modified code:

import streamlit as st
import time
from datetime import datetime

# A complex function using logging
def complex_function(log_area):
    log_data = ""
    for i in range(5):
        log_line = f'{datetime.now()} - INFO - Processing {i}\n'
        log_data += log_line
        log_area.markdown(f"```\n{log_data}\n```")  # Display logs using markdown
        time.sleep(1)  # Simulate processing time

# Streamlit UI setup
st.title("Display Logger in Streamlit")

if st.button('Run Complex Function'):
    log_area = st.empty()  # Placeholder for text_area update

If that fixes your issue, great! If not, just let me know, and we can dig deeper.

Best wishes,

1 Like

unfortunately your solution implies changes of the library. I ended up changing the lbrary to output logs to file, then using asyncio tasks to read the file

thank you though!

1 Like

Glad to hear that was still useful! :slight_smile:


This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.