-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwsgi.py
More file actions
101 lines (82 loc) · 3.59 KB
/
Copy pathwsgi.py
File metadata and controls
101 lines (82 loc) · 3.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
"""
The gevent monkey import and patch suppress a warning, and a potential problem.
Gunicorn would call it anyway, but if it tries to call it after the ssl module
has been initialized in another module (like, in our code, by the botocore
library), then it could lead to inconsistencies in how the ssl module is used.
Thus we patch the ssl module through gevent.monkey.patch_all before any other
import, especially the app import, which would cause the boto module to be
loaded, which would in turn load the ssl module.
"""
# pylint: disable=wrong-import-position,wrong-import-order,ungrouped-imports
import gevent.monkey
gevent.monkey.patch_all()
# Initialize OTEL.
# Initialize should be called as early as possible, but at least before the app is imported
# The order has a impact on how the libraries are instrumented. If called after app import,
# e.g. the flask instrumentation has no effect. See:
# https://github.com/open-telemetry/opentelemetry.io/blob/main/content/en/docs/zero-code/python/troubleshooting.md#use-programmatic-auto-instrumentation
from app.helpers.otel import initialize
from app.helpers.otel import initialize_flask
from app.helpers.otel import setup_trace_provider
initialize()
from gunicorn.app.base import BaseApplication
from app.app import app as application
from app.helpers.logging_utils import get_logging_cfg
from app.helpers.wmts_config import init_wmts_config
from app.settings import FORWARDED_PROTO_HEADER_NAME
from app.settings import FORWARED_ALLOW_IPS
from app.settings import GUNICORN_KEEPALIVE
from app.settings import GUNICORN_WORKER_TMP_DIR
from app.settings import WMTS_PORT
from app.settings import WMTS_WORKERS
from app.settings import WSGI_TIMEOUT
initialize_flask(application)
def post_fork(server, worker):
server.log.info("Worker spawned (pid: %s)", worker.pid)
# Setup OTEL providers for this worker
setup_trace_provider()
class StandaloneApplication(BaseApplication):
# pylint: disable=abstract-method
# pylint: disable=redefined-outer-name
def __init__(self, app, options=None):
self.options = options or {}
self.application = app
super().__init__()
def load_config(self):
config = {
key: value
for key, value in self.options.items()
if key in self.cfg.settings and value is not None
}
for key, value in config.items():
self.cfg.set(key.lower(), value)
def load(self):
return self.application
def on_starting(server):
# We initialize the wmts config here to do it only once, but only when
# the logging has been configured. If we do it in the app.__init__.py module
# the we don't have the logging yet configured and we don't get any logs
init_wmts_config()
# We use the port 9000 as default, otherwise we set the HTTP_PORT env variable
# within the container.
if __name__ == '__main__':
# Bind to 0.0.0.0 to let your app listen to all network interfaces.
options = {
'bind': f'0.0.0.0:{WMTS_PORT}',
'worker_class': 'gevent',
'workers': WMTS_WORKERS,
'worker_tmp_dir': GUNICORN_WORKER_TMP_DIR,
'timeout': WSGI_TIMEOUT,
'post_fork': post_fork,
'keepalive': GUNICORN_KEEPALIVE,
'access_log_format':
'%(h)s %(l)s %(u)s "%(r)s" %(s)s %(B)s Bytes '
'"%(f)s" "%(a)s" %(L)ss',
'logconfig_dict': get_logging_cfg(),
'on_starting': on_starting,
'forwarded_allow_ips': FORWARED_ALLOW_IPS,
'secure_scheme_headers': {
FORWARDED_PROTO_HEADER_NAME: 'https'
}
}
StandaloneApplication(application, options).run()