Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove secrets from logs #518

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions datadog/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import logging
import os
import os.path
import sys

# datadog
from datadog import api
Expand All @@ -26,8 +27,46 @@

__version__ = get_version()


def _replace_secrets(msg):
for secret in [api._api_key, api._application_key]:
if secret is not None:
msg = msg.replace(secret, "<SECRET>")
return msg


class WrapSecretFormatter(object):

def __init__(self, formatter):
self.formatter = formatter

def format(self, record):
return _replace_secrets(self.formatter.format(record))

def __getattr__(self, attr):
return getattr(self.formatter, attr)


class SecretFormatter(logging.Formatter):

def format(self, record):
return _replace_secrets(super(SecretFormatter, self).format(record))


_root_logger = logging.getLogger()
for h in _root_logger.handlers:
h.setFormatter(WrapSecretFormatter(h.formatter))

for logger in logging.Logger.manager.loggerDict.values():
for h in getattr(logger, 'handlers', []):
h.setFormatter(WrapSecretFormatter(h.formatter))

_secret_handler = logging.StreamHandler(stream=sys.stderr)
_secret_handler.setFormatter(SecretFormatter('%(levelname)s: %(message)s'))

# Loggers
logging.getLogger('datadog.api').addHandler(NullHandler())
logging.getLogger("datadog.dogshell").addHandler(_secret_handler)
logging.getLogger('datadog.dogstatsd').addHandler(NullHandler())
logging.getLogger('datadog.threadstats').addHandler(NullHandler())

Expand Down
24 changes: 13 additions & 11 deletions datadog/dogshell/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,29 @@
from __future__ import print_function
import os
import sys
import logging
import warnings

# datadog
from datadog.util.compat import is_p3k, configparser, IterableUserDict,\
from datadog.util.compat import configparser, IterableUserDict,\
get_input

log = logging.getLogger("datadog.dogshell")


def print_err(msg):
if is_p3k():
print(msg + '\n', file=sys.stderr)
else:
sys.stderr.write(msg + '\n')
warnings.warn("Use datadog.dogshell logger directly", warnings.DeprecationWarning, stacklevel=2)
log.error(msg)


def report_errors(res):
if 'errors' in res:
errors = res['errors']
if isinstance(errors, list):
for error in errors:
print_err("ERROR: {}".format(error))
log.error(error)
else:
print_err("ERROR: {}".format(errors))
log.error(errors)
sys.exit(1)
return False

Expand All @@ -35,9 +37,9 @@ def report_warnings(res):
warnings = res['warnings']
if isinstance(warnings, list):
for warning in warnings:
print_err("WARNING: {}".format(warning))
log.warning(warning)
else:
print_err("WARNING: {}".format(warnings))
log.warning(warnings)
return True
return False

Expand Down Expand Up @@ -79,11 +81,11 @@ def load(self, config_file, api_key, app_key):
print('Wrote %s' % config_file)
elif response.strip().lower() == 'n':
# Abort
print_err('Exiting\n')
log.info('Exiting')
sys.exit(1)
except KeyboardInterrupt:
# Abort
print_err('\nExiting')
log.info('Exiting')
sys.exit(1)

self['api_key'] = config.get('Connection', 'apikey')
Expand Down
13 changes: 6 additions & 7 deletions datadog/dogshell/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
# stdlib
import argparse
import json
import warnings

# 3p
from datadog.util.format import pretty_json

# datadog
from datadog import api
from datadog.dogshell.common import report_errors, report_warnings, print_err
from datadog.dogshell.common import log, report_errors, report_warnings


class MonitorClient(object):
Expand Down Expand Up @@ -185,19 +186,17 @@ def _update(cls, args):
if args.type:
if args.type_opt:
msg = 'Duplicate arguments for `type`. Using optional value --type'
print_err("WARNING: {}".format(msg))
log.warning(msg)
else:
to_update['type'] = args.type
msg = "[DEPRECATION] `type` is no longer required to `update` and may be omitted"
print_err("WARNING: {}".format(msg))
warnings.warn("`type` is no longer required to `update` and may be omitted", warnings.DeprecationWarning)
if args.query:
if args.query_opt:
msg = 'Duplicate arguments for `query`. Using optional value --query'
print_err("WARNING: {}".format(msg))
log.warning(msg)
else:
to_update['query'] = args.query
msg = "[DEPRECATION] `query` is no longer required to `update` and may be omitted"
print_err("WARNING: {}".format(msg))
warnings.warn("`query` is no longer required to `update` and may be omitted", warnings.DeprecationWarning)
if args.name:
to_update['name'] = args.name
if args.message:
Expand Down
4 changes: 2 additions & 2 deletions datadog/dogshell/screenboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

# datadog
from datadog import api
from datadog.dogshell.common import report_errors, report_warnings, print_err
from datadog.dogshell.common import log, report_errors, report_warnings
from datetime import datetime


Expand Down Expand Up @@ -126,7 +126,7 @@ def _push(cls, args):
res = api.Screenboard.create(**screen_obj)

if 'errors' in res:
print_err('Upload of screenboard {0} from file {1} failed.'
log.error('Upload of screenboard {0} from file {1} failed.'
.format(screen_obj["id"], f.name))

report_warnings(res)
Expand Down
4 changes: 2 additions & 2 deletions datadog/dogshell/timeboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

# datadog
from datadog import api
from datadog.dogshell.common import report_errors, report_warnings, print_err
from datadog.dogshell.common import log, report_errors, report_warnings
from datadog.util.format import pretty_json
from datetime import datetime

Expand Down Expand Up @@ -213,7 +213,7 @@ def _push(cls, args):
graphs=dash_obj["graphs"], template_variables=tpl_vars)

if 'errors' in res:
print_err('Upload of dashboard {0} from file {1} failed.'
log.error('Upload of dashboard {0} from file {1} failed.'
.format(dash_obj["id"], f.name))

report_warnings(res)
Expand Down