@@ -1018,6 +1018,61 @@ def _configure_logging(self) -> None:
10181018 # Prevent propagation to avoid duplicate or differently formatted messages
10191019 self .logger .propagate = False
10201020
1021+ def get_uvicorn_log_config (self ) -> Dict [str , Any ]:
1022+ """
1023+ Create uvicorn log config that matches the Application's logging format.
1024+
1025+ This method returns the log configuration used by uvicorn, allowing external
1026+ users to match the logging format of the Application class.
1027+
1028+ Returns
1029+ -------
1030+ Dict[str, Any]
1031+ Log configuration dictionary compatible with uvicorn's log_config parameter
1032+
1033+ """
1034+ log_config = {
1035+ 'version' : 1 ,
1036+ 'disable_existing_loggers' : False ,
1037+ 'formatters' : {
1038+ 'json' : {
1039+ '()' : 'singlestoredb.functions.ext.utils.JSONFormatter' ,
1040+ },
1041+ },
1042+ 'handlers' : {
1043+ 'default' : {
1044+ 'class' : (
1045+ 'logging.FileHandler' if self .log_file
1046+ else 'logging.StreamHandler'
1047+ ),
1048+ 'formatter' : 'json' ,
1049+ },
1050+ },
1051+ 'loggers' : {
1052+ 'uvicorn' : {
1053+ 'handlers' : ['default' ],
1054+ 'level' : self .log_level .upper (),
1055+ 'propagate' : False ,
1056+ },
1057+ 'uvicorn.error' : {
1058+ 'handlers' : ['default' ],
1059+ 'level' : self .log_level .upper (),
1060+ 'propagate' : False ,
1061+ },
1062+ 'uvicorn.access' : {
1063+ 'handlers' : ['default' ],
1064+ 'level' : self .log_level .upper (),
1065+ 'propagate' : False ,
1066+ },
1067+ },
1068+ }
1069+
1070+ # Add filename to file handler if log file is specified
1071+ if self .log_file :
1072+ log_config ['handlers' ]['default' ]['filename' ] = self .log_file # type: ignore
1073+
1074+ return log_config
1075+
10211076 async def __call__ (
10221077 self ,
10231078 scope : Dict [str , Any ],
@@ -2018,48 +2073,8 @@ def main(argv: Optional[List[str]] = None) -> None:
20182073 ).items () if v is not None
20192074 }
20202075
2021- # Configure uvicorn logging to use JSON format
2022- log_config = {
2023- 'version' : 1 ,
2024- 'disable_existing_loggers' : False ,
2025- 'formatters' : {
2026- 'json' : {
2027- '()' : 'singlestoredb.functions.ext.utils.JSONFormatter' ,
2028- },
2029- },
2030- 'handlers' : {
2031- 'default' : {
2032- 'class' : (
2033- 'logging.FileHandler' if args .log_file
2034- else 'logging.StreamHandler'
2035- ),
2036- 'formatter' : 'json' ,
2037- },
2038- },
2039- 'loggers' : {
2040- 'uvicorn' : {
2041- 'handlers' : ['default' ],
2042- 'level' : args .log_level .upper (),
2043- 'propagate' : False ,
2044- },
2045- 'uvicorn.error' : {
2046- 'handlers' : ['default' ],
2047- 'level' : args .log_level .upper (),
2048- 'propagate' : False ,
2049- },
2050- 'uvicorn.access' : {
2051- 'handlers' : ['default' ],
2052- 'level' : args .log_level .upper (),
2053- 'propagate' : False ,
2054- },
2055- },
2056- }
2057-
2058- # Add filename to file handler if log file is specified
2059- if args .log_file :
2060- log_config ['handlers' ]['default' ]['filename' ] = args .log_file # type: ignore
2061-
2062- app_args ['log_config' ] = log_config
2076+ # Configure uvicorn logging to use JSON format matching Application's format
2077+ app_args ['log_config' ] = app .get_uvicorn_log_config ()
20632078
20642079 if use_async :
20652080 asyncio .create_task (_run_uvicorn (uvicorn , app , app_args , db = args .db ))
0 commit comments