Skip to content

Commit

Permalink
fix/logger setting (#786)
Browse files Browse the repository at this point in the history
* Fix the logger settings so the already created Streamlit loggers work as expected

* Fix to deal with Streamlit's logger name aliasing from "root" to "streamlit"

* Update the logger structure to deal with the "streamlit" logger as one root
  • Loading branch information
whitphx authored Mar 14, 2024
1 parent 9ad77f3 commit 7bb74e2
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 30 deletions.
2 changes: 1 addition & 1 deletion packages/kernel/src/declarations.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ declare module "*.whl" {

// Declarations for the `self` object in worker.ts some of whose properties are used to share values with the Python environment.
interface Window {
__logCallback__: (msg: string) => void;
__logCallback__: (levelno: number, msg: string) => void;
__streamlitFlagOptions__: Record<string, PyodideConvertiblePrimitive>;
}
80 changes: 51 additions & 29 deletions packages/kernel/src/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ async function loadPyodideAndPackages() {
console.debug("Installed the requirements");
}

// The following code is necessary to avoid errors like `NameError: name '_imp' is not defined`
// The following code is necessary to avoid errors like `NameError: name '_imp' is not defined`
// at importing installed packages.
await pyodide.runPythonAsync(`
import importlib
Expand Down Expand Up @@ -225,45 +225,67 @@ async function loadPyodideAndPackages() {
streamlit.logger.setup_formatter = None
streamlit.logger.update_formatter = lambda *a, **k: None
streamlit.logger.set_log_level = lambda *a, **k: None
for name in streamlit.logger._loggers.keys():
if name == "root":
name = "streamlit"
logger = logging.getLogger(name)
logger.propagate = True
logger.handlers.clear()
logger.setLevel(logging.NOTSET)
streamlit.logger._loggers = {}
`);
// Then configure the logger.
const logCallback = (msg: string) => {
if (msg.startsWith("CRITICAL") || msg.startsWith("ERROR")) {
const logCallback = (levelno: number, msg: string) => {
if (levelno >= 40) {
console.error(msg);
} else if (msg.startsWith("WARNING")) {
} else if (levelno >= 30) {
console.warn(msg);
} else if (msg.startsWith("INFO")) {
} else if (levelno >= 20) {
console.info(msg);
} else if (msg.startsWith("DEBUG")) {
console.debug(msg);
} else {
console.log(msg);
console.debug(msg);
}
};
self.__logCallback__ = logCallback;
await pyodide.runPythonAsync(`
from js import __logCallback__
class JsHandler(logging.Handler):
def emit(self, record):
msg = self.format(record)
__logCallback__(msg)
main_formatter = logging.Formatter("%(levelname)s:%(name)s:%(message)s")
js_handler = JsHandler()
js_handler.setFormatter(main_formatter)
root_logger = logging.getLogger()
root_logger.handlers.clear()
root_logger.addHandler(js_handler)
root_logger.setLevel(logging.DEBUG)
streamlit_handler = logging.getLogger("streamlit")
streamlit_handler.setLevel(logging.DEBUG)
def setup_loggers(streamlit_level, streamlit_message_format):
from js import __logCallback__
class JsHandler(logging.Handler):
def emit(self, record):
msg = self.format(record)
__logCallback__(record.levelno, msg)
root_message_format = "%(levelname)s:%(name)s:%(message)s"
root_logger = logging.getLogger()
root_logger.handlers.clear()
root_formatter = logging.Formatter(root_message_format)
root_handler = JsHandler()
root_handler.setFormatter(root_formatter)
root_logger.addHandler(root_handler)
root_logger.setLevel(logging.DEBUG)
streamlit_logger = logging.getLogger("streamlit")
streamlit_logger.propagate = False
streamlit_logger.handlers.clear()
streamlit_formatter = logging.Formatter(streamlit_message_format)
streamlit_handler = JsHandler()
streamlit_handler.setFormatter(streamlit_formatter)
streamlit_logger.addHandler(streamlit_handler)
streamlit_logger.setLevel(streamlit_level.upper())
`);
const streamlitLogLevel = (
streamlitConfig?.["logger.level"] ?? "INFO"
).toString();
const streamlitLogMessageFormat =
streamlitConfig?.["logger.messageFormat"] ?? "%(asctime)s %(message)s";
const setupLoggers = pyodide.globals.get("setup_loggers");
setupLoggers(streamlitLogLevel, streamlitLogMessageFormat);
console.debug("Set the loggers");

postProgressMessage(
Expand Down

0 comments on commit 7bb74e2

Please sign in to comment.