diff --git a/changes/383.changed b/changes/383.changed new file mode 100644 index 00000000..a5816568 --- /dev/null +++ b/changes/383.changed @@ -0,0 +1 @@ +The pyntc rotating file handler is now opt-in via the `PYNTC_LOG_FILE` environment variable. When unset, no log file is created. When set, its value is used as the log file path, and the handler is registered only once per logger to avoid duplicate entries on repeated `get_log` calls. diff --git a/docs/user/lib_getting_started.md b/docs/user/lib_getting_started.md index 66aad79a..8d45927d 100644 --- a/docs/user/lib_getting_started.md +++ b/docs/user/lib_getting_started.md @@ -342,6 +342,23 @@ Full workflow example: >>> ``` +# Logging + +pyntc reads several environment variables to configure logging. None of them are required; all are read at runtime. + +| Variable | Description | +| --- | --- | +| `PYNTC_LOG_LEVEL` | Log level for the `pyntc` logger (e.g. `debug`, `info`, `warning`). Defaults to `info`. | +| `PYNTC_DEBUG` | When set to any non-empty value, forces the log level to `DEBUG` and switches to a more verbose log format. | +| `PYNTC_LOG_FILE` | Path to a file that pyntc should log to. When set, a `RotatingFileHandler` (2000 byte rotation) is attached to the logger using this path. When unset, no file handler is attached; log records still propagate to the root logger configured by `logging.basicConfig` (called from `pyntc.log.init` during device initialization) or by the calling application. | + +Example: + +```bash +export PYNTC_LOG_FILE=/var/log/pyntc.log +export PYNTC_LOG_LEVEL=debug +``` + #### Cisco IOS Install Mode Option New in 0.15 there is support for [Install Mode](https://content.cisco.com/chapter.sjs?uri=/searchable/chapter/c/en/us/td/docs/switches/lan/Denali_16-1/ConfigExamples_Technotes/Config_Examples/Misc/qos/m_install_vs_bundle.html.xml) upgrades. To execute this there is an option (defaults to False) to run install mode. **file_copy must be executed before install_os** diff --git a/pyntc/log.py b/pyntc/log.py index 13c57744..0fd0a566 100644 --- a/pyntc/log.py +++ b/pyntc/log.py @@ -17,6 +17,10 @@ def get_log(name=None): """Get log namespace and creates logger and rotating file handler. + A :class:`RotatingFileHandler` is attached if the ``PYNTC_LOG_FILE`` + environment variable is set, in which case its value is used as the log + file path. + Args: name (str, optional): Sublogger name. Defaults to None. @@ -24,10 +28,14 @@ def get_log(name=None): (logger): Return a logger instance in the :data:`APP` namespace. """ logger_name = f"{APP}.{name}" if name else APP - # file handler - handler = RotatingFileHandler(f"{logger_name}.log", maxBytes=2000) _logger = logging.getLogger(logger_name) - _logger.addHandler(handler) + + log_file = os.environ.get("PYNTC_LOG_FILE") + if log_file and not any( + isinstance(h, RotatingFileHandler) and getattr(h, "baseFilename", None) == os.path.abspath(log_file) + for h in _logger.handlers + ): + _logger.addHandler(RotatingFileHandler(log_file, maxBytes=2000)) return _logger