@@ -332,59 +332,32 @@ static void build_ctx_prefix(char *buf, size_t bufsz,
332332static void do_log_internal (log_level_t level ,
333333 const char * component , const char * stream ,
334334 const char * format , va_list args ) {
335- // Copy va_list: a va_list may only be traversed once; copying satisfies
336- // static-analysis tools (clang-analyzer-valist.Uninitialized).
337- va_list args_copy ;
338- va_copy (args_copy , args );
339-
340- // CRITICAL: Check if logger is shutting down or destroyed.
341- // Write directly to console without the mutex to avoid use-after-destroy.
342- if (logger .shutdown ) {
343- char message [4096 ];
344- vsnprintf (message , sizeof (message ), format , args_copy ); // NOLINT(clang-analyzer-valist.Uninitialized)
345- va_end (args_copy );
346-
347- time_t now ;
348- struct tm tm_buf ;
349- char timestamp [32 ];
350- time (& now );
351- strftime (timestamp , sizeof (timestamp ), "%Y-%m-%d %H:%M:%S" ,
352- localtime_r (& now , & tm_buf ));
353-
354- char ctx_prefix [224 ] = {0 };
355- build_ctx_prefix (ctx_prefix , sizeof (ctx_prefix ), component , stream );
356-
357- FILE * console = (level == LOG_LEVEL_ERROR ) ? stderr : stdout ;
358- fprintf (console , "[%s] [%s] %s%s\n" ,
359- timestamp , log_level_strings [level ], ctx_prefix , message );
360- fflush (console );
361- return ;
362- }
363-
364335 // Only log messages at or below the configured log level.
365336 if (level > logger .log_level ) {
366- va_end (args_copy );
367337 return ;
368338 }
369339
370- time_t now ;
340+ // Create timestamp
341+ struct timespec now ;
342+ clock_gettime (CLOCK_REALTIME , & now );
343+
371344 struct tm tm_buf ;
345+ localtime_r (& now .tv_sec , & tm_buf );
346+
372347 char timestamp [32 ];
373- char iso_timestamp [ 32 ] ;
348+ size_t offset = strftime ( timestamp , sizeof ( timestamp ), "%Y-%m-%d %H:%M:%S" , & tm_buf ) ;
374349
375- time (& now );
376- localtime_r (& now , & tm_buf );
377- strftime (timestamp , sizeof (timestamp ), "%Y-%m-%d %H:%M:%S" , & tm_buf );
378- strftime (iso_timestamp , sizeof (iso_timestamp ), "%Y-%m-%dT%H:%M:%S" , & tm_buf );
350+ unsigned int msec = (unsigned int )(now .tv_nsec / 1000000UL );
351+ snprintf (timestamp + offset , sizeof (timestamp ) - offset , ".%03u" , msec );
379352
380353 char message [4096 ];
381- vsnprintf (message , sizeof (message ), format , args_copy ); // NOLINT(clang-analyzer-valist.Uninitialized)
382- va_end (args_copy );
354+ vsnprintf (message , sizeof (message ), format , args );
383355
384356 char ctx_prefix [224 ] = {0 };
385357 build_ctx_prefix (ctx_prefix , sizeof (ctx_prefix ), component , stream );
386358
387- // Double-check shutdown before acquiring mutex.
359+ // CRITICAL: Check if logger is shutting down or destroyed.
360+ // Write directly to console without the mutex to avoid use-after-destroy.
388361 if (logger .shutdown ) {
389362 FILE * console = (level == LOG_LEVEL_ERROR ) ? stderr : stdout ;
390363 fprintf (console , "[%s] [%s] %s%s\n" ,
@@ -421,6 +394,9 @@ static void do_log_internal(log_level_t level,
421394 pthread_mutex_unlock (& logger .mutex );
422395
423396 if (write_json_log ) {
397+ char iso_timestamp [32 ];
398+
399+ strftime (iso_timestamp , sizeof (iso_timestamp ), "%Y-%m-%dT%H:%M:%S" , & tm_buf );
424400 write_json_log (level , iso_timestamp , message );
425401 }
426402}
0 commit comments