##// END OF EJS Templates
gunicorn: update config to present consistent pre and post logs.
marcink -
r2542:2daa9cc8 default
parent child Browse files
Show More
@@ -1,151 +1,152 b''
1 """
1 """
2 gunicorn config extension and hooks. Sets additional configuration that is
2 gunicorn config extension and hooks. Sets additional configuration that is
3 available post the .ini config.
3 available post the .ini config.
4
4
5 - workers = ${cpu_number}
5 - workers = ${cpu_number}
6 - threads = 1
6 - threads = 1
7 - proc_name = ${gunicorn_proc_name}
7 - proc_name = ${gunicorn_proc_name}
8 - worker_class = sync
8 - worker_class = sync
9 - worker_connections = 10
9 - worker_connections = 10
10 - max_requests = 1000
10 - max_requests = 1000
11 - max_requests_jitter = 30
11 - max_requests_jitter = 30
12 - timeout = 21600
12 - timeout = 21600
13
13
14 """
14 """
15
15
16 import multiprocessing
16 import multiprocessing
17 import sys
17 import sys
18 import time
18 import time
19 import datetime
19 import datetime
20 import threading
20 import threading
21 import traceback
21 import traceback
22 from gunicorn.glogging import Logger
22 from gunicorn.glogging import Logger
23
23
24
24
25 # GLOBAL
25 # GLOBAL
26 errorlog = '-'
26 errorlog = '-'
27 accesslog = '-'
27 accesslog = '-'
28 loglevel = 'debug'
28 loglevel = 'debug'
29
29
30 # SECURITY
30 # SECURITY
31
31
32 # The maximum size of HTTP request line in bytes.
32 # The maximum size of HTTP request line in bytes.
33 limit_request_line = 4094
33 limit_request_line = 4094
34
34
35 # Limit the number of HTTP headers fields in a request.
35 # Limit the number of HTTP headers fields in a request.
36 limit_request_fields = 1024
36 limit_request_fields = 1024
37
37
38 # Limit the allowed size of an HTTP request header field.
38 # Limit the allowed size of an HTTP request header field.
39 # Value is a positive number or 0.
39 # Value is a positive number or 0.
40 # Setting it to 0 will allow unlimited header field sizes.
40 # Setting it to 0 will allow unlimited header field sizes.
41 limit_request_field_size = 0
41 limit_request_field_size = 0
42
42
43
43
44 # Timeout for graceful workers restart.
44 # Timeout for graceful workers restart.
45 # After receiving a restart signal, workers have this much time to finish
45 # After receiving a restart signal, workers have this much time to finish
46 # serving requests. Workers still alive after the timeout (starting from the
46 # serving requests. Workers still alive after the timeout (starting from the
47 # receipt of the restart signal) are force killed.
47 # receipt of the restart signal) are force killed.
48 graceful_timeout = 30
48 graceful_timeout = 30
49
49
50
50
51 # The number of seconds to wait for requests on a Keep-Alive connection.
51 # The number of seconds to wait for requests on a Keep-Alive connection.
52 # Generally set in the 1-5 seconds range.
52 # Generally set in the 1-5 seconds range.
53 keepalive = 2
53 keepalive = 2
54
54
55
55
56 # SERVER MECHANICS
56 # SERVER MECHANICS
57 # None == system temp dir
57 # None == system temp dir
58 # worker_tmp_dir is recommended to be set to some tmpfs
58 worker_tmp_dir = None
59 worker_tmp_dir = None
59 tmp_upload_dir = None
60 tmp_upload_dir = None
60
61
61 # Custom log format
62 # Custom log format
62 access_log_format = (
63 access_log_format = (
63 '%(t)s GNCRN %(p)-8s %(h)-15s rqt:%(L)s %(s)s %(b)-6s "%(m)s:%(U)s %(q)s" usr:%(u)s "%(f)s" "%(a)s"')
64 '%(t)s GNCRN %(p)-8s %(h)-15s rqt:%(L)s %(s)s %(b)-6s "%(m)s:%(U)s %(q)s" usr:%(u)s "%(f)s" "%(a)s"')
64
65
65 # self adjust workers based on CPU count
66 # self adjust workers based on CPU count
66 # workers = multiprocessing.cpu_count() * 2 + 1
67 # workers = multiprocessing.cpu_count() * 2 + 1
67
68
68
69
69 def post_fork(server, worker):
70 def post_fork(server, worker):
70 server.log.info("[<%-10s>] WORKER spawned", worker.pid)
71 server.log.info("[<%-10s>] WORKER spawned", worker.pid)
71
72
72
73
73 def pre_fork(server, worker):
74 def pre_fork(server, worker):
74 pass
75 pass
75
76
76
77
77 def pre_exec(server):
78 def pre_exec(server):
78 server.log.info("Forked child, re-executing.")
79 server.log.info("Forked child, re-executing.")
79
80
80
81
81 def on_starting(server):
82 def on_starting(server):
82 server.log.info("Server is starting.")
83 server.log.info("Server is starting.")
83
84
84
85
85 def when_ready(server):
86 def when_ready(server):
86 server.log.info("Server is ready. Spawning workers")
87 server.log.info("Server is ready. Spawning workers")
87
88
88
89
89 def on_reload(server):
90 def on_reload(server):
90 pass
91 pass
91
92
92
93
93 def worker_int(worker):
94 def worker_int(worker):
94 worker.log.info("[<%-10s>] worker received INT or QUIT signal", worker.pid)
95 worker.log.info("[<%-10s>] worker received INT or QUIT signal", worker.pid)
95
96
96 # get traceback info, on worker crash
97 # get traceback info, on worker crash
97 id2name = dict([(th.ident, th.name) for th in threading.enumerate()])
98 id2name = dict([(th.ident, th.name) for th in threading.enumerate()])
98 code = []
99 code = []
99 for thread_id, stack in sys._current_frames().items():
100 for thread_id, stack in sys._current_frames().items():
100 code.append(
101 code.append(
101 "\n# Thread: %s(%d)" % (id2name.get(thread_id, ""), thread_id))
102 "\n# Thread: %s(%d)" % (id2name.get(thread_id, ""), thread_id))
102 for fname, lineno, name, line in traceback.extract_stack(stack):
103 for fname, lineno, name, line in traceback.extract_stack(stack):
103 code.append('File: "%s", line %d, in %s' % (fname, lineno, name))
104 code.append('File: "%s", line %d, in %s' % (fname, lineno, name))
104 if line:
105 if line:
105 code.append(" %s" % (line.strip()))
106 code.append(" %s" % (line.strip()))
106 worker.log.debug("\n".join(code))
107 worker.log.debug("\n".join(code))
107
108
108
109
109 def worker_abort(worker):
110 def worker_abort(worker):
110 worker.log.info("[<%-10s>] worker received SIGABRT signal", worker.pid)
111 worker.log.info("[<%-10s>] worker received SIGABRT signal", worker.pid)
111
112
112
113
113 def worker_exit(server, worker):
114 def worker_exit(server, worker):
114 worker.log.info("[<%-10s>] worker exit", worker.pid)
115 worker.log.info("[<%-10s>] worker exit", worker.pid)
115
116
116
117
117 def child_exit(server, worker):
118 def child_exit(server, worker):
118 worker.log.info("[<%-10s>] worker child exit", worker.pid)
119 worker.log.info("[<%-10s>] worker child exit", worker.pid)
119
120
120
121
121 def pre_request(worker, req):
122 def pre_request(worker, req):
122 worker.start_time = time.time()
123 worker.start_time = time.time()
123 worker.log.debug(
124 worker.log.debug(
124 "GNCRN PRE WORKER: %s %s", req.method, req.path)
125 "GNCRN PRE WORKER [cnt:%s]: %s %s", worker.nr, req.method, req.path)
125
126
126
127
127 def post_request(worker, req, environ, resp):
128 def post_request(worker, req, environ, resp):
128 total_time = time.time() - worker.start_time
129 total_time = time.time() - worker.start_time
129 worker.log.debug(
130 worker.log.debug(
130 "GNCRN POST WORKER [cnt:%s]: %s %s resp: %s, Load Time: %.3fs",
131 "GNCRN POST WORKER [cnt:%s]: %s %s resp: %s, Load Time: %.3fs",
131 worker.nr, req.method, req.path, resp.status_code, total_time)
132 worker.nr, req.method, req.path, resp.status_code, total_time)
132
133
133
134
134 class RhodeCodeLogger(Logger):
135 class RhodeCodeLogger(Logger):
135 """
136 """
136 Custom Logger that allows some customization that gunicorn doesn't allow
137 Custom Logger that allows some customization that gunicorn doesn't allow
137 """
138 """
138
139
139 datefmt = r"%Y-%m-%d %H:%M:%S"
140 datefmt = r"%Y-%m-%d %H:%M:%S"
140
141
141 def __init__(self, cfg):
142 def __init__(self, cfg):
142 Logger.__init__(self, cfg)
143 Logger.__init__(self, cfg)
143
144
144 def now(self):
145 def now(self):
145 """ return date in RhodeCode Log format """
146 """ return date in RhodeCode Log format """
146 now = time.time()
147 now = time.time()
147 msecs = int((now - long(now)) * 1000)
148 msecs = int((now - long(now)) * 1000)
148 return time.strftime(self.datefmt, time.localtime(now)) + '.{0:03d}'.format(msecs)
149 return time.strftime(self.datefmt, time.localtime(now)) + '.{0:03d}'.format(msecs)
149
150
150
151
151 logger_class = RhodeCodeLogger
152 logger_class = RhodeCodeLogger
General Comments 0
You need to be logged in to leave comments. Login now