# 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:

1. Track device lifecycle events (connect, disconnect, query, write).
2. Record communication events in traffic managers.
3. Capture warnings and errors from validation and exception handling.
4. Provide file-based logs for troubleshooting and reproducibility.

## Setup API

```python
from plestylib.utils.logger import setup_logging

setup_logging(app_name="powermeter", level="INFO", console_print=True)
```

Function signature:

```python
setup_logging(app_name, level: str = "INFO", console_print: bool = True)
```

Parameters:

1. `app_name`: Prefix used in log filename.
2. `level`: Log level string (`DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`).
3. `console_print`: If true, logs are sent to console in addition to file.

## Output Behavior

When `setup_logging` runs:

1. Creates `logs/` in current working directory if missing.
2. Creates a timestamped log file:
	`logs/<app_name>_YYYY-MM-DD_HH-MM-SS.log`
3. Configures logging format:
	`%(asctime)s | %(levelname)s | %(name)s | %(message)s`

## Minimal Example

```python
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:

```python
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.

```python
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:

1. `DEBUG` level captures fine-grained query/write traces.
2. File logs in `logs/` preserve run history for troubleshooting.
3. Console output helps while iterating quickly.

## End User Example

Use this pattern in production-like scripts where operators mainly need status and errors.

```python
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:

1. `INFO` level keeps output readable.
2. Important status/error events are visible without debug noise.
3. File logs can be attached when reporting issues.

## Where Logs Come From

You will see logs from multiple layers, for example:

1. Base device classes: query and write operations.
2. Traffic managers: open/close/send/receive events.
3. Error handling utility: warnings and exceptions.
4. TCP server/client service components.

## Notes and Caveats

1. `logging.basicConfig` is process-global and typically only applies once.
2. If logging was configured earlier (by your app or tests), calling `setup_logging` later may not replace existing handlers.
3. Log file path is relative to the process current working directory.

## Recommended Practices

1. Call `setup_logging` at entry point (`__main__`, service launcher, test harness).
2. Use `DEBUG` only when diagnosing issues; use `INFO` for normal runs.
3. Keep `console_print=True` for interactive sessions.
4. Keep `console_print=False` for long-running services if console output is noisy.
5. Include clear device IDs/addresses in your own log messages for traceability.
