Logging¶
This tutorial shows how to enable and use structured logging in pysenxor. The library uses structlog so you get consistent, key-value log lines that are easy to filter and parse (e.g. for debugging connection, register access, or streaming).
1. Default behavior¶
When you import senxor, a standard logger is configured automatically. The default log level is WARNING, so under normal use you will not see info-level messages. This keeps the library from affecting your application’s logging when you use pysenxor as a dependency.
To see more detail (e.g. device open/close, register reads/writes, stream start/stop), enable console or file logging as below.
2. Enable console logging¶
Call setup_console_logger at the start of your script so that senxor logs are printed to the console with a readable, colored format. Pass the desired level (e.g. "INFO" or "DEBUG").
from senxor.log import setup_console_logger
from senxor import connect, list_senxor
setup_console_logger("INFO")
devices = list_senxor("serial")
if not devices:
raise ValueError("No devices found")
dev = connect(devices[0])
print(dev.get_fw_version())
dev.close()
Output (example):
2026-03-02T14:06:22+0800 [info ] init_senxor_instance name=COM4 interface='SerialInterface - COM4'
2026-03-02T14:06:22+0800 [info ] opening_senxor name=COM4
2026-03-02T14:06:22+0800 [info ] read_reg_success name=COM4 op=read addr=177 value=32 updated_fields={'GET_SINGLE_FRAME': 0, 'CONTINUOUS_STREAM': 0, 'READOUT_MODE': 0, 'NO_HEADER': 1, 'ADC_ENABLE': 0}
2026-03-02T14:06:22+0800 [info ] write_reg_success name=COM4 op=write addr=177 value=32 updated_fields={}
2026-03-02T14:06:22+0800 [info ] set_field_success name=CONTINUOUS_STREAM value=0
2026-03-02T14:06:22+0800 [info ] stop_stream_success name=COM4
2026-03-02T14:06:22+0800 [info ] read_reg_success name=COM4 op=read addr=178 value=70 updated_fields={'FW_VERSION_MAJOR': 4, 'FW_VERSION_MINOR': 6}
...
setup_console_logger(log_level="INFO", logger_name="senxor", add_logger_name=False) lets you set the level, logger name, and whether to show the logger name in each line.
3. Log levels¶
Use standard levels: "DEBUG", "INFO", "WARNING", "ERROR". Pass them as strings or use logging constants.
from senxor.log import setup_console_logger
setup_console_logger("DEBUG")
"DEBUG" gives the most detail; "INFO" is usually enough for connection and register activity.
4. Log to a file¶
Use setup_file_logger to write senxor logs to a file. You can use plain text (default) or JSON.
from senxor.log import setup_file_logger
from senxor import connect, list_senxor
setup_file_logger("senxor.log", log_level="INFO")
devices = list_senxor("serial")
if not devices:
raise ValueError("No devices found")
dev = connect(devices[0])
dev.close()
Append to an existing file:
setup_file_logger("senxor.log", file_mode="a", log_level="INFO")
JSON format (one line per event) for later analysis or ingestion:
setup_file_logger("senxor.log", log_level="INFO", json_format=True)
For log rotation or external tools that replace the file, use watch_file=True so the handler reopens the file when it changes:
setup_file_logger("senxor.log", log_level="INFO", watch_file=True)
5. Use get_logger in your own code¶
If your application also wants structured logs in the same style, use get_logger. Any keyword arguments you pass are bound to every log event (e.g. device identifier).
from senxor.log import get_logger
logger = get_logger()
logger.info("custom_event", temperature=25.3)
Output (with console logger enabled): the event and key-value pairs (e.g. temperature=25.3) appear in the same format as the library logs.
6. Multiple loggers and custom pipelines (advanced)¶
After you understand the basic get_logger usage, you can build more advanced pipelines by using different logger names. Logger names act as separate logging pipelines. The default name used inside the library is "senxor", and both setup_console_logger and setup_file_logger attach handlers to a specific logger_name. By choosing different names, you can keep library logs and application logs completely separate.
For example, send Senxor logs (WARNING and above) to the console, and application logs (INFO and above) to a file:
from senxor.log import setup_console_logger, setup_file_logger, get_logger
# Senxor logs: WARNING+ to console
setup_console_logger("WARNING", logger_name="senxor")
# Application logs: INFO+ to file
app_log = get_logger("my_app", app_name="demo")
setup_file_logger("my_app.log", log_level="INFO", logger_name="my_app")
app_log.info("app_started")
In this example, senxor_log uses the "senxor" pipeline (console), and app_log uses the "my_app" pipeline (file). The first argument to get_logger is the logger name; any keyword arguments (such as app_name="demo") are bound as extra context on each event.