Skip to content

Commit

Permalink
properly initialize logging
Browse files Browse the repository at this point in the history
  • Loading branch information
kalefranz committed Aug 5, 2016
1 parent 84d3ea5 commit 2883eb7
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 104 deletions.
5 changes: 4 additions & 1 deletion conda/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@

import os
import sys
from conda.compat import text_type

from ._vendor.auxlib.packaging import get_version
from .common.compat import with_metaclass
from .compat import text_type
from .gateways.logging import initialize_logging

__all__ = [
"__name__", "__version__", "__author__",
Expand All @@ -30,6 +31,8 @@
if os.getenv('CONDA_ROOT') is None:
os.environ['CONDA_ROOT'] = sys.prefix

initialize_logging()


class CondaErrorType(type):
def __init__(cls, name, bases, attr):
Expand Down
2 changes: 1 addition & 1 deletion conda/_vendor/auxlib/logz.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def requests_models_Response_builder(builder, response_object):
if content_type == 'application/json':
builder.append(pformat(response_object.json, indent=2))
builder.append('')
elif content_type.startswith('text/'):
elif content_type is not None and content_type.startswith('text/'):
builder.append(response_object.text)

try:
Expand Down
2 changes: 1 addition & 1 deletion conda/base/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,4 @@ def from_sys(cls):
ROOT_ENV_NAME = 'root'

EMPTY_LIST = ()
EMPTY_MAP = frozendict(dict())
EMPTY_MAP = frozendict()
23 changes: 13 additions & 10 deletions conda/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,20 @@
conda <command> -h
'''

from __future__ import print_function, division, absolute_import
from __future__ import absolute_import, division, print_function

from argparse import SUPPRESS
import importlib
import logging
import sys
from argparse import SUPPRESS
from conda.gateways.logging import initialize_conda_logger
from logging import CRITICAL, DEBUG, Logger, getLogger

from .. import __version__
from ..base.context import context
from ..exceptions import conda_exception_handler, CommandNotFoundError
from ..exceptions import CommandNotFoundError, conda_exception_handler
from ..utils import on_win
from .. import __version__

log = getLogger(__name__)


def generate_parser():
Expand Down Expand Up @@ -82,6 +85,7 @@ def generate_parser():


def _main():
log.debug("conda.cli.main called with %s", sys.argv)
if len(sys.argv) > 1:
argv1 = sys.argv[1]
if argv1 in ('..activate', '..deactivate', '..checkenv', '..changeps1'):
Expand Down Expand Up @@ -125,13 +129,12 @@ def completer(prefix, **kwargs):

if getattr(args, 'json', False):
# Silence logging info to avoid interfering with JSON output
for logger in logging.Logger.manager.loggerDict:
for logger in Logger.manager.loggerDict:
if logger not in ('fetch', 'progress'):
logging.getLogger(logger).setLevel(logging.CRITICAL + 1)
getLogger(logger).setLevel(CRITICAL + 1)

if args.debug:
logging.disable(logging.NOTSET)
logging.basicConfig(level=logging.DEBUG)
if context.debug:
initialize_conda_logger(DEBUG)

exit_code = args.func(args, p)
if isinstance(exit_code, int):
Expand Down
33 changes: 29 additions & 4 deletions conda/common/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
import logging
import sys
from contextlib import contextmanager
from logging import getLogger, StreamHandler, Formatter
from logging import Formatter, StreamHandler, getLogger, WARN, DEBUG, CRITICAL

from .._vendor.auxlib.logz import NullHandler
from ..compat import StringIO

log = getLogger(__name__)
Expand All @@ -17,14 +18,15 @@
def captured():
class CapturedText(object):
pass
saved_stdout, saved_stderr = sys.stdout, sys.stderr
sys.stdout = outfile = StringIO()
sys.stderr = errfile = StringIO()
c = CapturedText()
try:
yield c
finally:
c.stdout, c.stderr = outfile.getvalue(), errfile.getvalue()
sys.stdout, sys.stderr = sys.__stdout__, sys.__stderr__
sys.stdout, sys.stderr = saved_stdout, saved_stderr


@contextmanager
Expand All @@ -39,14 +41,17 @@ def _logger_lock():
@contextmanager
def disable_logger(logger_name):
logr = getLogger(logger_name)
_dsbld, _prpgt = logr.disabled, logr.propagate
_hndlrs, _lvl, _dsbld, _prpgt = logr.handlers, logr.level, logr.disabled, logr.propagate
with _logger_lock():
logr.addHandler(NullHandler())
logr.setLevel(CRITICAL + 1)
logr.disabled, logr.propagate = True, False
try:
yield
finally:
with _logger_lock():
logr.disabled, logr.propagate = _dsbld, _prpgt
logr.handlers, logr.level, logr.disabled = _hndlrs, _lvl, _dsbld
logr.propagate = _prpgt


@contextmanager
Expand All @@ -68,3 +73,23 @@ def stderr_log_level(level, logger_name=None):
with _logger_lock():
logr.handlers, logr.level, logr.disabled = _hndlrs, _lvl, _dsbld
logr.propagate = _prpgt


def attach_stderr_handler(level=WARN, logger_name=None):
# get old stderr logger
logr = getLogger(logger_name)
old_stderr_handler = next((handler for handler in logr.handlers if handler.name == 'stderr'),
None)

# create new stderr logger
new_stderr_handler = StreamHandler(sys.stderr)
new_stderr_handler.name = 'stderr'
if level is not None:
new_stderr_handler.setLevel(level)
new_stderr_handler.setFormatter(_FORMATTER)

# do the switch
with _logger_lock():
if old_stderr_handler:
logr.removeHandler(old_stderr_handler)
logr.addHandler(new_stderr_handler)
2 changes: 1 addition & 1 deletion conda/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def get_binstar_token(url):
base_url = '%s://%s' % (url_parts.scheme, url_parts.netloc)
if DEFAULT_CHANNEL_ALIAS.startswith(base_url):
base_url = binstar_default_url
with disable_logger('binstar'), captured() as c:
with captured() as c:
config = get_config(remote_site=base_url)
url_from_bs_config = config.get('url', base_url)
token = load_token(url_from_bs_config)
Expand Down
3 changes: 2 additions & 1 deletion conda/fetch.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,9 +271,10 @@ def fetch_index(channel_urls, use_cache=False, unknown=False, index=None):
try:
import concurrent.futures
executor = concurrent.futures.ThreadPoolExecutor(10)
except (ImportError, RuntimeError):
except (ImportError, RuntimeError) as e:
# concurrent.futures is only available in Python >= 3.2 or if futures is installed
# RuntimeError is thrown if number of threads are limited by OS
log.debug(repr(e))
session = CondaSession()
repodatas = [(url, fetch_repodata(url, use_cache=use_cache, session=session))
for url in urls]
Expand Down
19 changes: 19 additions & 0 deletions conda/gateways/logging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals

from logging import WARN, getLogger, ERROR

from ..common.io import attach_stderr_handler

log = getLogger(__name__)


def initialize_logging():
initialize_root_logger()
initialize_conda_logger()

def initialize_root_logger(level=ERROR):
attach_stderr_handler(level)

def initialize_conda_logger(level=WARN):
attach_stderr_handler(level, 'conda')
44 changes: 10 additions & 34 deletions tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

from contextlib import contextmanager

import conda.cli as cli
from conda.compat import StringIO

expected_error_prefix = 'Using Anaconda Cloud api site https://api.anaconda.org'
Expand Down Expand Up @@ -83,42 +82,20 @@ def captured(disallow_stderr=True):
sys.stdout = outfile = StringIO()
sys.stderr = errfile = StringIO()
c = CapturedText()
yield c
c.stdout = outfile.getvalue()
c.stderr = strip_expected(errfile.getvalue())
sys.stdout = stdout
sys.stderr = stderr
if disallow_stderr and c.stderr:
raise Exception("Got stderr output: %s" % c.stderr)


def capture_with_argv(*argv):
# only used in capture_json_with_argv()
sys.argv = argv
stdout, stderr = StringIO(), StringIO()
oldstdout, oldstderr = sys.stdout, sys.stderr
sys.stdout = stdout
sys.stderr = stderr
reset_context(())
try:
cli.main()
except SystemExit:
pass
sys.stdout = oldstdout
sys.stderr = oldstderr

stdout.seek(0)
stderr.seek(0)
stdout, stderr = stdout.read(), stderr.read()

print(stdout)
print(stderr, file=sys.stderr)
return stdout, strip_expected(stderr)
yield c
finally:
c.stdout = outfile.getvalue()
c.stderr = strip_expected(errfile.getvalue())
sys.stdout = stdout
sys.stderr = stderr
if disallow_stderr and c.stderr:
raise Exception("Got stderr output: %s" % c.stderr)


def capture_json_with_argv(*argv, **kwargs):
# used in test_config (6 times), test_info (2 times), test_list (5 times), and test_search (10 times)
stdout, stderr = capture_with_argv(*argv)
stdout, stderr = run_conda_command(*argv)

if kwargs.get('relaxed'):
match = re.match('\A.*?({.*})', stdout, re.DOTALL)
Expand All @@ -129,9 +106,8 @@ def capture_json_with_argv(*argv, **kwargs):
return stderr

try:
return json.loads(stdout)
return json.loads(stdout.strip())
except ValueError:
print(str(stdout), str(stderr))
raise


Expand Down
Loading

0 comments on commit 2883eb7

Please sign in to comment.