diff --git a/c2cwsgiutils/sqlalchemylogger/README.md b/c2cwsgiutils/sqlalchemylogger/README.md index ac4549c41..2e49b9c43 100644 --- a/c2cwsgiutils/sqlalchemylogger/README.md +++ b/c2cwsgiutils/sqlalchemylogger/README.md @@ -63,3 +63,33 @@ if __name__ == '__main__': # logs after a timeout time.sleep(2) ``` + +## Use with forking server (ex: `gunicorn`) + +Snippet for configuration with `gunicorn` and `paste`: + +`production.ini`: + +``` +[handler_sqlalchemylogger] +class = c2cwsgiutils.sqlalchemylogger.handlers.SQLAlchemyHandler +args = ({'url':'postgresql://','tablename':'logs','tableargs': {'schema':'logs'}, 'delay_startup': True},'healthcheck') +level = NOTSET +formatter = generic +propagate = 0 +``` + +`gunicorn.conf.py`: + +```python +def post_fork(server, worker): + import logging + logger = logging.getHandlerByName('sqlalchemylogger') + logger.start() +``` + +The gunicorn must be started with this config file: + +```bash +gunicorn -c gunicorn.conf.py [...] +``` diff --git a/c2cwsgiutils/sqlalchemylogger/handlers.py b/c2cwsgiutils/sqlalchemylogger/handlers.py index 423e4eff6..dbea05102 100644 --- a/c2cwsgiutils/sqlalchemylogger/handlers.py +++ b/c2cwsgiutils/sqlalchemylogger/handlers.py @@ -36,6 +36,29 @@ def __init__( ) -> None: """Initialize the SQLAlchemyHandler.""" super().__init__() + + self.started = False + if sqlalchemy_url.get("delay_startup", False): + self.sqlalchemy_url = sqlalchemy_url + self.does_not_contain_expression = does_not_contain_expression + self.contains_expression = contains_expression + else: + self._start(sqlalchemy_url, does_not_contain_expression, contains_expression) + + def start(self) -> None: + """Force startup of logger in case of delayed startup.""" + self._start(self.sqlalchemy_url, self.does_not_contain_expression, self.contains_expression) + + def _start( + self, + sqlalchemy_url: dict[str, str], + does_not_contain_expression: str, + contains_expression: str, + ) -> None: + if self.started: + # only start once + return + # Initialize DB session self.engine = create_engine(sqlalchemy_url["url"]) self.Log = create_log_class( # pylint: disable=invalid-name @@ -55,6 +78,7 @@ def __init__( self.addFilter(DoesNotContainExpression(does_not_contain_expression)) if contains_expression: self.addFilter(ContainsExpression(contains_expression)) + self.started = True def _processor(self) -> None: _LOG.debug("%s: starting processor thread", __name__)