Yelp / detect-secrets

An enterprise friendly way of detecting and preventing secrets in code.
Apache License 2.0
3.82k stars 474 forks source link

Importing `detect-secrets` deletes existing logging handles #415

Open bbberard opened 3 years ago

bbberard commented 3 years ago

I'm attempting to upgrade from detect-secrets 0.14.3 to 1.0.3, but I'm encountering a new error in the handling of the Python logger. I have code that uses the style logging.info() for logging, which worked fine in 0.14.3, but does not in 1.0.3.

Since this is an import-related behavior, it's really hard to fix.

Previous Behavior

import logging

from detect_secrets.plugins.aws import AWSKeyDetector, verify_aws_secret_access_key

if __name__ == "__main__":
    print(len(logging.root.handlers)) # prints 0

    logging.basicConfig(level=logging.INFO)

    logging.info("This will print to the console properly")

Current Behavior

import logging

from detect_secrets.plugins.aws import AWSKeyDetector, verify_aws_secret_access_key

if __name__ == "__main__":
    print(len(logging.root.handlers)) # prints 1

    logging.basicConfig(level=logging.INFO)

    logging.info("This will NOT print to the console properly")
    logging.warning("This WILL print to the console properly, but with the format specified in `detect-secrets`")

Attempt # 1

The first thing I tried was to configure the logger before importing detect-secrets:

import logging

# I configure the logger here instead
logging.basicConfig(level=logging.INFO)

from detect_secrets.plugins.aws import AWSKeyDetector, verify_aws_secret_access_key

if __name__ == "__main__":
    logging.info("This will NOT print to the console properly")
    logging.warning("This WILL print to the console properly, but with the format specified in `detect-secrets`")

However, the logger I've configured is deleted/overwritten by detect-secrets.

Workaround

The only way I've been able to solve this problem for now is using the below code. I cannot simply delete the handlers because if I want to run my code in an AWS Lambda, for example, there's a pre-configured logger that I would like to continue to use.

import logging

handlers = logging.root.handlers[:]

from detect_secrets.plugins.aws import AWSKeyDetector, verify_aws_secret_access_key

logging.root.handlers = handlers

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)

    logging.info("This will print to the console properly")
domanchi commented 3 years ago

How curious. The only changes I made to detect_secrets.core.log during the upgrade is to add type hints. I agree that our logging infrastructure should be fixed (this is a great case, thanks for the examples), but I actually don't know of any good Python logging patterns for packages.

Pull requests welcome, or any good patterns you've observed in the wild.