2013-06-29 18:27:40 +02:00
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
'''
|
|
|
|
|
Logging and debuging facility
|
|
|
|
|
=============================
|
|
|
|
|
|
|
|
|
|
Levels:
|
|
|
|
|
DEBUG Detailed information, typically of interest only when diagnosing problems.
|
|
|
|
|
INFO Confirmation that things are working as expected.
|
|
|
|
|
WARNING An indication that something unexpected happened, or indicative of some problem in the
|
|
|
|
|
near future (e.g. ‘disk space low’). The software is still working as expected.
|
|
|
|
|
ERROR Due to a more serious problem, the software has not been able to perform some function.
|
|
|
|
|
CRITICAL A serious error, indicating that the program itself may be unable to continue running.
|
|
|
|
|
|
|
|
|
|
There are three loggers: `console_only`, `file_only` and `both`.
|
|
|
|
|
|
|
|
|
|
Use: `from debug import logger` to import this facility into whatever module you wish to log messages from.
|
|
|
|
|
Logging is thread-safe so you don't have to worry about locks, just import and log.
|
|
|
|
|
'''
|
|
|
|
|
import logging
|
|
|
|
|
import logging.config
|
2015-11-18 16:22:17 +01:00
|
|
|
|
import os
|
2014-04-19 20:45:37 +02:00
|
|
|
|
import sys
|
2015-11-18 16:22:17 +01:00
|
|
|
|
import traceback
|
2014-10-13 07:59:16 +02:00
|
|
|
|
import helper_startup
|
2017-01-11 17:00:00 +01:00
|
|
|
|
import state
|
2014-10-13 07:59:16 +02:00
|
|
|
|
helper_startup.loadConfig()
|
2013-06-29 18:27:40 +02:00
|
|
|
|
|
2016-04-30 12:45:01 +02:00
|
|
|
|
# Now can be overriden from a config file, which uses standard python logging.config.fileConfig interface
|
|
|
|
|
# examples are here: https://bitmessage.org/forum/index.php/topic,4820.msg11163.html#msg11163
|
|
|
|
|
log_level = 'WARNING'
|
2013-06-29 18:27:40 +02:00
|
|
|
|
|
2015-11-18 16:22:17 +01:00
|
|
|
|
def log_uncaught_exceptions(ex_cls, ex, tb):
|
|
|
|
|
logging.critical(''.join(traceback.format_tb(tb)))
|
|
|
|
|
logging.critical('{0}: {1}'.format(ex_cls, ex))
|
|
|
|
|
|
2013-07-15 21:45:03 +02:00
|
|
|
|
def configureLogging():
|
2015-11-18 16:22:17 +01:00
|
|
|
|
have_logging = False
|
|
|
|
|
try:
|
2017-01-11 17:00:00 +01:00
|
|
|
|
logging.config.fileConfig(os.path.join (state.appdata, 'logging.dat'))
|
2015-11-18 16:22:17 +01:00
|
|
|
|
have_logging = True
|
2017-01-11 17:00:00 +01:00
|
|
|
|
print "Loaded logger configuration from %s" % (os.path.join(state.appdata, 'logging.dat'))
|
2015-11-18 16:22:17 +01:00
|
|
|
|
except:
|
2017-01-11 17:00:00 +01:00
|
|
|
|
if os.path.isfile(os.path.join(state.appdata, 'logging.dat')):
|
|
|
|
|
print "Failed to load logger configuration from %s, using default logging config" % (os.path.join(state.appdata, 'logging.dat'))
|
2016-08-29 05:56:21 +02:00
|
|
|
|
print sys.exc_info()
|
|
|
|
|
else:
|
|
|
|
|
# no need to confuse the user if the logger config is missing entirely
|
|
|
|
|
print "Using default logger configuration"
|
2015-11-18 16:22:17 +01:00
|
|
|
|
|
|
|
|
|
sys.excepthook = log_uncaught_exceptions
|
|
|
|
|
|
|
|
|
|
if have_logging:
|
|
|
|
|
return False
|
|
|
|
|
|
2013-07-15 21:45:03 +02:00
|
|
|
|
logging.config.dictConfig({
|
|
|
|
|
'version': 1,
|
|
|
|
|
'formatters': {
|
|
|
|
|
'default': {
|
|
|
|
|
'format': '%(asctime)s - %(levelname)s - %(message)s',
|
|
|
|
|
},
|
2013-06-29 18:27:40 +02:00
|
|
|
|
},
|
2013-07-15 21:45:03 +02:00
|
|
|
|
'handlers': {
|
|
|
|
|
'console': {
|
|
|
|
|
'class': 'logging.StreamHandler',
|
|
|
|
|
'formatter': 'default',
|
|
|
|
|
'level': log_level,
|
2017-09-22 23:59:14 +02:00
|
|
|
|
'stream': 'ext://sys.stderr'
|
2013-07-15 21:45:03 +02:00
|
|
|
|
},
|
|
|
|
|
'file': {
|
|
|
|
|
'class': 'logging.handlers.RotatingFileHandler',
|
|
|
|
|
'formatter': 'default',
|
|
|
|
|
'level': log_level,
|
2017-01-11 17:00:00 +01:00
|
|
|
|
'filename': state.appdata + 'debug.log',
|
2013-07-15 21:45:03 +02:00
|
|
|
|
'maxBytes': 2097152, # 2 MiB
|
|
|
|
|
'backupCount': 1,
|
2016-12-06 16:15:37 +01:00
|
|
|
|
'encoding': 'UTF-8',
|
2013-07-15 21:45:03 +02:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
'loggers': {
|
|
|
|
|
'console_only': {
|
|
|
|
|
'handlers': ['console'],
|
|
|
|
|
'propagate' : 0
|
|
|
|
|
},
|
|
|
|
|
'file_only': {
|
|
|
|
|
'handlers': ['file'],
|
|
|
|
|
'propagate' : 0
|
|
|
|
|
},
|
|
|
|
|
'both': {
|
|
|
|
|
'handlers': ['console', 'file'],
|
|
|
|
|
'propagate' : 0
|
|
|
|
|
},
|
2013-06-29 18:27:40 +02:00
|
|
|
|
},
|
2013-07-15 21:45:03 +02:00
|
|
|
|
'root': {
|
2013-06-29 18:27:40 +02:00
|
|
|
|
'level': log_level,
|
|
|
|
|
'handlers': ['console'],
|
|
|
|
|
},
|
2013-07-15 21:45:03 +02:00
|
|
|
|
})
|
2015-11-18 16:22:17 +01:00
|
|
|
|
return True
|
|
|
|
|
|
2013-06-29 18:27:40 +02:00
|
|
|
|
# TODO (xj9): Get from a config file.
|
2013-07-14 22:12:59 +02:00
|
|
|
|
#logger = logging.getLogger('console_only')
|
2015-11-18 16:22:17 +01:00
|
|
|
|
if configureLogging():
|
|
|
|
|
if '-c' in sys.argv:
|
|
|
|
|
logger = logging.getLogger('file_only')
|
|
|
|
|
else:
|
|
|
|
|
logger = logging.getLogger('both')
|
2014-04-19 20:45:37 +02:00
|
|
|
|
else:
|
2015-11-18 16:22:17 +01:00
|
|
|
|
logger = logging.getLogger('default')
|
2013-07-15 21:45:03 +02:00
|
|
|
|
|
|
|
|
|
def restartLoggingInUpdatedAppdataLocation():
|
|
|
|
|
global logger
|
|
|
|
|
for i in list(logger.handlers):
|
|
|
|
|
logger.removeHandler(i)
|
|
|
|
|
i.flush()
|
|
|
|
|
i.close()
|
2015-11-18 16:22:17 +01:00
|
|
|
|
if configureLogging():
|
|
|
|
|
if '-c' in sys.argv:
|
|
|
|
|
logger = logging.getLogger('file_only')
|
|
|
|
|
else:
|
|
|
|
|
logger = logging.getLogger('both')
|
2014-04-19 20:45:37 +02:00
|
|
|
|
else:
|
2015-11-18 16:22:17 +01:00
|
|
|
|
logger = logging.getLogger('default')
|
2014-04-19 20:45:37 +02:00
|
|
|
|
|