logging: update ubuntutools.getLogger() to output to stdout/stderr correctly

Python logging by default sends all output to stderr, but that's not what
normal programs usually do and is not expected for these scripts.

Change the ubuntutools.getLogger() method to return a logger with handlers
correctly set up to send INFO level (or lower) logs to stdout and WARNING
level (or higher; technically INFO+1 level or higher) logs to stderr.

This results in normally logged output going to stdout and warnings/errors
going to stderr, as expected.
This commit is contained in:
Dan Streetman 2021-02-01 18:26:13 -05:00
parent b35712fa40
commit 0eeb93ee0c
20 changed files with 65 additions and 31 deletions

View File

@ -42,7 +42,7 @@ from ubuntutools.misc import (system_distribution, vendor_to_distroinfo,
from ubuntutools.question import YesNoQuestion
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
def error(msg):

View File

@ -30,7 +30,7 @@ from launchpadlib.errors import HTTPError
from ubuntutools.config import UDTConfig
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
def error_out(msg):

View File

@ -28,7 +28,7 @@ from httplib2 import Http, HttpLib2Error
import ubuntutools.misc
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
def main():

View File

@ -37,7 +37,7 @@ from launchpadlib.launchpad import Launchpad
from ubuntutools.lp.libsupport import translate_web_api
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
def check_args():

View File

@ -33,7 +33,7 @@ from launchpadlib.launchpad import Launchpad
from ubuntutools.config import UDTConfig
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
def main():

View File

@ -23,7 +23,7 @@ import sys
from debian.changelog import Changelog
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
def usage(exit_code=1):

View File

@ -44,7 +44,7 @@ from ubuntutools.config import UDTConfig
from ubuntutools.question import YesNoQuestion
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
class PbuilderDist(object):

View File

@ -27,7 +27,7 @@ from ubuntutools.config import UDTConfig
from ubuntutools.version import Version
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
def previous_version(package, version, distance):

View File

@ -30,7 +30,7 @@ from ubuntutools.question import (YesNoQuestion, EditBugReport,
from ubuntutools.rdepends import query_rdepends, RDependsException
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
class DestinationException(Exception):

View File

@ -39,7 +39,7 @@ from ubuntutools.question import confirmation_prompt, EditBugReport
from ubuntutools.version import Version
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
#
# entry point

View File

@ -24,7 +24,7 @@ from ubuntutools.misc import (system_distribution, vendor_to_distroinfo,
from ubuntutools.rdepends import query_rdepends, RDependsException
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
DEFAULT_MAX_DEPTH = 10 # We want avoid any infinite loop...

View File

@ -26,7 +26,7 @@ from ubuntutools.lp.lpapicache import (Distribution, Launchpad,
PackageNotFoundException)
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
DATA_URL = 'http://qa.ubuntuwire.org/ubuntu-seeded-packages/seeded.json.gz'

View File

@ -26,7 +26,7 @@ from ubuntutools.config import UDTConfig
from ubuntutools.sponsor_patch.sponsor_patch import sponsor_patch, check_dependencies
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
def parse(script_name):

View File

@ -40,7 +40,7 @@ from ubuntutools.question import YesNoQuestion, EditFile
from ubuntutools.update_maintainer import update_maintainer, restore_maintainer
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
def get_most_recent_debian_version(changelog):

View File

@ -46,7 +46,7 @@ from ubuntutools.requestsync.lp import get_debian_srcpkg, get_ubuntu_srcpkg
from ubuntutools.version import Version
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
def remove_signature(dscname):

View File

@ -33,7 +33,7 @@ from ubuntutools.lp.lpapicache import Distribution, PersonTeam
from ubuntutools.misc import split_release_pocket
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
def main():

View File

@ -25,7 +25,7 @@ import subprocess
import sys
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
def extract(iso, path):

View File

@ -23,7 +23,7 @@ from ubuntutools.lp.lpapicache import (Launchpad, Distribution, PersonTeam,
from ubuntutools.misc import split_release_pocket
from ubuntutools import getLogger
Logger = getLogger(__name__)
Logger = getLogger()
def parse_arguments():

View File

@ -4,18 +4,50 @@
# https://launchpad.net/ubuntu-dev-tools
import logging
import sys
def _loggingBasicConfig(**kwargs):
'''Set log level to INFO and define log format to use.'''
if 'level' not in kwargs:
kwargs['level'] = logging.INFO
if 'format' not in kwargs:
kwargs['format'] = '%(message)s'
logging.basicConfig(**kwargs)
def getLogger():
''' Get the logger instance for this module
Quick guide for using this or not: if you want to call ubuntutools
module code and have its output print to stdout/stderr ONLY, you can
use the logger this creates. You can also log directly to this logger
from your own code to send output to stdout/stderr.
def getLogger(name=None):
'''Get standard Python logging.Logger with some ubuntutools defaults.'''
_loggingBasicConfig()
return logging.getLogger(name)
This creates the ubuntutools module-level logger, and sets some default
values for formatting and levels, and directs INFO-level logs messages to
stdout and logs higher than INFO to stderr. The logger's level may be
adjusted to show more logs (e.g. DEBUG) or less (e.g. WARNING, to suppress
all INFO messages).
Without calling this module, the ubuntutools logs will propagate up to
higher level loggers (possibly the root logger) and be handled by them.
Note that the default for python logging is to print WARNING and above
logs to stderr.
Note if any code calls this method, the ubuntutools module-level logger
will no longer propagate ubuntutools log message up to higher level
loggers.
This should only be used by runnable scripts provided by the
ubuntu-dev-tools package, or other runnable scripts that want the behavior
described above.
'''
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.propagate = False
fmt = logging.Formatter('%(message)s')
stdout_handler = logging.StreamHandler(stream=sys.stdout)
stdout_handler.setFormatter(fmt)
stdout_handler.addFilter(lambda r: r.levelno <= logging.INFO)
logger.addHandler(stdout_handler)
stderr_handler = logging.StreamHandler(stream=sys.stderr)
stdout_handler.setFormatter(fmt)
stderr_handler.setLevel(logging.INFO+1)
logger.addHandler(stderr_handler)
return logger

View File

@ -49,8 +49,10 @@ from ubuntutools.misc import (split_release_pocket,
UPLOAD_QUEUE_STATUSES,
STATUSES)
from ubuntutools import _loggingBasicConfig
# by default we use standard logging.getLogger() and only use
# ubuntutools.getLogger() in PullPkg().main()
from ubuntutools import getLogger as ubuntutools_getLogger
import logging
Logger = logging.getLogger(__name__)
@ -98,7 +100,7 @@ class PullPkg(object):
unexpected errors will flow up to the caller.
On success, this simply returns.
"""
_loggingBasicConfig()
Logger = ubuntutools_getLogger()
try:
cls(*args, **kwargs).pull()