| 1 | """ |
|---|
| 2 | Logging functions. |
|---|
| 3 | |
|---|
| 4 | Upon import creates a module level log class (log) and |
|---|
| 5 | the following logging functions:: |
|---|
| 6 | |
|---|
| 7 | debug, info, warn and error |
|---|
| 8 | |
|---|
| 9 | The default formatters will print out the function the log was triggered from. |
|---|
| 10 | """ |
|---|
| 11 | |
|---|
| 12 | import sys, logging |
|---|
| 13 | |
|---|
| 14 | # python 2.5 logging will be differnt |
|---|
| 15 | PYTHON25 = sys.version_info >= (2, 5) |
|---|
| 16 | |
|---|
| 17 | def get_logger( name='yeti-logger', stream=sys.stdout, formatter=None): |
|---|
| 18 | """ |
|---|
| 19 | Returns a logger |
|---|
| 20 | |
|---|
| 21 | >>> disable('INFO') |
|---|
| 22 | >>> info( 'logtest, this message SHOULD NOT be visible' ) |
|---|
| 23 | >>> disable() |
|---|
| 24 | >>> info( 'logtest, this message should be visible' ) |
|---|
| 25 | >>> disable('DEBUG') |
|---|
| 26 | >>> debug( 'logtest, this message SHOULD NOT be visible' ) |
|---|
| 27 | >>> info( 'logtest, this message should be visible' ) |
|---|
| 28 | """ |
|---|
| 29 | logp = logging.getLogger(name) |
|---|
| 30 | |
|---|
| 31 | # this is needed in case the process is |
|---|
| 32 | # forked/multithreaded; loggers exist in a global scope |
|---|
| 33 | # we don't want each import to duplocate this handler |
|---|
| 34 | if not logp.handlers: |
|---|
| 35 | console = logging.StreamHandler(stream) |
|---|
| 36 | console.setLevel(logging.DEBUG ) |
|---|
| 37 | if PYTHON25: |
|---|
| 38 | format = '%(levelname)s %(module)s.%(funcName)s: %(message)s' |
|---|
| 39 | else: |
|---|
| 40 | format = '%(levelname)s %(module)s: %(message)s' |
|---|
| 41 | |
|---|
| 42 | formatter = formatter or logging.Formatter(format) |
|---|
| 43 | console.setFormatter(formatter) |
|---|
| 44 | logp.addHandler(console) |
|---|
| 45 | logp.setLevel(logging.DEBUG) |
|---|
| 46 | return logp |
|---|
| 47 | |
|---|
| 48 | def disable( level=None ): |
|---|
| 49 | """ |
|---|
| 50 | Disables logging levels |
|---|
| 51 | Levels: DEBUG, INFO, WARNING, ERROR |
|---|
| 52 | |
|---|
| 53 | >>> disable('INFO') |
|---|
| 54 | >>> info( 'logtest, this message SHOULD NOT be visible' ) |
|---|
| 55 | """ |
|---|
| 56 | level = str(level) |
|---|
| 57 | store = dict( NOTSET=0, DEBUG=10, INFO=20, WARNING=30, ERROR=40) |
|---|
| 58 | |
|---|
| 59 | # also take numerical values |
|---|
| 60 | store['0'] = 20 |
|---|
| 61 | store['1'] = 10 |
|---|
| 62 | store['2'] = 0 |
|---|
| 63 | |
|---|
| 64 | value = store.get( level.upper(), 0) |
|---|
| 65 | logging.disable( value ) |
|---|
| 66 | |
|---|
| 67 | # populate some loggers by default |
|---|
| 68 | log = get_logger() |
|---|
| 69 | debug, info, warn, error = log.debug, log.info, log.warn, log.error |
|---|
| 70 | |
|---|
| 71 | # disable DEBUG level logging by default |
|---|
| 72 | disable('DEBUG') |
|---|
| 73 | |
|---|
| 74 | def test( verbose=0 ): |
|---|
| 75 | "Performs module level testing" |
|---|
| 76 | import doctest |
|---|
| 77 | doctest.testmod( verbose=verbose ) |
|---|
| 78 | |
|---|
| 79 | def OptionParser(usage=None): |
|---|
| 80 | "An option parser that can disable various logger levels" |
|---|
| 81 | from optparse import OptionParser |
|---|
| 82 | |
|---|
| 83 | parser = OptionParser(usage=usage) |
|---|
| 84 | |
|---|
| 85 | parser.add_option( |
|---|
| 86 | '-v', '--verbosity', action="store", |
|---|
| 87 | dest="verbosity", type="int", default=1, |
|---|
| 88 | help="sets the verbosity (0, 1) (default=1)", |
|---|
| 89 | ) |
|---|
| 90 | |
|---|
| 91 | return parser |
|---|
| 92 | |
|---|
| 93 | if __name__ == "__main__": |
|---|
| 94 | test() |
|---|
| 95 | |
|---|