##// END OF EJS Templates
gunicorn: allow custom logger to set consistent formatting of requests for gunicorn with rhodecode logging.
marcink -
r2075:0e299543 default
parent child Browse files
Show More
@@ -1,90 +1,113 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 import time
19 import datetime
18 20 import threading
19 21 import traceback
22 from gunicorn.glogging import Logger
20 23
21 24
22 25 # GLOBAL
23 26 errorlog = '-'
24 27 accesslog = '-'
25 28 loglevel = 'debug'
26 29
27 30 # SECURITY
28 31 limit_request_line = 4094
29 32 limit_request_fields = 100
30 33 limit_request_field_size = 8190
31 34
32 35 # SERVER MECHANICS
33 36 # None == system temp dir
34 37 worker_tmp_dir = None
35 38 tmp_upload_dir = None
36 39
37 40 # Custom log format
38 41 access_log_format = (
39 42 '%(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"')
40 43
41 44 # self adjust workers based on CPU count
42 45 # workers = multiprocessing.cpu_count() * 2 + 1
43 46
44 47
45 48 def post_fork(server, worker):
46 49 server.log.info("[<%-10s>] WORKER spawned", worker.pid)
47 50
48 51
49 52 def pre_fork(server, worker):
50 53 pass
51 54
52 55
53 56 def pre_exec(server):
54 57 server.log.info("Forked child, re-executing.")
55 58
56 59
57 60 def when_ready(server):
58 61 server.log.info("Server is ready. Spawning workers")
59 62
60 63
61 64 def worker_int(worker):
62 65 worker.log.info("[<%-10s>] worker received INT or QUIT signal", worker.pid)
63 66
64 67 # get traceback info, on worker crash
65 68 id2name = dict([(th.ident, th.name) for th in threading.enumerate()])
66 69 code = []
67 70 for thread_id, stack in sys._current_frames().items():
68 71 code.append(
69 72 "\n# Thread: %s(%d)" % (id2name.get(thread_id, ""), thread_id))
70 73 for fname, lineno, name, line in traceback.extract_stack(stack):
71 74 code.append('File: "%s", line %d, in %s' % (fname, lineno, name))
72 75 if line:
73 76 code.append(" %s" % (line.strip()))
74 77 worker.log.debug("\n".join(code))
75 78
76 79
77 80 def worker_abort(worker):
78 81 worker.log.info("[<%-10s>] worker received SIGABRT signal", worker.pid)
79 82
80 83
81 84 def pre_request(worker, req):
82 85 return
83 86 worker.log.debug("[<%-10s>] PRE WORKER: %s %s",
84 87 worker.pid, req.method, req.path)
85 88
86 89
87 90 def post_request(worker, req, environ, resp):
88 91 return
89 92 worker.log.debug("[<%-10s>] POST WORKER: %s %s resp: %s", worker.pid,
90 req.method, req.path, resp.status_code) No newline at end of file
93 req.method, req.path, resp.status_code)
94
95
96 class RhodeCodeLogger(Logger):
97 """
98 Custom Logger that allows some customization that gunicorn doesn't allow
99 """
100
101 datefmt = r"%Y-%m-%d %H:%M:%S"
102
103 def __init__(self, cfg):
104 Logger.__init__(self, cfg)
105
106 def now(self):
107 """ return date in RhodeCode Log format """
108 now = time.time()
109 msecs = int((now - long(now)) * 1000)
110 return time.strftime(self.datefmt, time.localtime(now)) + '.{0:03d}'.format(msecs)
111
112
113 logger_class = RhodeCodeLogger
General Comments 0
You need to be logged in to leave comments. Login now