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