Coverage for src/app.py: 0%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import logging
2import signal
3import sys
5import sentry_sdk
6from sentry_sdk.integrations.atexit import AtexitIntegration
7from sentry_sdk.integrations.dedupe import DedupeIntegration
8from sentry_sdk.integrations.logging import LoggingIntegration
9from sentry_sdk.integrations.modules import ModulesIntegration
10from sentry_sdk.integrations.stdlib import StdlibIntegration
11from sentry_sdk.integrations.threading import ThreadingIntegration
12from sqlalchemy.sql import text
14from couchers import config
15from couchers.db import apply_migrations, session_scope
16from couchers.jobs.worker import start_jobs_scheduler, start_jobs_worker
17from couchers.metrics import create_prometheus_server, main_process_registry
18from couchers.server import create_main_server, create_media_server
19from dummy_data import add_dummy_data
21config.check_config()
23logging.basicConfig(format="%(asctime)s: %(name)s: %(message)s", level=logging.INFO)
24logger = logging.getLogger(__name__)
26logging.getLogger("couchers.jobs.worker").setLevel(logging.INFO)
28if config.config["SENTRY_ENABLED"]:
29 # Sends exception tracebacks to Sentry, a cloud service for collecting exceptions
30 sentry_sdk.init(
31 config.config["SENTRY_URL"],
32 traces_sample_rate=0.0,
33 environment=config.config["COOKIE_DOMAIN"],
34 release=config.config["VERSION"],
35 default_integrations=False,
36 integrations=[
37 # we need to manually list out the integrations, there is no other way of disabling the global excepthook integration
38 # we want to disable that because it seems to be picking up already handled gRPC errors (e.g. grpc.StatusCode.NOT_FOUND)
39 LoggingIntegration(),
40 StdlibIntegration(),
41 DedupeIntegration(),
42 AtexitIntegration(),
43 ModulesIntegration(),
44 ThreadingIntegration(),
45 ],
46 )
48# used to export metrics
49create_prometheus_server(main_process_registry, 8000)
52def log_unhandled_exception(exc_type, exc_value, exc_traceback):
53 """Make sure that any unhandled exceptions will write to the logs"""
54 if issubclass(exc_type, KeyboardInterrupt):
55 # call the default excepthook saved at __excepthook__
56 sys.__excepthook__(exc_type, exc_value, exc_traceback)
57 return
58 logger.critical("Unhandled exception", exc_info=(exc_type, exc_value, exc_traceback))
61sys.excepthook = log_unhandled_exception
63logger.info(f"Checking DB connection")
65with session_scope() as session:
66 res = session.execute(text("SELECT 42;"))
67 if list(res) != [(42,)]:
68 raise Exception("Failed to connect to DB")
70logger.info(f"Running DB migrations")
72apply_migrations()
74if config.config["ADD_DUMMY_DATA"]:
75 add_dummy_data()
77logger.info(f"Starting")
79if config.config["ROLE"] in ["api", "all"]:
80 server = create_main_server(port=1751)
81 server.start()
82 media_server = create_media_server(port=1753)
83 media_server.start()
84 logger.info(f"Serving on 1751 (secure) and 1753 (media)")
86if config.config["ROLE"] in ["scheduler", "all"]:
87 scheduler = start_jobs_scheduler()
89if config.config["ROLE"] in ["worker", "all"]:
90 worker = start_jobs_worker()
92logger.info("App waiting for signal...")
94signal.pause()