-
Notifications
You must be signed in to change notification settings - Fork 3
/
log.py
98 lines (87 loc) · 3.13 KB
/
log.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
from nose.tools import set_trace
import datetime
import logging
import json
import os
import socket
from config import Configuration
from StringIO import StringIO
if not Configuration.instance:
Configuration.load()
DEFAULT_DATA_FORMAT = "%(asctime)s:%(name)s:%(levelname)s:%(filename)s:%(message)s"
class JSONFormatter(logging.Formatter):
hostname = socket.gethostname()
fqdn = socket.getfqdn()
if len(fqdn) > len(hostname):
hostname = fqdn
def format(self, record):
try:
message = record.msg % record.args
except TypeError, e:
if record.args:
raise e
else:
message = record.msg
data = dict(
host=self.hostname,
app="simplified",
name=record.name,
level=record.levelname,
filename=record.filename,
message=message,
timestamp=datetime.datetime.utcnow().isoformat()
)
if record.exc_info:
data['traceback'] = self.formatException(record.exc_info)
return json.dumps(data)
class UTF8Formatter(logging.Formatter):
"""Encode all Unicode output to UTF-8 to prevent encoding errors."""
def format(self, record):
try:
data = super(UTF8Formatter, self).format(record)
except Exception, e:
data = super(UTF8Formatter, self).format(record)
if isinstance(data, unicode):
data = data.encode("utf8")
return data
class LogglyAPI(object):
@classmethod
def handler(cls, log_level):
integration = Configuration.integration('loggly', required=True)
token = integration['token']
url = integration['url'] % dict(token=token)
from loggly.handlers import HTTPSHandler
return HTTPSHandler(url)
def set_formatter(handler, output_type=None, data_format=None):
log_config = Configuration.logging_policy()
if not output_type:
output_type = log_config.get(Configuration.LOG_OUTPUT_TYPE, 'text')
if not data_format:
data_format = log_config.get(Configuration.LOG_DATA_FORMAT, DEFAULT_DATA_FORMAT)
if output_type in ('json', 'loggly'):
cls = JSONFormatter
else:
cls = UTF8Formatter
handler.setFormatter(cls(data_format))
return handler
log_config = Configuration.logging_policy()
logger = logging.getLogger()
if os.environ.get('TESTING'):
log_level = 'DEBUG'
output_type = 'text'
else:
log_level = log_config.get(Configuration.LOG_LEVEL, 'INFO').upper()
output_type = log_config.get(Configuration.LOG_OUTPUT_TYPE, 'text').lower()
if output_type == 'loggly':
logging.getLogger().addHandler(LogglyAPI.handler(log_level))
stderr_handler = logging.StreamHandler()
logging.getLogger().addHandler(stderr_handler)
logger.setLevel(log_level)
for handler in logger.handlers:
set_formatter(handler, output_type)
database_log_level = log_config.get(Configuration.DATABASE_LOG_LEVEL, 'WARN')
for logger in (
'sqlalchemy.engine', 'elasticsearch',
'requests.packages.urllib3.connectionpool'
):
logging.getLogger(logger).setLevel(database_log_level)