23
23
struct logger * crashlog ;
24
24
25
25
struct print_filter {
26
+ /* In list log_book->print_filters / log_file->print_filters */
26
27
struct list_node list ;
27
28
28
29
const char * prefix ;
29
30
enum log_level level ;
30
31
};
31
32
33
+ struct log_file {
34
+ struct list_head print_filters ;
35
+ FILE * f ;
36
+ };
37
+
32
38
struct log_book {
33
39
size_t mem_used ;
34
40
size_t max_mem ;
@@ -43,7 +49,7 @@ struct log_book {
43
49
struct list_head loggers ;
44
50
45
51
/* Array of log files: one per ld->logfiles[] */
46
- FILE * * outfiles ;
52
+ struct log_file * * log_files ;
47
53
bool print_timestamps ;
48
54
49
55
struct log_entry * log ;
@@ -131,6 +137,23 @@ static const char *level_prefix(enum log_level level)
131
137
abort ();
132
138
}
133
139
140
+ /* What do these filters say about level to log this entry at? */
141
+ static bool filter_level (const struct list_head * print_filters ,
142
+ const char * prefix ,
143
+ const char * node_id_str ,
144
+ enum log_level * level )
145
+ {
146
+ struct print_filter * i ;
147
+
148
+ list_for_each (print_filters , i , list ) {
149
+ if (strstr (prefix , i -> prefix ) || strstr (node_id_str , i -> prefix )) {
150
+ * level = i -> level ;
151
+ return true;
152
+ }
153
+ }
154
+ return false;
155
+ }
156
+
134
157
static void log_to_files (const char * log_prefix ,
135
158
const char * entry_prefix ,
136
159
enum log_level level ,
@@ -140,10 +163,11 @@ static void log_to_files(const char *log_prefix,
140
163
const u8 * io ,
141
164
size_t io_len ,
142
165
bool print_timestamps ,
143
- FILE * * outfiles )
166
+ const enum log_level * default_print_level ,
167
+ struct log_file * * log_files )
144
168
{
145
169
char tstamp [sizeof ("YYYY-mm-ddTHH:MM:SS.nnnZ " )];
146
- char * entry ;
170
+ char * entry , * nodestr ;
147
171
148
172
if (print_timestamps ) {
149
173
char iso8601_msec_fmt [sizeof ("YYYY-mm-ddTHH:MM:SS.%03dZ " )];
@@ -152,6 +176,10 @@ static void log_to_files(const char *log_prefix,
152
176
} else
153
177
tstamp [0 ] = '\0' ;
154
178
179
+ if (node_id )
180
+ nodestr = node_id_to_hexstr (tmpctx , node_id );
181
+ else
182
+ nodestr = "" ;
155
183
if (level == LOG_IO_IN || level == LOG_IO_OUT ) {
156
184
const char * dir = level == LOG_IO_IN ? "[IN]" : "[OUT]" ;
157
185
char * hex = tal_hexstr (NULL , io , io_len );
@@ -161,7 +189,7 @@ static void log_to_files(const char *log_prefix,
161
189
else
162
190
entry = tal_fmt (tmpctx , "%s%s%s-%s: %s%s %s\n" ,
163
191
log_prefix , tstamp ,
164
- node_id_to_hexstr ( tmpctx , node_id ) ,
192
+ nodestr ,
165
193
entry_prefix , str , dir , hex );
166
194
tal_free (hex );
167
195
} else {
@@ -171,18 +199,31 @@ static void log_to_files(const char *log_prefix,
171
199
else
172
200
entry = tal_fmt (tmpctx , "%s%s%s %s-%s: %s\n" ,
173
201
log_prefix , tstamp , level_prefix (level ),
174
- node_id_to_hexstr ( tmpctx , node_id ) ,
202
+ nodestr ,
175
203
entry_prefix , str );
176
204
}
177
205
178
206
/* Default if nothing set is stdout */
179
- if (!outfiles ) {
207
+ if (!log_files ) {
180
208
fwrite (entry , strlen (entry ), 1 , stdout );
181
209
fflush (stdout );
182
210
}
183
- for (size_t i = 0 ; i < tal_count (outfiles ); i ++ ) {
184
- fwrite (entry , strlen (entry ), 1 , outfiles [i ]);
185
- fflush (outfiles [i ]);
211
+
212
+ /* We may have to apply per-file filters. */
213
+ for (size_t i = 0 ; i < tal_count (log_files ); i ++ ) {
214
+ enum log_level filter ;
215
+ if (!filter_level (& log_files [i ]-> print_filters ,
216
+ entry_prefix , nodestr , & filter )) {
217
+ /* If we haven't set default yet, only log UNUSUAL */
218
+ if (default_print_level )
219
+ filter = * default_print_level ;
220
+ else
221
+ filter = LOG_UNUSUAL ;
222
+ }
223
+ if (level < filter )
224
+ continue ;
225
+ fwrite (entry , strlen (entry ), 1 , log_files [i ]-> f );
226
+ fflush (log_files [i ]-> f );
186
227
}
187
228
}
188
229
@@ -278,7 +319,7 @@ struct log_book *new_log_book(struct lightningd *ld, size_t max_mem)
278
319
log_book -> mem_used = 0 ;
279
320
log_book -> num_entries = 0 ;
280
321
log_book -> max_mem = max_mem ;
281
- log_book -> outfiles = NULL ;
322
+ log_book -> log_files = NULL ;
282
323
log_book -> default_print_level = NULL ;
283
324
/* We have to allocate this, since we tal_free it on resetting */
284
325
log_book -> prefix = tal_strdup (log_book , "" );
@@ -295,19 +336,33 @@ struct log_book *new_log_book(struct lightningd *ld, size_t max_mem)
295
336
return log_book ;
296
337
}
297
338
298
- static enum log_level filter_level (struct log_book * log_book ,
299
- const struct log_prefix * lp ,
300
- const struct node_id * node_id )
339
+ /* What's the minimum level to print for this log book? */
340
+ static enum log_level print_level (struct log_book * log_book ,
341
+ const struct log_prefix * lp ,
342
+ const struct node_id * node_id )
301
343
{
302
- struct print_filter * i ;
344
+ enum log_level level ;
303
345
const char * node_id_str = node_id ? node_id_to_hexstr (tmpctx , node_id ) : "" ;
304
346
305
347
assert (log_book -> default_print_level != NULL );
306
- list_for_each ( & log_book -> print_filters , i , list ) {
307
- if ( strstr ( lp -> prefix , i -> prefix ) || strstr ( node_id_str , i -> prefix ))
308
- return i -> level ;
348
+ if (! filter_level ( & log_book -> print_filters , lp -> prefix ,
349
+ node_id_str , & level )) {
350
+ level = * log_book -> default_print_level ;
309
351
}
310
- return * log_book -> default_print_level ;
352
+
353
+ /* We need to look into per-file filters as well: might give a
354
+ * lower filter! */
355
+ for (size_t i = 0 ; i < tal_count (log_book -> log_files ); i ++ ) {
356
+ enum log_level sublevel ;
357
+ if (filter_level (& log_book -> log_files [i ]-> print_filters ,
358
+ lp -> prefix , node_id_str , & sublevel )) {
359
+ if (sublevel < level ) {
360
+ level = sublevel ;
361
+ }
362
+ }
363
+ }
364
+
365
+ return level ;
311
366
}
312
367
313
368
static void destroy_logger (struct logger * log )
@@ -337,7 +392,7 @@ new_logger(const tal_t *ctx, struct log_book *log_book,
337
392
if (!log -> log_book -> default_print_level )
338
393
log -> print_level = LOG_UNUSUAL ;
339
394
else
340
- log -> print_level = filter_level (log -> log_book , log -> prefix , default_node_id );
395
+ log -> print_level = print_level (log -> log_book , log -> prefix , default_node_id );
341
396
list_add (& log -> log_book -> loggers , & log -> list );
342
397
tal_add_destructor (log , destroy_logger );
343
398
return log ;
@@ -350,7 +405,7 @@ const char *log_prefix(const struct logger *log)
350
405
351
406
bool log_has_io_logging (const struct logger * log )
352
407
{
353
- return filter_level (log -> log_book , log -> prefix , log -> default_node_id ) < LOG_DBG ;
408
+ return print_level (log -> log_book , log -> prefix , log -> default_node_id ) < LOG_DBG ;
354
409
}
355
410
356
411
/* This may move entry! */
@@ -415,7 +470,8 @@ static void maybe_print(struct logger *log, const struct log_entry *l)
415
470
& l -> time , l -> log ,
416
471
l -> io , tal_bytelen (l -> io ),
417
472
log -> log_book -> print_timestamps ,
418
- log -> log_book -> outfiles );
473
+ log -> log_book -> default_print_level ,
474
+ log -> log_book -> log_files );
419
475
}
420
476
421
477
void logv (struct logger * log , enum log_level level ,
@@ -465,7 +521,8 @@ void log_io(struct logger *log, enum log_level dir,
465
521
& l -> time , str ,
466
522
data , len ,
467
523
log -> log_book -> print_timestamps ,
468
- log -> log_book -> outfiles );
524
+ log -> log_book -> default_print_level ,
525
+ log -> log_book -> log_files );
469
526
470
527
/* Save a tal header, by using raw malloc. */
471
528
l -> log = strdup (str );
@@ -656,12 +713,12 @@ static struct io_plan *setup_read(struct io_conn *conn, struct lightningd *ld);
656
713
static struct io_plan * rotate_log (struct io_conn * conn , struct lightningd * ld )
657
714
{
658
715
log_info (ld -> log , "Ending log due to SIGHUP" );
659
- for (size_t i = 0 ; i < tal_count (ld -> log -> log_book -> outfiles ); i ++ ) {
716
+ for (size_t i = 0 ; i < tal_count (ld -> log -> log_book -> log_files ); i ++ ) {
660
717
if (streq (ld -> logfiles [i ], "-" ))
661
718
continue ;
662
- fclose (ld -> log -> log_book -> outfiles [i ]);
663
- ld -> log -> log_book -> outfiles [i ] = fopen (ld -> logfiles [i ], "a" );
664
- if (!ld -> log -> log_book -> outfiles [i ])
719
+ fclose (ld -> log -> log_book -> log_files [i ]-> f );
720
+ ld -> log -> log_book -> log_files [i ]-> f = fopen (ld -> logfiles [i ], "a" );
721
+ if (!ld -> log -> log_book -> log_files [i ]-> f )
665
722
err (1 , "failed to reopen log file %s" , ld -> logfiles [i ]);
666
723
}
667
724
@@ -712,29 +769,31 @@ static void setup_log_rotation(struct lightningd *ld)
712
769
char * arg_log_to_file (const char * arg , struct lightningd * ld )
713
770
{
714
771
int size ;
715
- FILE * outf ;
772
+ struct log_file * logf ;
716
773
717
774
if (!ld -> logfiles ) {
718
775
setup_log_rotation (ld );
719
776
ld -> logfiles = tal_arr (ld , const char * , 0 );
720
- ld -> log -> log_book -> outfiles = tal_arr (ld -> log -> log_book , FILE * , 0 );
777
+ ld -> log_book -> log_files = tal_arr (ld -> log_book , struct log_file * , 0 );
721
778
}
722
779
780
+ logf = tal (ld -> log_book -> log_files , struct log_file );
781
+ list_head_init (& logf -> print_filters );
723
782
if (streq (arg , "-" ))
724
- outf = stdout ;
783
+ logf -> f = stdout ;
725
784
else {
726
- outf = fopen (arg , "a" );
727
- if (!outf )
785
+ logf -> f = fopen (arg , "a" );
786
+ if (!logf -> f )
728
787
return tal_fmt (tmpctx , "Failed to open: %s" , strerror (errno ));
729
788
}
730
789
731
790
tal_arr_expand (& ld -> logfiles , tal_strdup (ld -> logfiles , arg ));
732
- tal_arr_expand (& ld -> log -> log_book -> outfiles , outf );
791
+ tal_arr_expand (& ld -> log_book -> log_files , logf );
733
792
734
793
/* For convenience make a block of empty lines just like Bitcoin Core */
735
- size = ftell (outf );
794
+ size = ftell (logf -> f );
736
795
if (size > 0 )
737
- fprintf (outf , "\n\n\n\n" );
796
+ fprintf (logf -> f , "\n\n\n\n" );
738
797
739
798
log_debug (ld -> log , "Opened log file %s" , arg );
740
799
return NULL ;
@@ -770,22 +829,23 @@ void logging_options_parsed(struct log_book *log_book)
770
829
771
830
/* Set print_levels for each log, depending on filters. */
772
831
list_for_each (& log_book -> loggers , log , list ) {
773
- log -> print_level = filter_level (log_book ,
774
- log -> prefix ,
775
- log -> default_node_id );
832
+ log -> print_level = print_level (log_book ,
833
+ log -> prefix ,
834
+ log -> default_node_id );
776
835
}
777
836
778
837
/* Catch up, since before we were only printing BROKEN msgs */
779
838
for (size_t i = 0 ; i < log_book -> num_entries ; i ++ ) {
780
839
const struct log_entry * l = & log_book -> log [i ];
781
840
782
- if (l -> level >= filter_level (log_book , l -> prefix , l -> nc ? & l -> nc -> node_id : NULL ))
841
+ if (l -> level >= print_level (log_book , l -> prefix , l -> nc ? & l -> nc -> node_id : NULL ))
783
842
log_to_files (log_book -> prefix , l -> prefix -> prefix , l -> level ,
784
843
l -> nc ? & l -> nc -> node_id : NULL ,
785
844
& l -> time , l -> log ,
786
845
l -> io , tal_bytelen (l -> io ),
787
846
log_book -> print_timestamps ,
788
- log_book -> outfiles );
847
+ log_book -> default_print_level ,
848
+ log_book -> log_files );
789
849
}
790
850
}
791
851
0 commit comments