@@ -373,59 +373,32 @@ static void build_ctx_prefix(char *buf, size_t bufsz,
373373static void do_log_internal (log_level_t level ,
374374 const char * component , const char * stream ,
375375 const char * format , va_list args ) {
376- // Copy va_list: a va_list may only be traversed once; copying satisfies
377- // static-analysis tools (clang-analyzer-valist.Uninitialized).
378- va_list args_copy ;
379- va_copy (args_copy , args );
380-
381- // CRITICAL: Check if logger is shutting down or destroyed.
382- // Write directly to console without the mutex to avoid use-after-destroy.
383- if (logger .shutdown ) {
384- char message [4096 ];
385- vsnprintf (message , sizeof (message ), format , args_copy ); // NOLINT(clang-analyzer-valist.Uninitialized)
386- va_end (args_copy );
387-
388- time_t now ;
389- struct tm tm_buf ;
390- char timestamp [32 ];
391- time (& now );
392- strftime (timestamp , sizeof (timestamp ), "%Y-%m-%d %H:%M:%S" ,
393- localtime_r (& now , & tm_buf ));
394-
395- char ctx_prefix [224 ] = {0 };
396- build_ctx_prefix (ctx_prefix , sizeof (ctx_prefix ), component , stream );
397-
398- FILE * console = (level == LOG_LEVEL_ERROR ) ? stderr : stdout ;
399- fprintf (console , "[%s] [%s] %s%s\n" ,
400- timestamp , log_level_strings [level ], ctx_prefix , message );
401- fflush (console );
402- return ;
403- }
404-
405376 // Only log messages at or below the configured log level.
406377 if (level > logger .log_level ) {
407- va_end (args_copy );
408378 return ;
409379 }
410380
411- time_t now ;
381+ // Create timestamp
382+ struct timespec now ;
383+ clock_gettime (CLOCK_REALTIME , & now );
384+
412385 struct tm tm_buf ;
386+ localtime_r (& now .tv_sec , & tm_buf );
387+
413388 char timestamp [32 ];
414- char iso_timestamp [ 32 ] ;
389+ size_t offset = strftime ( timestamp , sizeof ( timestamp ), "%Y-%m-%d %H:%M:%S" , & tm_buf ) ;
415390
416- time (& now );
417- localtime_r (& now , & tm_buf );
418- strftime (timestamp , sizeof (timestamp ), "%Y-%m-%d %H:%M:%S" , & tm_buf );
419- strftime (iso_timestamp , sizeof (iso_timestamp ), "%Y-%m-%dT%H:%M:%S" , & tm_buf );
391+ unsigned int msec = (unsigned int )(now .tv_nsec / 1000000UL );
392+ snprintf (timestamp + offset , sizeof (timestamp ) - offset , ".%03u" , msec );
420393
421394 char message [4096 ];
422- vsnprintf (message , sizeof (message ), format , args_copy ); // NOLINT(clang-analyzer-valist.Uninitialized)
423- va_end (args_copy );
395+ vsnprintf (message , sizeof (message ), format , args );
424396
425397 char ctx_prefix [224 ] = {0 };
426398 build_ctx_prefix (ctx_prefix , sizeof (ctx_prefix ), component , stream );
427399
428- // Double-check shutdown before acquiring mutex.
400+ // CRITICAL: Check if logger is shutting down or destroyed.
401+ // Write directly to console without the mutex to avoid use-after-destroy.
429402 if (logger .shutdown ) {
430403 FILE * console = (level == LOG_LEVEL_ERROR ) ? stderr : stdout ;
431404 fprintf (console , "[%s] [%s] %s%s\n" ,
@@ -462,6 +435,9 @@ static void do_log_internal(log_level_t level,
462435 pthread_mutex_unlock (& logger .mutex );
463436
464437 if (write_json_log ) {
438+ char iso_timestamp [32 ];
439+
440+ strftime (iso_timestamp , sizeof (iso_timestamp ), "%Y-%m-%dT%H:%M:%S" , & tm_buf );
465441 write_json_log (level , iso_timestamp , message );
466442 }
467443}
0 commit comments