"""Logging for the Smarter SDK.The SDK logs to the ``smarter`` logger hierarchy (``smarter.client``, ``smarter.resources...``) and,as a library should, adds no handlers unless asked to. Set ``SMARTER_LOG=info`` to log eachrequest's method, url, status and duration to stderr, or ``SMARTER_LOG=debug`` to log their bodiestoo. Or configure the ``smarter`` logger as you would any other.The Smarter platform controls its logging per module with waffle switches (ADR-011). The SDK'sequivalent is the logger hierarchy: e.g. ``logging.getLogger("smarter.client").setLevel(...)``.Api keys are never logged: see :func:`mask_secret`."""importloggingfromtypingimportOptionalROOT_LOGGER_NAME="smarter"_configured=False
[docs]defmask_secret(secret:Optional[str])->str:""" A secret, masked for logging: its last four characters. :param secret: The secret, e.g. an api key. :returns: e.g. ``****5150``, or ``None``. """ifnotsecret:return"None"return"****"+secret[-4:]iflen(secret)>8else"****"
[docs]defsetup_logging(level:Optional[str])->None:""" Log the SDK's messages to stderr, at the given level, once per process. :param level: ``debug`` or ``info``, or None to leave logging as it is. """global_configured# pylint: disable=global-statementifnotlevelor_configured:returnlogger=logging.getLogger(ROOT_LOGGER_NAME)handler=logging.StreamHandler()handler.setFormatter(logging.Formatter("[%(asctime)s - %(name)s - %(levelname)s] %(message)s"))logger.addHandler(handler)logger.setLevel(logging.DEBUGiflevel=="debug"elselogging.INFO)_configured=True