make setting up logs explicit and allow us to break it down and pull the bits we want into services (bug 725828)
This commit is contained in:
Родитель
f0a62f99ec
Коммит
f2324c6148
|
@ -11,101 +11,108 @@ base_fmt = ('%(name)s:%(levelname)s %(message)s '
|
|||
error_fmt = ('%(name)s:%(levelname)s %(request_path)s %(message)s '
|
||||
':%(pathname)s:%(lineno)s')
|
||||
|
||||
formatters = {
|
||||
'debug': {
|
||||
'()': commonware.log.Formatter,
|
||||
'datefmt': '%H:%M:%S',
|
||||
'format': '%(asctime)s ' + base_fmt,
|
||||
},
|
||||
'prod': {
|
||||
'()': commonware.log.Formatter,
|
||||
'datefmt': '%H:%M:%S',
|
||||
'format': ('%s: [%%(USERNAME)s][%%(REMOTE_ADDR)s] %s'
|
||||
% (settings.SYSLOG_TAG, base_fmt)),
|
||||
},
|
||||
'prod2': {
|
||||
'()': commonware.log.Formatter,
|
||||
'datefmt': '%H:%M:%S',
|
||||
'format': ('%s: [%%(USERNAME)s][%%(REMOTE_ADDR)s] %s'
|
||||
% (settings.SYSLOG_TAG2, base_fmt)),
|
||||
},
|
||||
'error': {
|
||||
'()': commonware.log.Formatter,
|
||||
'datefmt': '%H:%M:%S',
|
||||
'format': ('%s: [%%(USERNAME)s][%%(REMOTE_ADDR)s] %s'
|
||||
% (settings.SYSLOG_TAG, error_fmt)),
|
||||
},
|
||||
}
|
||||
|
||||
handlers = {
|
||||
'console': {
|
||||
'()': logging.StreamHandler,
|
||||
'formatter': 'debug',
|
||||
},
|
||||
'syslog': {
|
||||
'class': 'lib.misc.unicode_log.UnicodeHandler',
|
||||
'facility': logging.handlers.SysLogHandler.LOG_LOCAL7,
|
||||
'formatter': 'prod',
|
||||
},
|
||||
'syslog2': {
|
||||
'class': 'lib.misc.unicode_log.UnicodeHandler',
|
||||
'facility': logging.handlers.SysLogHandler.LOG_LOCAL7,
|
||||
'formatter': 'prod2',
|
||||
},
|
||||
'null': {
|
||||
'class': 'lib.misc.admin_log.NullHandler',
|
||||
},
|
||||
'mail_admins': {
|
||||
'level': 'ERROR',
|
||||
'class': 'lib.misc.admin_log.AdminEmailHandler'
|
||||
},
|
||||
'statsd': {
|
||||
'level': 'ERROR',
|
||||
'class': 'lib.misc.admin_log.StatsdHandler',
|
||||
},
|
||||
'arecibo': {
|
||||
'level': 'ERROR',
|
||||
'class': 'lib.misc.admin_log.AreciboHandler',
|
||||
},
|
||||
'errortype_syslog': {
|
||||
'class': 'lib.misc.admin_log.ErrorSyslogHandler',
|
||||
'facility': logging.handlers.SysLogHandler.LOG_LOCAL7,
|
||||
'formatter': 'error',
|
||||
},
|
||||
}
|
||||
|
||||
loggers = {
|
||||
'z': {},
|
||||
'django.request': {
|
||||
# Note these handlers will choose what they want to emit and when.
|
||||
'handlers': ['mail_admins', 'errortype_syslog',
|
||||
'statsd', 'arecibo'],
|
||||
'level': 'ERROR',
|
||||
'propagate': True,
|
||||
},
|
||||
}
|
||||
|
||||
cfg = {
|
||||
'version': 1,
|
||||
'filters': {},
|
||||
'formatters': {
|
||||
'debug': {
|
||||
'()': commonware.log.Formatter,
|
||||
'datefmt': '%H:%M:%S',
|
||||
'format': '%(asctime)s ' + base_fmt,
|
||||
},
|
||||
'prod': {
|
||||
'()': commonware.log.Formatter,
|
||||
'datefmt': '%H:%M:%S',
|
||||
'format': ('%s: [%%(USERNAME)s][%%(REMOTE_ADDR)s] %s'
|
||||
% (settings.SYSLOG_TAG, base_fmt)),
|
||||
},
|
||||
'prod2': {
|
||||
'()': commonware.log.Formatter,
|
||||
'datefmt': '%H:%M:%S',
|
||||
'format': ('%s: [%%(USERNAME)s][%%(REMOTE_ADDR)s] %s'
|
||||
% (settings.SYSLOG_TAG2, base_fmt)),
|
||||
},
|
||||
'error': {
|
||||
'()': commonware.log.Formatter,
|
||||
'datefmt': '%H:%M:%S',
|
||||
'format': ('%s: [%%(USERNAME)s][%%(REMOTE_ADDR)s] %s'
|
||||
% (settings.SYSLOG_TAG, error_fmt)),
|
||||
},
|
||||
},
|
||||
'handlers': {
|
||||
'console': {
|
||||
'()': logging.StreamHandler,
|
||||
'formatter': 'debug',
|
||||
},
|
||||
'syslog': {
|
||||
'class': 'lib.misc.admin_log.UnicodeHandler',
|
||||
'facility': logging.handlers.SysLogHandler.LOG_LOCAL7,
|
||||
'formatter': 'prod',
|
||||
},
|
||||
'syslog2': {
|
||||
'class': 'lib.misc.admin_log.UnicodeHandler',
|
||||
'facility': logging.handlers.SysLogHandler.LOG_LOCAL7,
|
||||
'formatter': 'prod2',
|
||||
},
|
||||
'null': {
|
||||
'class': 'lib.misc.admin_log.NullHandler',
|
||||
},
|
||||
'mail_admins': {
|
||||
'level': 'ERROR',
|
||||
'class': 'lib.misc.admin_log.AdminEmailHandler'
|
||||
},
|
||||
# 'statsd': {
|
||||
# 'level': 'ERROR',
|
||||
# 'class': 'lib.misc.admin_log.StatsdHandler',
|
||||
# },
|
||||
# 'arecibo': {
|
||||
# 'level': 'ERROR',
|
||||
# 'class': 'lib.misc.admin_log.AreciboHandler',
|
||||
# },
|
||||
'errortype_syslog': {
|
||||
'class': 'lib.misc.admin_log.ErrorSyslogHandler',
|
||||
'facility': logging.handlers.SysLogHandler.LOG_LOCAL7,
|
||||
'formatter': 'error',
|
||||
},
|
||||
},
|
||||
'loggers': {
|
||||
'z': {},
|
||||
'django.request': {
|
||||
# Note these handlers will choose what they want to emit and when.
|
||||
'handlers': ['mail_admins', 'errortype_syslog'],#,
|
||||
# 'statsd', 'arecibo'],
|
||||
'level': 'ERROR',
|
||||
'propagate': True,
|
||||
},
|
||||
},
|
||||
'formatters': formatters,
|
||||
'handlers': handlers,
|
||||
'loggers': loggers,
|
||||
'root': {},
|
||||
}
|
||||
|
||||
for key, value in settings.LOGGING.items():
|
||||
cfg[key].update(value)
|
||||
|
||||
def log_configure():
|
||||
"""You have to explicitly call this to configure logging."""
|
||||
for key, value in settings.LOGGING.items():
|
||||
cfg[key].update(value)
|
||||
|
||||
USE_SYSLOG = settings.HAS_SYSLOG and not settings.DEBUG
|
||||
|
||||
|
||||
USE_SYSLOG = settings.HAS_SYSLOG and not settings.DEBUG
|
||||
if USE_SYSLOG:
|
||||
cfg['loggers']['z.timer'] = {'handlers': ['syslog2']}
|
||||
|
||||
# Set the level and handlers for all loggers.
|
||||
for logger in cfg['loggers'].values() + [cfg['root']]:
|
||||
if 'handlers' not in logger:
|
||||
logger['handlers'] = ['syslog' if USE_SYSLOG else 'console']
|
||||
if 'level' not in logger:
|
||||
logger['level'] = settings.LOG_LEVEL
|
||||
if logger is not cfg['root'] and 'propagate' not in logger:
|
||||
logger['propagate'] = False
|
||||
|
||||
if USE_SYSLOG:
|
||||
cfg['loggers']['z.timer'] = {'handlers': ['syslog2']}
|
||||
|
||||
# Set the level and handlers for all loggers.
|
||||
for logger in cfg['loggers'].values() + [cfg['root']]:
|
||||
if 'handlers' not in logger:
|
||||
logger['handlers'] = ['syslog' if USE_SYSLOG else 'console']
|
||||
if 'level' not in logger:
|
||||
logger['level'] = settings.LOG_LEVEL
|
||||
if logger is not cfg['root'] and 'propagate' not in logger:
|
||||
logger['propagate'] = False
|
||||
|
||||
dictconfig.dictConfig(cfg)
|
||||
dictconfig.dictConfig(cfg)
|
||||
|
|
|
@ -20,15 +20,14 @@ NO_EMAIL_PATTERNS = {
|
|||
}
|
||||
|
||||
import logging
|
||||
import socket
|
||||
import traceback
|
||||
|
||||
from django.conf import settings
|
||||
from django.core import mail
|
||||
|
||||
#from django_arecibo.tasks import post
|
||||
#from django_statsd.clients import statsd
|
||||
|
||||
from django_arecibo.tasks import post
|
||||
from django_statsd.clients import statsd
|
||||
from unicode_log import UnicodeHandler
|
||||
|
||||
getLogger = logging.getLogger
|
||||
|
||||
|
@ -46,30 +45,6 @@ if not logger.handlers:
|
|||
logger.addHandler(NullHandler())
|
||||
|
||||
|
||||
class UnicodeHandler(logging.handlers.SysLogHandler):
|
||||
|
||||
def emit(self, record):
|
||||
msg = self.format(record) + '\000'
|
||||
prio = '<%d>' % self.encodePriority(self.facility,
|
||||
self.mapPriority(record.levelname))
|
||||
if type(msg) is unicode:
|
||||
msg = msg.encode('utf-8')
|
||||
msg = prio + msg
|
||||
try:
|
||||
if self.unixsocket:
|
||||
try:
|
||||
self.socket.send(msg)
|
||||
except socket.error:
|
||||
self._connect_unixsocket(self.address)
|
||||
self.socket.send(msg)
|
||||
else:
|
||||
self.socket.sendto(msg, self.address)
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
raise
|
||||
except:
|
||||
self.handleError(record)
|
||||
|
||||
|
||||
class ErrorTypeHandler(logging.Handler):
|
||||
"""A base class for a logging handler that examines the error."""
|
||||
|
||||
|
@ -98,27 +73,27 @@ class ErrorTypeHandler(logging.Handler):
|
|||
pass
|
||||
|
||||
|
||||
#class StatsdHandler(ErrorTypeHandler):
|
||||
# """Send error to statsd, we'll send this every time."""
|
||||
#
|
||||
# def emit(self, record):
|
||||
# if not record.exc_info:
|
||||
# return
|
||||
#
|
||||
# statsd.incr('error.%s' % record.exc_info[0].__name__.lower())
|
||||
# self.emitted(self.__class__.__name__.lower())
|
||||
#
|
||||
#
|
||||
#class AreciboHandler(ErrorTypeHandler):
|
||||
# """Send error to Arecibo, only if we are also emailing it."""
|
||||
#
|
||||
# def emit(self, record):
|
||||
# arecibo = getattr(settings, 'ARECIBO_SERVER_URL', '')
|
||||
# if not self.should_email(record) or not arecibo:
|
||||
# return
|
||||
#
|
||||
# post(record.request, 500)
|
||||
# self.emitted(self.__class__.__name__.lower())
|
||||
class StatsdHandler(ErrorTypeHandler):
|
||||
"""Send error to statsd, we'll send this every time."""
|
||||
|
||||
def emit(self, record):
|
||||
if not record.exc_info:
|
||||
return
|
||||
|
||||
statsd.incr('error.%s' % record.exc_info[0].__name__.lower())
|
||||
self.emitted(self.__class__.__name__.lower())
|
||||
|
||||
|
||||
class AreciboHandler(ErrorTypeHandler):
|
||||
"""Send error to Arecibo, only if we are also emailing it."""
|
||||
|
||||
def emit(self, record):
|
||||
arecibo = getattr(settings, 'ARECIBO_SERVER_URL', '')
|
||||
if not self.should_email(record) or not arecibo:
|
||||
return
|
||||
|
||||
post(record.request, 500)
|
||||
self.emitted(self.__class__.__name__.lower())
|
||||
|
||||
|
||||
class ErrorSyslogHandler(UnicodeHandler, ErrorTypeHandler):
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import logging.handlers
|
||||
import socket
|
||||
|
||||
|
||||
class UnicodeHandler(logging.handlers.SysLogHandler):
|
||||
|
||||
def emit(self, record):
|
||||
msg = self.format(record) + '\000'
|
||||
prio = '<%d>' % self.encodePriority(self.facility,
|
||||
self.mapPriority(record.levelname))
|
||||
if type(msg) is unicode:
|
||||
msg = msg.encode('utf-8')
|
||||
msg = prio + msg
|
||||
try:
|
||||
if self.unixsocket:
|
||||
try:
|
||||
self.socket.send(msg)
|
||||
except socket.error:
|
||||
self._connect_unixsocket(self.address)
|
||||
self.socket.send(msg)
|
||||
else:
|
||||
self.socket.sendto(msg, self.address)
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
raise
|
||||
except:
|
||||
self.handleError(record)
|
|
@ -100,7 +100,8 @@ djcelery.setup_loader()
|
|||
|
||||
# Import for side-effect: configures our logging handlers.
|
||||
# pylint: disable-msg=W0611
|
||||
from lib import log_settings_base
|
||||
from lib.log_settings_base import log_configure
|
||||
log_configure()
|
||||
|
||||
from lib.misc import safe_signals
|
||||
safe_signals.start_the_machine()
|
||||
|
|
|
@ -15,7 +15,6 @@ from django.utils.http import urlencode
|
|||
|
||||
import settings_local as settings
|
||||
setup_environ(settings)
|
||||
from lib import log_settings_base
|
||||
# This has to be imported after the settings so statsd knows where to log to.
|
||||
from statsd import statsd
|
||||
|
||||
|
@ -25,8 +24,11 @@ except ImportError:
|
|||
from apps.versions.compare import version_int
|
||||
|
||||
from constants import base
|
||||
from utils import get_mirror, APP_GUIDS, PLATFORMS, STATUSES_PUBLIC
|
||||
from utils import (get_mirror, log_configure, APP_GUIDS, PLATFORMS,
|
||||
STATUSES_PUBLIC)
|
||||
|
||||
# Go configure the log.
|
||||
log_configure()
|
||||
|
||||
good_rdf = """<?xml version="1.0"?>
|
||||
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
from datetime import datetime, timedelta
|
||||
import dictconfig
|
||||
import logging
|
||||
import settings_local as settings
|
||||
import posixpath
|
||||
import re
|
||||
|
@ -13,7 +15,7 @@ import commonware.log
|
|||
# Pyflakes will complain about these, but they are required for setup.
|
||||
import settings_local as settings
|
||||
setup_environ(settings)
|
||||
from lib import log_settings_base
|
||||
from lib.log_settings_base import formatters, handlers, loggers
|
||||
|
||||
# Ugh. But this avoids any zamboni or django imports at all.
|
||||
# Perhaps we can import these without any problems and we can
|
||||
|
@ -83,13 +85,25 @@ def getconn():
|
|||
mypool = pool.QueuePool(getconn, max_overflow=10, pool_size=5, recycle=300)
|
||||
|
||||
|
||||
error_log = commonware.log.getLogger('z.services')
|
||||
def log_configure():
|
||||
"""You have to call this to explicity configure logging."""
|
||||
cfg = {
|
||||
'version': 1,
|
||||
'filters': {},
|
||||
'formatters': dict(prod2=formatters['prod2']),
|
||||
'handlers': dict(syslog2=handlers['syslog2']),
|
||||
'loggers': {},
|
||||
'root': {},
|
||||
}
|
||||
dictconfig.dictConfig(cfg)
|
||||
|
||||
|
||||
def log_exception(data):
|
||||
(typ, value, discard) = sys.exc_info()
|
||||
error_log = logging.getLogger('z.services')
|
||||
error_log.error(u'Type: %s, %s. Data: %s' % (typ, value, data))
|
||||
|
||||
|
||||
def log_info(data, msg):
|
||||
error_log = logging.getLogger('z.services')
|
||||
error_log.info(u'Msg: %s, Data: %s' % (msg, data))
|
||||
|
|
|
@ -4,9 +4,12 @@ import re
|
|||
from time import time
|
||||
from urlparse import parse_qsl
|
||||
|
||||
from utils import (log_exception, log_info, mypool, settings,
|
||||
from utils import (log_configure, log_exception, log_info, mypool, settings,
|
||||
CONTRIB_CHARGEBACK, CONTRIB_PURCHASE, CONTRIB_REFUND)
|
||||
|
||||
# Go configure the log.
|
||||
log_configure()
|
||||
|
||||
import jwt
|
||||
import M2Crypto
|
||||
# This has to be imported after the settings (utils).
|
||||
|
|
Загрузка…
Ссылка в новой задаче