Logging System#
PlestyLib uses Python built-in logging throughout device, traffic, service, and utility layers.
Central setup helper: setup_logging in plestylib.utils.logger.
Purpose#
The logging system is used to:
Track device lifecycle events (connect, disconnect, query, write).
Record communication events in traffic managers.
Capture warnings and errors from validation and exception handling.
Provide file-based logs for troubleshooting and reproducibility.
Setup API#
from plestylib.utils.logger import setup_logging
setup_logging(app_name="powermeter", level="INFO", console_print=True)
Function signature:
setup_logging(app_name, level: str = "INFO", console_print: bool = True)
Parameters:
app_name: Prefix used in log filename.level: Log level string (DEBUG,INFO,WARNING,ERROR,CRITICAL).console_print: If true, logs are sent to console in addition to file.
Output Behavior#
When setup_logging runs:
Creates
logs/in current working directory if missing.Creates a timestamped log file:
logs/<app_name>_YYYY-MM-DD_HH-MM-SS.logConfigures logging format:
%(asctime)s | %(levelname)s | %(name)s | %(message)s
Minimal Example#
from plestylib.utils.logger import setup_logging
setup_logging(app_name="pm100d", level="DEBUG", console_print=True)
# Then run your normal device logic.
Typical Integration Pattern#
Call setup once at process startup, before creating device instances:
import logging
from plestylib.utils.logger import setup_logging
from powermeter_device import PowermeterDevice
setup_logging(app_name="powermeter_service", level="INFO", console_print=True)
with PowermeterDevice("USB0::0x1313::0x8078::P0000001::INSTR", sensor_type="S155C") as dev:
print(dev.identity())
logging.info("Connected to PM100D")
logging.debug("Debug trace for identity query complete")
Developer Example#
Use this pattern when building or debugging a new device API implementation.
import logging
from plestylib.device.base_tcp_scpi_device import BaseTCPScpiDevice
class DemoScpiDevice(BaseTCPScpiDevice):
def __init__(self, host: str, port: int):
super().__init__(host=host, port=port)
self.register_config("POWER", dtype=float, read_only=True, command="MEAS:POW")
logging.info("Initialization finished.")
def some_utility_function():
try:
# do something
logging.debug("xxx done")
except Exception as e:
logging.error(f"Error: {e}")
Why this helps developers:
DEBUGlevel captures fine-grained query/write traces.File logs in
logs/preserve run history for troubleshooting.Console output helps while iterating quickly.
End User Example#
Use this pattern in production-like scripts where operators mainly need status and errors.
import logging
from plestylib.utils.logger import setup_logging
from powermeter_device import PowermeterDevice
setup_logging(app_name="powermeter_run", level="INFO", console_print=True)
address = "USB0::0x1313::0x8078::P0000001::INSTR"
try:
with PowermeterDevice(address, sensor_type="S155C") as dev:
value = dev.query("POWER")
print(f"Power: {value}")
logging.info(f"Measured power: {value}")
except Exception as e:
logging.error(f"Measurement failed: {e}")
Why this fits end users:
INFOlevel keeps output readable.Important status/error events are visible without debug noise.
File logs can be attached when reporting issues.
Where Logs Come From#
You will see logs from multiple layers, for example:
Base device classes: query and write operations.
Traffic managers: open/close/send/receive events.
Error handling utility: warnings and exceptions.
TCP server/client service components.
Notes and Caveats#
logging.basicConfigis process-global and typically only applies once.If logging was configured earlier (by your app or tests), calling
setup_logginglater may not replace existing handlers.Log file path is relative to the process current working directory.
Recommended Practices#
Call
setup_loggingat entry point (__main__, service launcher, test harness).Use
DEBUGonly when diagnosing issues; useINFOfor normal runs.Keep
console_print=Truefor interactive sessions.Keep
console_print=Falsefor long-running services if console output is noisy.Include clear device IDs/addresses in your own log messages for traceability.