##// END OF EJS Templates
request-tracking: use consistent lenght formatting
marcink -
r3242:e10ff237 default
parent child Browse files
Show More
@@ -1,170 +1,171 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2018 RhodeCode GmbH
3 # Copyright (C) 2010-2018 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
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
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
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/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import sys
21 import sys
22 import logging
22 import logging
23
23
24
24
25 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
25 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
26
26
27 # Sequences
27 # Sequences
28 RESET_SEQ = "\033[0m"
28 RESET_SEQ = "\033[0m"
29 COLOR_SEQ = "\033[0;%dm"
29 COLOR_SEQ = "\033[0;%dm"
30 BOLD_SEQ = "\033[1m"
30 BOLD_SEQ = "\033[1m"
31
31
32 COLORS = {
32 COLORS = {
33 'CRITICAL': MAGENTA,
33 'CRITICAL': MAGENTA,
34 'ERROR': RED,
34 'ERROR': RED,
35 'WARNING': CYAN,
35 'WARNING': CYAN,
36 'INFO': GREEN,
36 'INFO': GREEN,
37 'DEBUG': BLUE,
37 'DEBUG': BLUE,
38 'SQL': YELLOW
38 'SQL': YELLOW
39 }
39 }
40
40
41
41
42 def one_space_trim(s):
42 def one_space_trim(s):
43 if s.find(" ") == -1:
43 if s.find(" ") == -1:
44 return s
44 return s
45 else:
45 else:
46 s = s.replace(' ', ' ')
46 s = s.replace(' ', ' ')
47 return one_space_trim(s)
47 return one_space_trim(s)
48
48
49
49
50 def format_sql(sql):
50 def format_sql(sql):
51 sql = sql.replace('\n', '')
51 sql = sql.replace('\n', '')
52 sql = one_space_trim(sql)
52 sql = one_space_trim(sql)
53 sql = sql\
53 sql = sql\
54 .replace(',', ',\n\t')\
54 .replace(',', ',\n\t')\
55 .replace('SELECT', '\n\tSELECT \n\t')\
55 .replace('SELECT', '\n\tSELECT \n\t')\
56 .replace('UPDATE', '\n\tUPDATE \n\t')\
56 .replace('UPDATE', '\n\tUPDATE \n\t')\
57 .replace('DELETE', '\n\tDELETE \n\t')\
57 .replace('DELETE', '\n\tDELETE \n\t')\
58 .replace('FROM', '\n\tFROM')\
58 .replace('FROM', '\n\tFROM')\
59 .replace('ORDER BY', '\n\tORDER BY')\
59 .replace('ORDER BY', '\n\tORDER BY')\
60 .replace('LIMIT', '\n\tLIMIT')\
60 .replace('LIMIT', '\n\tLIMIT')\
61 .replace('WHERE', '\n\tWHERE')\
61 .replace('WHERE', '\n\tWHERE')\
62 .replace('AND', '\n\tAND')\
62 .replace('AND', '\n\tAND')\
63 .replace('LEFT', '\n\tLEFT')\
63 .replace('LEFT', '\n\tLEFT')\
64 .replace('INNER', '\n\tINNER')\
64 .replace('INNER', '\n\tINNER')\
65 .replace('INSERT', '\n\tINSERT')\
65 .replace('INSERT', '\n\tINSERT')\
66 .replace('DELETE', '\n\tDELETE')
66 .replace('DELETE', '\n\tDELETE')
67 return sql
67 return sql
68
68
69
69
70 class ExceptionAwareFormatter(logging.Formatter):
70 class ExceptionAwareFormatter(logging.Formatter):
71 """
71 """
72 Extended logging formatter which prints out remote tracebacks.
72 Extended logging formatter which prints out remote tracebacks.
73 """
73 """
74
74
75 def formatException(self, ei):
75 def formatException(self, ei):
76 ex_type, ex_value, ex_tb = ei
76 ex_type, ex_value, ex_tb = ei
77
77
78 local_tb = logging.Formatter.formatException(self, ei)
78 local_tb = logging.Formatter.formatException(self, ei)
79 if hasattr(ex_value, '_vcs_server_traceback'):
79 if hasattr(ex_value, '_vcs_server_traceback'):
80
80
81 def formatRemoteTraceback(remote_tb_lines):
81 def formatRemoteTraceback(remote_tb_lines):
82 result = ["\n +--- This exception occured remotely on VCSServer - Remote traceback:\n\n"]
82 result = ["\n +--- This exception occured remotely on VCSServer - Remote traceback:\n\n"]
83 result.append(remote_tb_lines)
83 result.append(remote_tb_lines)
84 result.append("\n +--- End of remote traceback\n")
84 result.append("\n +--- End of remote traceback\n")
85 return result
85 return result
86
86
87 try:
87 try:
88 if ex_type is not None and ex_value is None and ex_tb is None:
88 if ex_type is not None and ex_value is None and ex_tb is None:
89 # possible old (3.x) call syntax where caller is only
89 # possible old (3.x) call syntax where caller is only
90 # providing exception object
90 # providing exception object
91 if type(ex_type) is not type:
91 if type(ex_type) is not type:
92 raise TypeError(
92 raise TypeError(
93 "invalid argument: ex_type should be an exception "
93 "invalid argument: ex_type should be an exception "
94 "type, or just supply no arguments at all")
94 "type, or just supply no arguments at all")
95 if ex_type is None and ex_tb is None:
95 if ex_type is None and ex_tb is None:
96 ex_type, ex_value, ex_tb = sys.exc_info()
96 ex_type, ex_value, ex_tb = sys.exc_info()
97
97
98 remote_tb = getattr(ex_value, "_vcs_server_traceback", None)
98 remote_tb = getattr(ex_value, "_vcs_server_traceback", None)
99
99
100 if remote_tb:
100 if remote_tb:
101 remote_tb = formatRemoteTraceback(remote_tb)
101 remote_tb = formatRemoteTraceback(remote_tb)
102 return local_tb + ''.join(remote_tb)
102 return local_tb + ''.join(remote_tb)
103 finally:
103 finally:
104 # clean up cycle to traceback, to allow proper GC
104 # clean up cycle to traceback, to allow proper GC
105 del ex_type, ex_value, ex_tb
105 del ex_type, ex_value, ex_tb
106
106
107 return local_tb
107 return local_tb
108
108
109
109
110 class ColorFormatter(ExceptionAwareFormatter):
110 class ColorFormatter(ExceptionAwareFormatter):
111
111
112 def format(self, record):
112 def format(self, record):
113 """
113 """
114 Changes record's levelname to use with COLORS enum
114 Changes record's levelname to use with COLORS enum
115 """
115 """
116
116
117 levelname = record.levelname
117 levelname = record.levelname
118 start = COLOR_SEQ % (COLORS[levelname])
118 start = COLOR_SEQ % (COLORS[levelname])
119 def_record = logging.Formatter.format(self, record)
119 def_record = logging.Formatter.format(self, record)
120 end = RESET_SEQ
120 end = RESET_SEQ
121
121
122 colored_record = ''.join([start, def_record, end])
122 colored_record = ''.join([start, def_record, end])
123 return colored_record
123 return colored_record
124
124
125
125
126 def _inject_req_id(record):
126 def _inject_req_id(record):
127 from pyramid.threadlocal import get_current_request
127 from pyramid.threadlocal import get_current_request
128 req = get_current_request()
128 req = get_current_request()
129 req_id = 'req_id:%-36s ' % (getattr(req, 'req_id', None))
129 dummy = '00000000-0000-0000-0000-000000000000'
130 req_id = 'req_id:%-36s' % (getattr(req, 'req_id', dummy))
130 record.req_id = req_id
131 record.req_id = req_id
131
132
132
133
133 class RequestTrackingFormatter(ExceptionAwareFormatter):
134 class RequestTrackingFormatter(ExceptionAwareFormatter):
134 def format(self, record):
135 def format(self, record):
135 _inject_req_id(record)
136 _inject_req_id(record)
136 def_record = logging.Formatter.format(self, record)
137 def_record = logging.Formatter.format(self, record)
137 return def_record
138 return def_record
138
139
139
140
140 class ColorRequestTrackingFormatter(ColorFormatter):
141 class ColorRequestTrackingFormatter(ColorFormatter):
141 def format(self, record):
142 def format(self, record):
142 """
143 """
143 Changes record's levelname to use with COLORS enum
144 Changes record's levelname to use with COLORS enum
144 """
145 """
145 _inject_req_id(record)
146 _inject_req_id(record)
146 levelname = record.levelname
147 levelname = record.levelname
147 start = COLOR_SEQ % (COLORS[levelname])
148 start = COLOR_SEQ % (COLORS[levelname])
148 def_record = logging.Formatter.format(self, record)
149 def_record = logging.Formatter.format(self, record)
149 end = RESET_SEQ
150 end = RESET_SEQ
150
151
151 colored_record = ''.join([start, def_record, end])
152 colored_record = ''.join([start, def_record, end])
152 return colored_record
153 return colored_record
153
154
154
155
155 class ColorFormatterSql(logging.Formatter):
156 class ColorFormatterSql(logging.Formatter):
156
157
157 def format(self, record):
158 def format(self, record):
158 """
159 """
159 Changes record's levelname to use with COLORS enum
160 Changes record's levelname to use with COLORS enum
160 """
161 """
161
162
162 start = COLOR_SEQ % (COLORS['SQL'])
163 start = COLOR_SEQ % (COLORS['SQL'])
163 def_record = format_sql(logging.Formatter.format(self, record))
164 def_record = format_sql(logging.Formatter.format(self, record))
164 end = RESET_SEQ
165 end = RESET_SEQ
165
166
166 colored_record = ''.join([start, def_record, end])
167 colored_record = ''.join([start, def_record, end])
167 return colored_record
168 return colored_record
168
169
169 # marcink: needs to stay with this name for backward .ini compatability
170 # marcink: needs to stay with this name for backward .ini compatability
170 Pyro4AwareFormatter = ExceptionAwareFormatter
171 Pyro4AwareFormatter = ExceptionAwareFormatter
General Comments 0
You need to be logged in to leave comments. Login now