3131import django_rq
3232import opensearchpy
3333import redis
34+ import structlog
3435
3536from django .conf import settings
3637from django .db import connections , OperationalError
4445DEFAULT_MAX_RETRIES = 10
4546
4647
48+ logger = structlog .get_logger (__name__ )
49+
50+
4751@click .group ()
4852@click .pass_context
4953def run (ctx : Context ):
@@ -122,17 +126,17 @@ def periodic_maintain_tasks(interval):
122126 while True :
123127 try :
124128 maintain_tasks ()
125- logging .info ("Maintenance tasks executed successfully. " )
126- except redis .exceptions .ConnectionError as e :
127- logging .error (f "Redis connection error during maintenance tasks: { e } " )
128- except django .db .utils .OperationalError as e :
129- logging .error (f "Database connection error during maintenance tasks: { e } " )
129+ logger .info ("Maintenance tasks executed successfully" )
130+ except redis .exceptions .ConnectionError as exc :
131+ logger .error ("Redis connection error during maintenance tasks" , err = exc )
132+ except django .db .utils .OperationalError as exc :
133+ logger .error ("Database connection error during maintenance tasks" , err = exc )
130134 connections .close_all ()
131- except Exception as e :
132- logging .error ("Error during maintenance tasks: %s " , e )
135+ except Exception as exc :
136+ logger .error ("Unexpected error during maintenance tasks" , err = exc )
133137 raise
134138 except KeyboardInterrupt :
135- logging .info ("Maintenance task interrupted. Exiting..." )
139+ logger .info ("Maintenance task interrupted. Exiting..." )
136140 return
137141
138142 time .sleep (interval )
@@ -146,7 +150,7 @@ def _maintenance_process(maintenance_interval):
146150 )
147151 process .start ()
148152
149- logging .info ("Started maintenance process with PID %s " , process .pid )
153+ logger .info ("Started maintenance process" , pid = process .pid )
150154
151155 return process
152156
@@ -217,6 +221,10 @@ def _wait_opensearch_ready(
217221) -> None :
218222 """Wait for OpenSearch to be available before starting"""
219223
224+ # The 'opensearch' library writes logs with the exceptions while
225+ # connecting to the database. Disable them temporarily until
226+ # the service is up. We have to use logging library because structlog
227+ # doesn't allow to disable a logger dynamically.
220228 os_logger = logging .getLogger ("opensearch" )
221229 os_logger .disabled = True
222230
@@ -245,24 +253,26 @@ def _wait_opensearch_ready(
245253 # Index still not created, but OpenSearch is up
246254 break
247255 except opensearchpy .exceptions .AuthorizationException :
248- logging .error ("OpenSearch Authorization failed. Check your credentials." )
256+ logger .error ("OpenSearch Authorization failed. Check your credentials." )
249257 exit (1 )
250258 except (
251259 opensearchpy .exceptions .ConnectionError ,
252260 opensearchpy .exceptions .TransportError ,
253- ) as e :
254- logging .warning (
255- f"[{ attempt + 1 } /{ DEFAULT_MAX_RETRIES } ] OpenSearch connection not ready: { e } "
261+ ) as exc :
262+ logger .warning (
263+ f"[{ attempt + 1 } /{ DEFAULT_MAX_RETRIES } ] OpenSearch connection not ready" ,
264+ err = exc ,
256265 )
257266 _sleep_backoff (attempt )
258267
259268 else :
260- logging .error ("Failed to connect to OpenSearch." )
269+ logger .error ("Failed to connect to OpenSearch." )
261270 exit (1 )
262271
272+ # Enable back 'opensearch' library logs
263273 os_logger .disabled = False
264274
265- logging .info ("OpenSearch is ready." )
275+ logger .info ("OpenSearch is ready." )
266276
267277
268278def _wait_redis_ready ():
@@ -273,16 +283,17 @@ def _wait_redis_ready():
273283 redis_conn = django_rq .get_connection ()
274284 redis_conn .ping ()
275285 break
276- except redis .exceptions .ConnectionError as e :
277- logging .warning (
278- f"[{ attempt + 1 } /{ DEFAULT_MAX_RETRIES } ] Redis connection not ready: { e } "
286+ except redis .exceptions .ConnectionError as exc :
287+ logger .warning (
288+ f"[{ attempt + 1 } /{ DEFAULT_MAX_RETRIES } ] Redis connection not ready" ,
289+ err = exc ,
279290 )
280291 _sleep_backoff (attempt )
281292 else :
282- logging .error ("Failed to connect to Redis server" )
293+ logger .error ("Failed to connect to Redis server" )
283294 exit (1 )
284295
285- logging .info ("Redis is ready" )
296+ logger .info ("Redis is ready" )
286297
287298
288299def _wait_database_ready ():
@@ -296,17 +307,18 @@ def _wait_database_ready():
296307 pass # Just test the connection
297308 break
298309
299- except OperationalError as e :
300- logging .warning (
301- f"[{ attempt + 1 } /{ DEFAULT_MAX_RETRIES } ] Database connection not ready: { e .__cause__ } "
310+ except OperationalError as exc :
311+ logger .warning (
312+ f"[{ attempt + 1 } /{ DEFAULT_MAX_RETRIES } ] Database connection not ready" ,
313+ err = exc .__cause__ ,
302314 )
303315 _sleep_backoff (attempt )
304316 else :
305317 error_msg = "Failed to connect to the database after all retries"
306- logging .error (error_msg )
318+ logger .error (error_msg )
307319 raise ConnectionError (error_msg )
308320
309- logging .info ("Database is ready." )
321+ logger .info ("Database is ready." )
310322
311323 # Close all database connections to avoid timed out connections
312324 connections .close_all ()
0 commit comments