@@ -14,11 +14,9 @@ enum {
1414LOG_LINE_SIZE = 2048 // Log line should be at least 100
1515};
1616
17- static FILE * logfile = NULL ; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
18- static int loglevel = LOG_ERROR ; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
19- static ev_timer logging_timer ; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
20- static ev_signal sigusr2 ; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
21- static struct ring_buffer * flight_recorder = NULL ; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
17+ // Default global logging context for backwards compatibility
18+ static logging_context_t g_default_context ; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
19+ static int g_default_initialized = 0 ; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
2220
2321static const char * const SeverityStr [] = {
2422 "[D]" ,
@@ -29,83 +27,97 @@ static const char * const SeverityStr[] = {
2927 "[F]"
3028};
3129
32- void logging_timer_cb (struct ev_loop __attribute__((unused )) * loop ,
33- ev_timer __attribute__((unused )) * w ,
34- int __attribute__((unused )) revents ) {
35- if (logfile ) {
36- (void )fflush (logfile );
37- }
38- }
30+ // === Context-aware implementations ===
3931
40- void logging_flight_recorder_dump (void ) {
41- if (flight_recorder ) {
42- ILOG ("Flight recorder dump" ); // will be also at the end of the dump :)
43- ring_buffer_dump (flight_recorder , logfile );
44- } else {
45- ILOG ("Flight recorder is disabled" );
32+ static void logging_timer_cb_ctx (struct ev_loop __attribute__((unused )) * loop ,
33+ ev_timer * w , int __attribute__((unused )) revents ) {
34+ logging_context_t * ctx = (logging_context_t * )w -> data ;
35+ if (ctx -> logfile ) {
36+ (void )fflush (ctx -> logfile );
4637 }
4738}
4839
49- static void logging_flight_recorder_dump_cb (struct ev_loop __attribute__((unused )) * loop ,
50- ev_signal __attribute__((__unused__ )) * w ,
51- int __attribute__(( __unused__ )) revents ) {
52- logging_flight_recorder_dump ( );
40+ static void logging_flight_recorder_dump_cb_ctx (struct ev_loop __attribute__((unused )) * loop ,
41+ ev_signal * w , int __attribute__((__unused__ )) revents ) {
42+ logging_context_t * ctx = ( logging_context_t * ) w -> data ;
43+ logging_context_flight_recorder_dump ( ctx );
5344}
5445
55- void logging_events_init (struct ev_loop * loop ) {
56- /* don't start timer if we will never write messages that are not flushed */
57- if (loglevel < LOG_FLUSH_LEVEL ) {
58- DLOG ("starting periodic log flush timer" );
59- ev_timer_init (& logging_timer , logging_timer_cb , 0 , 10 );
60- ev_timer_start (loop , & logging_timer );
46+ void logging_context_init (logging_context_t * ctx , int fd , int level ,
47+ unsigned flight_recorder_size ) {
48+ if (ctx -> logfile ) {
49+ (void )fclose (ctx -> logfile );
6150 }
51+ ctx -> logfile = fdopen (fd , "a" );
52+ ctx -> loglevel = level ;
53+ ctx -> loop = NULL ;
6254
63- DLOG ("starting SIGUSR2 handler" );
64- ev_signal_init (& sigusr2 , logging_flight_recorder_dump_cb , SIGUSR2 );
65- ev_signal_start (loop , & sigusr2 );
55+ ring_buffer_init (& ctx -> flight_recorder , flight_recorder_size );
6656}
6757
68- void logging_events_cleanup (struct ev_loop * loop ) {
69- ev_timer_stop (loop , & logging_timer );
70- ev_signal_stop (loop , & sigusr2 );
71- }
58+ void logging_context_events_init (logging_context_t * ctx , struct ev_loop * loop ) {
59+ ctx -> loop = loop ;
7260
73- void logging_init (int fd , int level , uint32_t flight_recorder_size ) {
74- if (logfile ) {
75- (void )fclose (logfile );
61+ /* don't start timer if we will never write messages that are not flushed */
62+ if (ctx -> loglevel < LOG_FLUSH_LEVEL ) {
63+ ev_timer_init (& ctx -> logging_timer , logging_timer_cb_ctx , 0 , 10 );
64+ ctx -> logging_timer .data = ctx ;
65+ ev_timer_start (loop , & ctx -> logging_timer );
7666 }
77- logfile = fdopen (fd , "a" );
78- loglevel = level ;
7967
80- ring_buffer_init (& flight_recorder , flight_recorder_size );
68+ ev_signal_init (& ctx -> sigusr2 , logging_flight_recorder_dump_cb_ctx , SIGUSR2 );
69+ ctx -> sigusr2 .data = ctx ;
70+ ev_signal_start (loop , & ctx -> sigusr2 );
8171}
8272
83- void logging_cleanup (void ) {
84- if (flight_recorder ) {
85- ring_buffer_free (& flight_recorder );
86- flight_recorder = NULL ;
73+ void logging_context_events_cleanup (logging_context_t * ctx ) {
74+ if (ctx -> loop ) {
75+ ev_timer_stop (ctx -> loop , & ctx -> logging_timer );
76+ ev_signal_stop (ctx -> loop , & ctx -> sigusr2 );
77+ }
78+ }
79+
80+ void logging_context_cleanup (logging_context_t * ctx ) {
81+ if (ctx -> flight_recorder ) {
82+ ring_buffer_free (& ctx -> flight_recorder );
83+ ctx -> flight_recorder = NULL ;
8784 }
8885
89- if (logfile ) {
90- (void )fclose (logfile );
86+ if (ctx -> logfile ) {
87+ (void )fclose (ctx -> logfile );
9188 }
92- logfile = NULL ;
89+ ctx -> logfile = NULL ;
90+ ctx -> loop = NULL ;
9391}
9492
95- int logging_debug_enabled (void ) {
96- return loglevel <= LOG_DEBUG || flight_recorder ;
93+ int logging_context_debug_enabled (logging_context_t * ctx ) {
94+ return ctx -> loglevel <= LOG_DEBUG || ctx -> flight_recorder ;
95+ }
96+
97+ void logging_context_flight_recorder_dump (logging_context_t * ctx ) {
98+ if (ctx -> flight_recorder ) {
99+ // Log using context to avoid recursion
100+ if (ctx -> logfile ) {
101+ fprintf (ctx -> logfile , "[I] Flight recorder dump\n" );
102+ fflush (ctx -> logfile );
103+ }
104+ ring_buffer_dump (ctx -> flight_recorder , ctx -> logfile );
105+ }
97106}
98107
99108// NOLINTNEXTLINE(misc-no-recursion) because of severity check
100- void _log (const char * file , int line , int severity , const char * fmt , ...) {
101- if (severity < loglevel && !flight_recorder ) {
109+ void logging_context_log (logging_context_t * ctx , const char * file , int line ,
110+ int severity , const char * fmt , ...) {
111+ if (severity < ctx -> loglevel && !ctx -> flight_recorder ) {
102112 return ;
103113 }
104114 if (severity < 0 || severity >= LOG_MAX ) {
105- FLOG ("Unknown log severity: %d" , severity );
115+ // Can't use FLOG here due to recursion, just log error
116+ fprintf (stderr , "Unknown log severity: %d\n" , severity );
117+ return ;
106118 }
107- if (!logfile ) {
108- logfile = fdopen (STDOUT_FILENO , "w" );
119+ if (!ctx -> logfile ) {
120+ ctx -> logfile = fdopen (STDOUT_FILENO , "w" );
109121 }
110122
111123 struct timeval tv ;
@@ -134,21 +146,132 @@ void _log(const char *file, int line, int severity, const char *fmt, ...) {
134146 buff [buff_pos - 1 ] = '$' ; // indicate truncation
135147 }
136148
137- if (flight_recorder ) {
138- ring_buffer_push_back (flight_recorder , buff , buff_pos );
149+ if (ctx -> flight_recorder ) {
150+ ring_buffer_push_back (ctx -> flight_recorder , buff , buff_pos );
151+ }
152+
153+ if (severity < ctx -> loglevel ) {
154+ return ;
155+ }
156+ (void )fprintf (ctx -> logfile , "%s\n" , buff );
157+
158+ if (severity >= LOG_FLUSH_LEVEL ) {
159+ (void )fflush (ctx -> logfile );
160+ }
161+ if (severity == LOG_FATAL ) {
162+ if (ctx -> flight_recorder ) {
163+ ring_buffer_dump (ctx -> flight_recorder , ctx -> logfile );
164+ }
165+ #ifdef DEBUG
166+ abort ();
167+ #else
168+ exit (1 );
169+ #endif
170+ }
171+ }
172+
173+ // === Legacy API (uses default global context) ===
174+
175+ logging_context_t * logging_get_default_context (void ) {
176+ return & g_default_context ;
177+ }
178+
179+ void logging_init (int fd , int level , unsigned flight_recorder_size ) {
180+ logging_context_init (& g_default_context , fd , level , flight_recorder_size );
181+ g_default_initialized = 1 ;
182+ }
183+
184+ void logging_events_init (struct ev_loop * loop ) {
185+ if (!g_default_initialized ) {
186+ // Initialize with default stderr if not already initialized
187+ logging_init (STDERR_FILENO , LOG_ERROR , 0 );
188+ }
189+ logging_context_events_init (& g_default_context , loop );
190+ }
191+
192+ void logging_events_cleanup (struct ev_loop * loop ) {
193+ (void )loop ; // Unused - kept for API compatibility
194+ logging_context_events_cleanup (& g_default_context );
195+ }
196+
197+ void logging_cleanup (void ) {
198+ logging_context_cleanup (& g_default_context );
199+ g_default_initialized = 0 ;
200+ }
201+
202+ int logging_debug_enabled (void ) {
203+ return logging_context_debug_enabled (& g_default_context );
204+ }
205+
206+ void logging_flight_recorder_dump (void ) {
207+ logging_context_flight_recorder_dump (& g_default_context );
208+ }
209+
210+ // Keep original _log for backwards compatibility with existing macros
211+ void _log (const char * file , int line , int severity , const char * fmt , ...) {
212+ if (!g_default_initialized ) {
213+ // Auto-initialize to stderr if not already initialized
214+ logging_init (STDERR_FILENO , LOG_ERROR , 0 );
215+ }
216+
217+ if (severity < g_default_context .loglevel && !g_default_context .flight_recorder ) {
218+ return ;
219+ }
220+
221+ // Forward to context-aware implementation
222+ va_list args ;
223+ va_start (args , fmt );
224+
225+ // Manually inline the logging logic since we can't forward va_list easily
226+ if (severity < 0 || severity >= LOG_MAX ) {
227+ fprintf (stderr , "Unknown log severity: %d\n" , severity );
228+ va_end (args );
229+ return ;
230+ }
231+
232+ if (!g_default_context .logfile ) {
233+ g_default_context .logfile = fdopen (STDOUT_FILENO , "w" );
234+ }
235+
236+ struct timeval tv ;
237+ gettimeofday (& tv , NULL );
238+
239+ char buff [LOG_LINE_SIZE ];
240+ uint32_t buff_pos = 0 ;
241+ int chars = snprintf (buff , LOG_LINE_SIZE , "%s %8" PRIu64 ".%06" PRIu64 " %s:%d " ,
242+ SeverityStr [severity ], (uint64_t )tv .tv_sec , (uint64_t )tv .tv_usec , file , line );
243+ if (chars < 0 || chars >= LOG_LINE_SIZE /2 ) {
244+ abort ();
245+ }
246+ buff_pos += (uint32_t )chars ;
247+
248+ chars = vsnprintf (buff + buff_pos , LOG_LINE_SIZE - buff_pos , fmt , args ); // NOLINT(clang-diagnostic-format-nonliteral)
249+ va_end (args );
250+
251+ if (chars < 0 ) {
252+ abort ();
253+ }
254+ buff_pos += (uint32_t )chars ;
255+ if (buff_pos >= LOG_LINE_SIZE ) {
256+ buff_pos = LOG_LINE_SIZE - 1 ;
257+ buff [buff_pos - 1 ] = '$' ;
258+ }
259+
260+ if (g_default_context .flight_recorder ) {
261+ ring_buffer_push_back (g_default_context .flight_recorder , buff , buff_pos );
139262 }
140263
141- if (severity < loglevel ) {
264+ if (severity < g_default_context . loglevel ) {
142265 return ;
143266 }
144- (void )fprintf (logfile , "%s\n" , buff );
267+ (void )fprintf (g_default_context . logfile , "%s\n" , buff );
145268
146269 if (severity >= LOG_FLUSH_LEVEL ) {
147- (void )fflush (logfile );
270+ (void )fflush (g_default_context . logfile );
148271 }
149272 if (severity == LOG_FATAL ) {
150- if (flight_recorder ) {
151- ring_buffer_dump (flight_recorder , logfile );
273+ if (g_default_context . flight_recorder ) {
274+ ring_buffer_dump (g_default_context . flight_recorder , g_default_context . logfile );
152275 }
153276#ifdef DEBUG
154277 abort ();
0 commit comments