Hi @Cerri, in general you should expect your streamlit app to be rerun every time you interact with something on your app. If you absolutely need the log to only run at certain times, you might be able to use st.experimental_memo with a TTL. Or, you could set a flag in st.session_state that keeps track of whether a certain logging statement has already been run, and only call the logging function if that flag is False. Something like:
if not st.session_state["have_logged_thing"]:
logger.debug(...)
st.session_state["have_logged_thing"] = True
@Cerri Did you manage to create the log-file? I have the same issue and can’t figure out how to make it create a file. I tried the standard logging module and the loguru one which @blackary suggested. I can see the logging messages in the terminal, but it doesn’t write them to the file I specified.
I’m using the built in logging module in Python and I’m still getting multiple log entries.
Here is simplified code:
import streamlit as st
import os
import logging
def configure_logging(file_path, level=logging.DEBUG):
logger = logging.getLogger()
logger.setLevel(level)
file_handler = logging.FileHandler(file_path)
file_handler.setLevel(level)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
return logger
if __name__ == '__main__':
log_file = os.path.join(os.getcwd(), 'log', f'parcel-qc.log')
logger = configure_logging(log_file)
check_tables = st.checkbox('Check for data tables')
if st.button('Run Checks'):
if check_tables:
with st.echo():
st.session_state.has_logged = False if 'has_logged' not in st.session_state else False
st.write(st.session_state)
st.write(f'Check for data tables: {check_tables}')
with st.spinner('Checking for data tables...'):
lengthy_process_output = "The quick brown fox jumped over the lazy dog."
st.write(lengthy_process_output)
with st.echo():
if not st.session_state.has_logged:
logger.debug(f'Data table check: {lengthy_process_output}')
st.session_state.has_logged = True
st.write(st.session_state)
I’ve noticed the number of repeats is not consistent, sometimes 4 sometimes 14. It really blows up the size of the log and makes it difficult to debug. I’m using with st.echo() to confirm its only logging once.
Any other suggestions on what to try to get only a single output for each log entry?
Just to test, I thought I’d try replacing the logging with a simple text appending function and replaced my logging calls with the a call to that append function and I only got a single line written to the text file.
I also tried putting BOTH the logging call and the text calls into my app and when doing so, the logging call doesn’t seem to write to the log, but the text append works fine.
There is something in how the python logging works that doesn’t play well with streamlit. I even seemed to get log entries appearing (duplicates too), after shutting the app down. The text append meets my needs, but there is definitely something fishy with the logging module.
The problem seems to be that, because of the streamlit model of “rerun on every interaction”, you end up running the configure_logging multiple times, and therefore setting up multiple loggers. An easy fix is to use @st.cache_resource on the configure_logging function, therefore returning the same logger object each time. This seems to resolve the issue!
Hello, this code should be added to streamlit documentation. It solves the issue of logs duplications and I think it is very important. I am using loguru BTW.
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking “Accept all”, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.