Coverage for src/app.py: 0%

48 statements  

« prev     ^ index     » next       coverage.py v7.5.0, created at 2024-07-20 21:46 +0000

1import logging 

2import signal 

3import sys 

4 

5import sentry_sdk 

6from sentry_sdk.integrations import argv, atexit, dedupe, modules, stdlib, threading 

7from sentry_sdk.integrations import logging as sentry_logging 

8from sqlalchemy.sql import text 

9 

10from couchers.config import check_config, config 

11from couchers.db import apply_migrations, session_scope 

12from couchers.jobs.worker import start_jobs_scheduler, start_jobs_worker 

13from couchers.metrics import create_prometheus_server, main_process_registry 

14from couchers.server import create_main_server, create_media_server 

15from dummy_data import add_dummy_data 

16 

17check_config() 

18 

19logging.basicConfig(format="%(asctime)s: %(name)s: %(message)s", level=logging.INFO) 

20logger = logging.getLogger(__name__) 

21 

22logging.getLogger("couchers.jobs.worker").setLevel(logging.INFO) 

23 

24if config["SENTRY_ENABLED"]: 

25 # Sends exception tracebacks to Sentry, a cloud service for collecting exceptions 

26 sentry_sdk.init( 

27 config["SENTRY_URL"], 

28 traces_sample_rate=0.0, 

29 environment=config["COOKIE_DOMAIN"], 

30 release=config["VERSION"], 

31 default_integrations=False, 

32 integrations=[ 

33 # we need to manually list out the integrations, there is no other way of disabling the global excepthook integration 

34 # we want to disable that because it seems to be picking up already handled gRPC errors (e.g. grpc.StatusCode.NOT_FOUND) 

35 argv.ArgvIntegration(), 

36 atexit.AtexitIntegration(), 

37 dedupe.DedupeIntegration(), 

38 sentry_logging.LoggingIntegration(), 

39 modules.ModulesIntegration(), 

40 stdlib.StdlibIntegration(), 

41 threading.ThreadingIntegration(), 

42 ], 

43 ) 

44 

45# used to export metrics 

46create_prometheus_server(main_process_registry, 8000) 

47 

48 

49def log_unhandled_exception(exc_type, exc_value, exc_traceback): 

50 """Make sure that any unhandled exceptions will write to the logs""" 

51 if issubclass(exc_type, KeyboardInterrupt): 

52 # call the default excepthook saved at __excepthook__ 

53 sys.__excepthook__(exc_type, exc_value, exc_traceback) 

54 return 

55 logger.critical("Unhandled exception", exc_info=(exc_type, exc_value, exc_traceback)) 

56 

57 

58sys.excepthook = log_unhandled_exception 

59 

60logger.info("Checking DB connection") 

61 

62with session_scope() as session: 

63 res = session.execute(text("SELECT 42;")) 

64 if list(res) != [(42,)]: 

65 raise Exception("Failed to connect to DB") 

66 

67logger.info("Running DB migrations") 

68 

69apply_migrations() 

70 

71if config["ADD_DUMMY_DATA"]: 

72 add_dummy_data() 

73 

74logger.info("Starting") 

75 

76if config["ROLE"] in ["api", "all"]: 

77 server = create_main_server(port=1751) 

78 server.start() 

79 media_server = create_media_server(port=1753) 

80 media_server.start() 

81 logger.info("Serving on 1751 (secure) and 1753 (media)") 

82 

83if config["ROLE"] in ["scheduler", "all"]: 

84 scheduler = start_jobs_scheduler() 

85 

86if config["ROLE"] in ["worker", "all"]: 

87 worker = start_jobs_worker() 

88 

89logger.info("App waiting for signal...") 

90 

91signal.pause()