@@ -50,6 +50,8 @@ void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2, 3);
50
50
51
51
static void elog_internal (int elevel , bool file_only , const char * fmt , va_list args )
52
52
pg_attribute_printf (3 , 0 );
53
+ static void elog_stderr (int elevel , const char * fmt , ...)
54
+ pg_attribute_printf (2 , 3 );
53
55
54
56
/* Functions to work with log files */
55
57
static void open_logfile (FILE * * file , const char * filename_format );
@@ -63,8 +65,8 @@ static FILE *log_file = NULL;
63
65
static FILE * error_log_file = NULL ;
64
66
65
67
static bool exit_hook_registered = false;
66
- /* Logging to file is in progress */
67
- static bool logging_to_file = false;
68
+ /* Logging of the current thread is in progress */
69
+ static bool loggin_in_progress = false;
68
70
69
71
static pthread_mutex_t log_file_mutex = PTHREAD_MUTEX_INITIALIZER ;
70
72
@@ -111,11 +113,37 @@ write_elevel(FILE *stream, int elevel)
111
113
fputs ("PANIC: " , stream );
112
114
break ;
113
115
default :
114
- elog (ERROR , "invalid logging level: %d" , elevel );
116
+ elog_stderr (ERROR , "invalid logging level: %d" , elevel );
115
117
break ;
116
118
}
117
119
}
118
120
121
+ /*
122
+ * Exit with code if it is an error.
123
+ * Check for in_cleanup flag to avoid deadlock in case of ERROR in cleanup
124
+ * routines.
125
+ */
126
+ static void
127
+ exit_if_necessary (int elevel )
128
+ {
129
+ if (elevel > WARNING && !in_cleanup )
130
+ {
131
+ /* Interrupt other possible routines */
132
+ interrupted = true;
133
+
134
+ /* If this is not the main thread then don't call exit() */
135
+ #ifdef WIN32
136
+ if (main_tid != GetCurrentThreadId ())
137
+ ExitThread (elevel );
138
+ #else
139
+ if (!pthread_equal (main_tid , pthread_self ()))
140
+ pthread_exit (NULL );
141
+ #endif
142
+ else
143
+ exit (elevel );
144
+ }
145
+ }
146
+
119
147
/*
120
148
* Logs to stderr or to log file and exit if ERROR or FATAL.
121
149
*
@@ -132,18 +160,19 @@ elog_internal(int elevel, bool file_only, const char *fmt, va_list args)
132
160
time_t log_time = (time_t ) time (NULL );
133
161
char strfbuf [128 ];
134
162
135
- write_to_file = !logging_to_file && elevel >= LOG_LEVEL_FILE &&
163
+ write_to_file = elevel >= LOG_LEVEL_FILE && log_path [0 ] != '\0' ;
164
+ write_to_error_log = elevel >= ERROR && error_log_filename &&
136
165
log_path [0 ] != '\0' ;
137
- write_to_error_log = !logging_to_file && elevel >= ERROR &&
138
- error_log_filename && log_path [0 ] != '\0' ;
139
166
write_to_stderr = elevel >= LOG_LEVEL_CONSOLE && !file_only ;
140
167
141
168
/*
142
- * There is no need to lock if this is elog() from upper elog() and
143
- * logging is not initialized.
169
+ * There is no need to lock if this is elog() from upper elog().
144
170
*/
145
- if (write_to_file || write_to_error_log || write_to_stderr )
171
+ if (!loggin_in_progress )
172
+ {
146
173
pthread_mutex_lock (& log_file_mutex );
174
+ loggin_in_progress = true;
175
+ }
147
176
148
177
/* We need copy args only if we need write to error log file */
149
178
if (write_to_error_log )
@@ -166,8 +195,6 @@ elog_internal(int elevel, bool file_only, const char *fmt, va_list args)
166
195
*/
167
196
if (write_to_file )
168
197
{
169
- logging_to_file = true;
170
-
171
198
if (log_file == NULL )
172
199
{
173
200
if (log_filename == NULL )
@@ -182,8 +209,6 @@ elog_internal(int elevel, bool file_only, const char *fmt, va_list args)
182
209
vfprintf (log_file , fmt , args );
183
210
fputc ('\n' , log_file );
184
211
fflush (log_file );
185
-
186
- logging_to_file = false;
187
212
}
188
213
189
214
/*
@@ -193,8 +218,6 @@ elog_internal(int elevel, bool file_only, const char *fmt, va_list args)
193
218
*/
194
219
if (write_to_error_log )
195
220
{
196
- logging_to_file = true;
197
-
198
221
if (error_log_file == NULL )
199
222
open_logfile (& error_log_file , error_log_filename );
200
223
@@ -205,7 +228,6 @@ elog_internal(int elevel, bool file_only, const char *fmt, va_list args)
205
228
fputc ('\n' , error_log_file );
206
229
fflush (error_log_file );
207
230
208
- logging_to_file = false;
209
231
va_end (error_args );
210
232
}
211
233
@@ -228,25 +250,41 @@ elog_internal(int elevel, bool file_only, const char *fmt, va_list args)
228
250
va_end (std_args );
229
251
}
230
252
231
- if (write_to_file || write_to_error_log || write_to_stderr )
253
+ if (loggin_in_progress )
254
+ {
232
255
pthread_mutex_unlock (& log_file_mutex );
256
+ loggin_in_progress = false;
257
+ }
258
+
259
+ exit_if_necessary (elevel );
260
+ }
261
+
262
+ /*
263
+ * Log only to stderr. It is called only within elog_internal() when another
264
+ * logging already was started.
265
+ */
266
+ static void
267
+ elog_stderr (int elevel , const char * fmt , ...)
268
+ {
269
+ va_list args ;
233
270
234
271
/*
235
- * Exit with code if it is an error.
236
- * Check for in_cleanup flag to avoid deadlock in case of ERROR in cleanup
237
- * routines.
272
+ * Do not log message if severity level is less than log_level.
273
+ * It is the little optimisation to put it here not in elog_internal().
238
274
*/
239
- if (elevel > WARNING && !in_cleanup )
240
- {
241
- /* Interrupt other possible routines */
242
- interrupted = true;
275
+ if (elevel < LOG_LEVEL_CONSOLE && elevel < ERROR )
276
+ return ;
243
277
244
- /* If this is not the main thread then don't call exit() */
245
- if (!pthread_equal (main_tid , pthread_self ()))
246
- pthread_exit (NULL );
247
- else
248
- exit (elevel );
249
- }
278
+ va_start (args , fmt );
279
+
280
+ write_elevel (stderr , elevel );
281
+ vfprintf (stderr , fmt , args );
282
+ fputc ('\n' , stderr );
283
+ fflush (stderr );
284
+
285
+ va_end (args );
286
+
287
+ exit_if_necessary (elevel );
250
288
}
251
289
252
290
/*
@@ -417,7 +455,7 @@ logfile_getname(const char *format, time_t timestamp)
417
455
struct tm * tm = localtime (& timestamp );
418
456
419
457
if (log_path [0 ] == '\0' )
420
- elog (ERROR , "logging path is not set" );
458
+ elog_stderr (ERROR , "logging path is not set" );
421
459
422
460
filename = (char * ) palloc (MAXPGPATH );
423
461
@@ -427,7 +465,7 @@ logfile_getname(const char *format, time_t timestamp)
427
465
428
466
/* Treat log_filename as a strftime pattern */
429
467
if (strftime (filename + len , MAXPGPATH - len , format , tm ) <= 0 )
430
- elog (ERROR , "strftime(%s) failed: %s" , format , strerror (errno ));
468
+ elog_stderr (ERROR , "strftime(%s) failed: %s" , format , strerror (errno ));
431
469
432
470
return filename ;
433
471
}
@@ -453,8 +491,8 @@ logfile_open(const char *filename, const char *mode)
453
491
{
454
492
int save_errno = errno ;
455
493
456
- elog (FATAL , "could not open log file \"%s\": %s" ,
457
- filename , strerror (errno ));
494
+ elog_stderr (FATAL , "could not open log file \"%s\": %s" ,
495
+ filename , strerror (errno ));
458
496
errno = save_errno ;
459
497
}
460
498
@@ -488,8 +526,8 @@ open_logfile(FILE **file, const char *filename_format)
488
526
goto logfile_open ;
489
527
}
490
528
else
491
- elog (ERROR , "cannot stat log file \"%s\": %s" ,
492
- filename , strerror (errno ));
529
+ elog_stderr (ERROR , "cannot stat log file \"%s\": %s" ,
530
+ filename , strerror (errno ));
493
531
}
494
532
/* Found log file "filename" */
495
533
logfile_exists = true;
@@ -505,35 +543,35 @@ open_logfile(FILE **file, const char *filename_format)
505
543
if (stat (control , & control_st ) == -1 )
506
544
{
507
545
if (errno != ENOENT )
508
- elog (ERROR , "cannot stat rotation file \"%s\": %s" ,
509
- control , strerror (errno ));
546
+ elog_stderr (ERROR , "cannot stat rotation file \"%s\": %s" ,
547
+ control , strerror (errno ));
510
548
}
511
549
else
512
550
{
513
551
char buf [1024 ];
514
552
515
553
control_file = fopen (control , "r" );
516
554
if (control_file == NULL )
517
- elog (ERROR , "cannot open rotation file \"%s\": %s" ,
518
- control , strerror (errno ));
555
+ elog_stderr (ERROR , "cannot open rotation file \"%s\": %s" ,
556
+ control , strerror (errno ));
519
557
520
558
if (fgets (buf , lengthof (buf ), control_file ))
521
559
{
522
560
time_t creation_time ;
523
561
524
562
if (!parse_int64 (buf , (int64 * ) & creation_time , 0 ))
525
- elog (ERROR , "rotation file \"%s\" has wrong "
526
- "creation timestamp \"%s\"" ,
527
- control , buf );
563
+ elog_stderr (ERROR , "rotation file \"%s\" has wrong "
564
+ "creation timestamp \"%s\"" ,
565
+ control , buf );
528
566
/* Parsed creation time */
529
567
530
568
rotation_requested = (cur_time - creation_time ) >
531
569
/* convert to seconds */
532
570
log_rotation_age * 60 ;
533
571
}
534
572
else
535
- elog (ERROR , "cannot read creation timestamp from "
536
- "rotation file \"%s\"" , control );
573
+ elog_stderr (ERROR , "cannot read creation timestamp from "
574
+ "rotation file \"%s\"" , control );
537
575
538
576
fclose (control_file );
539
577
}
@@ -560,8 +598,8 @@ open_logfile(FILE **file, const char *filename_format)
560
598
561
599
control_file = fopen (control , "w" );
562
600
if (control_file == NULL )
563
- elog (ERROR , "cannot open rotation file \"%s\": %s" ,
564
- control , strerror (errno ));
601
+ elog_stderr (ERROR , "cannot open rotation file \"%s\": %s" ,
602
+ control , strerror (errno ));
565
603
566
604
fprintf (control_file , "%ld" , timestamp );
567
605
0 commit comments