Show More
@@ -0,0 +1,69 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | ||||
|
3 | # Copyright (C) 2010-2016 RhodeCode GmbH | |||
|
4 | # | |||
|
5 | # This program is free software: you can redistribute it and/or modify | |||
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |||
|
7 | # (only), as published by the Free Software Foundation. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
14 | # You should have received a copy of the GNU Affero General Public License | |||
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
|
16 | # | |||
|
17 | # This program is dual-licensed. If you wish to learn more about the | |||
|
18 | # AppEnlight Enterprise Edition, including its added features, Support | |||
|
19 | # services, and proprietary license terms, please see | |||
|
20 | # https://rhodecode.com/licenses/ | |||
|
21 | ||||
|
22 | import json | |||
|
23 | import logging | |||
|
24 | ||||
|
25 | ignored_keys = ['args', 'asctime', 'created', 'exc_info', 'exc_text', | |||
|
26 | 'filename', 'funcName', 'levelname', 'levelno', 'lineno', | |||
|
27 | 'message', 'module', 'msecs', 'msg', 'name', 'pathname', | |||
|
28 | 'process', 'processName', 'relativeCreated', 'stack_info', | |||
|
29 | 'thread', 'threadName'] | |||
|
30 | ||||
|
31 | ||||
|
32 | class JSONFormatter(logging.Formatter): | |||
|
33 | def format(self, record): | |||
|
34 | """ | |||
|
35 | Format the specified record as text. | |||
|
36 | ||||
|
37 | The record's attribute dictionary is used as the operand to a | |||
|
38 | string formatting operation which yields the returned string. | |||
|
39 | Before formatting the dictionary, a couple of preparatory steps | |||
|
40 | are carried out. The message attribute of the record is computed | |||
|
41 | using LogRecord.getMessage(). If the formatting string uses the | |||
|
42 | time (as determined by a call to usesTime(), formatTime() is | |||
|
43 | called to format the event time. If there is exception information, | |||
|
44 | it is formatted using formatException() and appended to the message. | |||
|
45 | """ | |||
|
46 | record.message = record.getMessage() | |||
|
47 | log_dict = vars(record) | |||
|
48 | keys = [k for k in log_dict.keys() if k not in ignored_keys] | |||
|
49 | payload = {'message': record.message} | |||
|
50 | payload.update({k: log_dict[k] for k in keys}) | |||
|
51 | record.message = json.dumps(payload, default=lambda x: str(x)) | |||
|
52 | ||||
|
53 | if self.usesTime(): | |||
|
54 | record.asctime = self.formatTime(record, self.datefmt) | |||
|
55 | s = self.formatMessage(record) | |||
|
56 | if record.exc_info: | |||
|
57 | # Cache the traceback text to avoid converting it multiple times | |||
|
58 | # (it's constant anyway) | |||
|
59 | if not record.exc_text: | |||
|
60 | record.exc_text = self.formatException(record.exc_info) | |||
|
61 | if record.exc_text: | |||
|
62 | if s[-1:] != "\n": | |||
|
63 | s = s + "\n" | |||
|
64 | s = s + record.exc_text | |||
|
65 | if record.stack_info: | |||
|
66 | if s[-1:] != "\n": | |||
|
67 | s = s + "\n" | |||
|
68 | s = s + self.formatStack(record.stack_info) | |||
|
69 | return s |
@@ -153,7 +153,7 b' keys = root, appenlight, sqlalchemy' | |||||
153 | keys = console |
|
153 | keys = console | |
154 |
|
154 | |||
155 | [formatters] |
|
155 | [formatters] | |
156 | keys = generic |
|
156 | keys = generic, json | |
157 |
|
157 | |||
158 | [logger_root] |
|
158 | [logger_root] | |
159 | level = WARN |
|
159 | level = WARN | |
@@ -176,9 +176,14 b' qualname = sqlalchemy.engine' | |||||
176 | class = StreamHandler |
|
176 | class = StreamHandler | |
177 | args = (sys.stderr,) |
|
177 | args = (sys.stderr,) | |
178 | level = NOTSET |
|
178 | level = NOTSET | |
179 |
formatter = |
|
179 | formatter = json | |
180 |
|
180 | |||
181 | [formatter_generic] |
|
181 | [formatter_generic] | |
182 | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s |
|
182 | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s | |
183 |
|
183 | |||
|
184 | # json string will land as "message" key of format string | |||
|
185 | [formatter_json] | |||
|
186 | class=appenlight.lib.logging.JSONFormatter | |||
|
187 | format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s | |||
|
188 | ||||
184 | # End logging configuration |
|
189 | # End logging configuration |
@@ -160,7 +160,7 b' keys = root, appenlight, sqlalchemy, elasticsearch' | |||||
160 | keys = console |
|
160 | keys = console | |
161 |
|
161 | |||
162 | [formatters] |
|
162 | [formatters] | |
163 | keys = generic |
|
163 | keys = generic, json | |
164 |
|
164 | |||
165 | [logger_root] |
|
165 | [logger_root] | |
166 | level = INFO |
|
166 | level = INFO | |
@@ -188,9 +188,14 b' qualname = sqlalchemy.engine' | |||||
188 | class = StreamHandler |
|
188 | class = StreamHandler | |
189 | args = (sys.stderr,) |
|
189 | args = (sys.stderr,) | |
190 | level = NOTSET |
|
190 | level = NOTSET | |
191 |
formatter = |
|
191 | formatter = json | |
192 |
|
192 | |||
193 | [formatter_generic] |
|
193 | [formatter_generic] | |
194 | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s |
|
194 | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s | |
195 |
|
195 | |||
|
196 | # json string will land as "message" key of format string | |||
|
197 | [formatter_json] | |||
|
198 | class=appenlight.lib.logging.JSONFormatter | |||
|
199 | format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s | |||
|
200 | ||||
196 | # End logging configuration |
|
201 | # End logging configuration |
@@ -146,7 +146,7 b' keys = root, appenlight, sqlalchemy, elasticsearch' | |||||
146 | keys = console |
|
146 | keys = console | |
147 |
|
147 | |||
148 | [formatters] |
|
148 | [formatters] | |
149 | keys = generic |
|
149 | keys = generic, json | |
150 |
|
150 | |||
151 | [logger_root] |
|
151 | [logger_root] | |
152 | level = INFO |
|
152 | level = INFO | |
@@ -174,9 +174,14 b' qualname = sqlalchemy.engine' | |||||
174 | class = StreamHandler |
|
174 | class = StreamHandler | |
175 | args = (sys.stderr,) |
|
175 | args = (sys.stderr,) | |
176 | level = NOTSET |
|
176 | level = NOTSET | |
177 |
formatter = |
|
177 | formatter = json | |
178 |
|
178 | |||
179 | [formatter_generic] |
|
179 | [formatter_generic] | |
180 | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s |
|
180 | format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s | |
181 |
|
181 | |||
|
182 | # json string will land as "message" key of format string | |||
|
183 | [formatter_json] | |||
|
184 | class=appenlight.lib.logging.JSONFormatter | |||
|
185 | format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s | |||
|
186 | ||||
182 | # End logging configuration |
|
187 | # End logging configuration |
General Comments 0
You need to be logged in to leave comments.
Login now