-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathmongo_log_handlers.py
executable file
·123 lines (108 loc) · 4.48 KB
/
mongo_log_handlers.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
from bson.timestamp import Timestamp
from pymongo import MongoClient as Connection
from pymongo.errors import AutoReconnect
from settings_ctp import log_database,log_collection
import logging
mongo_server = 'localhost'
"""
Example format of generated bson document:
{
'thread': -1216977216,
'level': 'ERROR',
'timestamp': Timestamp(1290895671, 63),
'message': 'test message',
'fileName': '/var/projects/python/log4mongo-python/tests/test_mongo_handler.py',
'lineNumber': 38,
'method': 'test_emit_exception',
'loggerName': 'testLogger',
'exception': {
'stackTrace': 'Traceback (most recent call last):
File "/var/projects/python/log4mongo-python/tests/test_mongo_handler.py", line 36, in test_emit_exception
raise Exception(\'exc1\')
Exception: exc1',
'message': 'exc1',
'code': 0
}
}
"""
logging.LogRecord
class MongoFormatter(logging.Formatter):
DEFAULT_PROPERTIES = logging.LogRecord('', '', '', '','', '', '', '').__dict__.keys()
def format(self, record):
"""Formats LogRecord into python dictionary."""
# Standard document
document = {
'timestamp': Timestamp(int(record.created)+8*3600, int(record.msecs)),
'level': record.levelname,
'thread': record.thread,
'message': record.getMessage(),
'loggerName': record.name,
'fileName': record.pathname,
'method': record.funcName,
'lineNumber': record.lineno
}
# Standard document decorated with exception info
if record.exc_info is not None:
document.update({
'exception': {
'message': str(record.exc_info[1]),
'code': 0,
'stackTrace': self.formatException(record.exc_info)
}
})
# Standard document decorated with extra contextual information
if len(self.DEFAULT_PROPERTIES) != len(record.__dict__):
contextual_extra = set(record.__dict__).difference(set(self.DEFAULT_PROPERTIES))
if contextual_extra:
for key in contextual_extra:
document[key] = record.__dict__[key]
return document
class MongoHandler(logging.Handler):
def __init__(self, level=logging.NOTSET, host=mongo_server, port=27017, database_name=log_database, collection=log_collection,
username=None, password=None, fail_silently=False, formatter=None):
"""Setting up mongo handler, initializing mongo database connection via pymongo."""
logging.Handler.__init__(self, level)
self.host = host
self.port = port
self.database_name = database_name
self.collection_name = collection
self.username = username
self.password = password
self.fail_silently = fail_silently
self.connection = None
self.db = None
self.collection = None
self.authenticated = False
self.formatter = formatter or MongoFormatter()
self._connect()
def show(self,len=100,offset=0):
return list(self.collection.find(sort=[('timestamp',desc)],limit=len,skip=offset*len))
def _connect(self):
"""Connecting to mongo database."""
try:
self.connection = Connection(host=self.host, port=self.port)
except AutoReconnect, e:
if self.fail_silently:
return
else:
raise AutoReconnect(e)
self.db = self.connection[self.database_name]
if self.username is not None and self.password is not None:
self.authenticated = self.db.authenticate(self.username, self.password)
if self.collection_name not in self.db.collection_names():
self.db.create_collection(self.collection_name,size=512000000,capped=True,max=200)
self.collection = self.db[self.collection_name]
def close(self):
"""If authenticated, logging out and closing mongo database connection."""
if self.authenticated:
self.db.logout()
if self.connection is not None:
self.connection.close()
def emit(self, record):
"""Inserting new logging record to mongo database."""
if self.collection is not None:
try:
self.collection.save(self.format(record))
except Exception:
if not self.fail_silently:
self.handleError(record)