Merge branch 'master' into path_hash_prefix

This commit is contained in:
dachshund 2013-08-13 13:40:21 -04:00
commit e86f458a2f
5 changed files with 170 additions and 36 deletions

View file

@ -12,10 +12,9 @@
See LICENSE for licensing information.
<Purpose>
A central location for all logging-related configuration.
This module should be imported once by the main program.
If other modules wish to incorporate 'tuf' logging, they
should do the following:
A central location for all logging-related configuration. This module should
be imported once by the main program. If other modules wish to incorporate
'tuf' logging, they should do the following:
import logging
logger = logging.getLogger('tuf')
@ -26,18 +25,28 @@
instance. In this 'log.py' module, we perform the initial setup for the name
'tuf'. The 'log.py' module should only be imported once by the main program.
When any other module does a logging.getLogger('tuf'), it is referring to the
same 'tuf' instance and its associated settings we set up here in 'log.py'.
See http://docs.python.org/library/logging.html#logger-objects
for more information.
same 'tuf' instance, and its associated settings, set here in 'log.py'.
See http://docs.python.org/library/logging.html#logger-objects for more
information.
We use multiple handlers to process log messages in various ways and to
configure each one independently. Instead of using one single manner of
processing log messages, we can use two built-in handlers that have already
been configured for us. For example, the built-in FileHandler will catch
log message and dump them to a file. If we wanted, we could set this file
handler to only catch CRITICAL (and greater) messages and save them to a
file. The other stream handler would still handle DEBUG-level (and greater)
messages.
log messages and dump them to a file. If we wanted, we could set this file
handler to only catch CRITICAL (and greater) messages and save them to a
file. Other handlers (e.g., StreamHandler) could handle INFO-level
(and greater) messages.
Logging Levels:
--Level-- --Value--
logging.CRITICAL 50
logging.ERROR 40
logging.WARNING 30
logging.INFO 20
logging.DEBUG 10
logging.NOTSET 0
"""
@ -45,35 +54,46 @@
import logging
import time
import tuf
_DEFAULT_LOG_LEVEL = logging.INFO
# Setting a handler's log level filters only logging messages of that level
# (and above). For example, setting the built-in StreamHandler's log level to
# 'logging.WARNING' will cause the stream handler to only process messages
# of levels: WARNING, ERROR, and CRITICAL.
_DEFAULT_LOG_FILENAME = 'tuf.log'
_DEFAULT_LOG_LEVEL = logging.DEBUG
_DEFAULT_CONSOLE_LOG_LEVEL = logging.INFO
_DEFAULT_FILE_LOG_LEVEL = logging.DEBUG
# Set the format for logging messages.
# Example format for '_FORMAT_STRING':
# [2013-08-13 15:21:18,068 UTC] [tuf] [INFO][_update_metadata:851@updater.py]
_FORMAT_STRING = '[%(asctime)s UTC] [%(name)s] [%(levelname)s]'+\
'[%(funcName)s:%(lineno)s@%(filename)s] %(message)s'
logging.Formatter.converter = time.gmtime
formatter = logging.Formatter(_FORMAT_STRING)
# Set the handlers for the logger.
# The built-in stream handler will log
# messages to 'sys.stderr' and capture
# '_DEFAULT_LOG_LEVEL' messages.
stream_handler = logging.StreamHandler()
stream_handler.setLevel(_DEFAULT_LOG_LEVEL)
stream_handler.setFormatter(formatter)
# Set the handlers for the logger. The console handler is unset by default. A
# module importing 'log.py' should explicitly set the console handler if
# outputting log messages to the screen is needed. Adding a console handler
# can be done with tuf.log.add_console_handler(). Logging messages to a file
# *is* set by default.
console_handler = None
# Set the built-in file handler. Messages
# will be logged to '_DEFAULT_LOG_FILENAME'
# and use the logger's default log level.
# The file will be opened in append mode.
# Set the built-in file handler. Messages will be logged to
# '_DEFAULT_LOG_FILENAME', and only those messages with a log level of
# '_DEFAULT_LOG_LEVEL'. The log level of messages handled by 'file_handler'
# may be modified with 'set_filehandler_log_level()'. '_DEFAULT_LOG_FILENAME'
# will be opened in append mode.
file_handler = logging.FileHandler(_DEFAULT_LOG_FILENAME)
file_handler.setLevel(_DEFAULT_LOG_LEVEL)
file_handler.setFormatter(formatter)
# Set the logger and its settings.
logger = logging.getLogger('tuf')
logger.setLevel(_DEFAULT_LOG_LEVEL)
logger.addHandler(stream_handler)
logger.addHandler(file_handler)
# Silently ignore logger exceptions.
@ -83,27 +103,132 @@
def set_log_level(log_level):
def set_log_level(log_level=_DEFAULT_LOG_LEVEL):
"""
<Purpose>
Allow the default log level to be overridden.
<Arguments>
log_level:
The log level to set for the logger and handler(s).
E.g., logging.INFO; logging.CRITICAL.
The log level to set for the 'log.py' file handler.
'log_level' examples: logging.INFO; logging.CRITICAL.
<Exceptions>
None.
<Side Effects>
Overrides the logging level for the internal
'logger' and 'handler'.
Overrides the logging level for the 'log.py' file handler.
<Returns>
None.
"""
# Does 'log_level' have the correct format?
# Raise 'tuf.FormatError' if there is a mismatch.
tuf.formats.LENGTH_SCHEMA.check_match(log_level)
logger.setLevel(log_level)
stream_handler.setLevel(log_level)
def set_filehandler_log_level(log_level=_DEFAULT_FILE_LOG_LEVEL):
"""
<Purpose>
Allow the default file handler log level to be overridden.
<Arguments>
log_level:
The log level to set for the 'log.py' file handler.
'log_level' examples: logging.INFO; logging.CRITICAL.
<Exceptions>
None.
<Side Effects>
Overrides the logging level for the 'log.py' file handler.
<Returns>
None.
"""
# Does 'log_level' have the correct format?
# Raise 'tuf.FormatError' if there is a mismatch.
tuf.formats.LENGTH_SCHEMA.check_match(log_level)
file_handler.setLevel(log_level)
def set_console_log_level(log_level=_DEFAULT_CONSOLE_LOG_LEVEL):
"""
<Purpose>
Allow the default log level for console messages to be overridden.
<Arguments>
log_level:
The log level to set for the console handler.
'log_level' examples: logging.INFO; logging.CRITICAL.
<Exceptions>
tuf.Error, if the 'log.py' console handler has not been set yet with
add_console_handler().
<Side Effects>
Overrides the logging level for the console handler.
<Returns>
None.
"""
# Does 'log_level' have the correct format?
# Raise 'tuf.FormatError' if there is a mismatch.
tuf.formats.LENGTH_SCHEMA.check_match(log_level)
if console_handler is not None:
console_handler.setLevel(log_level)
else:
message = 'The console handler has not been set with add_console_handler().'
raise tuf.Error(message)
def add_console_handler(log_level=_DEFAULT_CONSOLE_LOG_LEVEL):
"""
<Purpose>
Add a console handler and set its log level to 'log_level'.
<Arguments>
log_level:
The log level to set for the console handler.
'log_level' examples: logging.INFO; logging.CRITICAL.
<Exceptions>
None.
<Side Effects>
Adds a console handler to the 'log.py' logger and sets its logging level to
'log_level'.
<Returns>
None.
"""
# Does 'log_level' have the correct format?
# Raise 'tuf.FormatError' if there is a mismatch.
tuf.formats.LENGTH_SCHEMA.check_match(log_level)
# Set the console handler for the logger. The built-in console handler will
# log messages to 'sys.stderr' and capture 'log_level' messages.
console_handler = logging.StreamHandler()
console_handler.setLevel(log_level)
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)

View file

@ -147,7 +147,7 @@ def load_keystore_from_keyfiles(directory_name, keyids, passwords):
<Arguments>
directory_name:
The name of the directory containing the key files ('<keyid>.key'),
conformant to tuf.formats.RELPATH_SCHEMA.
conformant to 'tuf.formats.RELPATH_SCHEMA'.
keyids:
A list containing the keyids of the signing keys to load.
@ -188,10 +188,8 @@ def load_keystore_from_keyfiles(directory_name, keyids, passwords):
logger.info('Loading private key(s) from '+repr(directory_name))
# Make sure the directory exists.
if not os.path.exists(directory_name):
logger.warn('...no such directory. Keystore cannot be loaded.')
else:
# Load the private key(s) if 'directory_name' exists, otherwise log a warning.
if os.path.exists(directory_name):
# Decrypt the keys we can from those stored in 'keyids'.
for keyid in keyids:
try:
@ -243,7 +241,11 @@ def load_keystore_from_keyfiles(directory_name, keyids, passwords):
logger.warn(repr(full_filepath)+' contains an invalid key type.')
continue
else:
logger.warn('...no such directory. Keystore cannot be loaded.')
logger.info('Done.')
return loaded_keys

View file

@ -19,12 +19,19 @@
import unittest
import shutil
import os
import logging
import tuf.repo.keystore
import tuf.rsa_key
import tuf.formats
import tuf.util
logger = logging.getLogger('tuf')
# Disable all logging calls of level CRITICAL and below.
# Comment the line below to enable logging.
logging.disable(logging.CRITICAL)
# We'll need json module for testing '_encrypt()' and '_decrypt()'
# internal function.
json = tuf.util.import_json()

0
tuf/tests/test_push.py Normal file → Executable file
View file

0
tuf/tests/test_pushtoolslib.py Normal file → Executable file
View file