Skip to content

Commit a2758d0

Browse files
staviqcebtenzzre
andauthored
log : make generating separate log files optional (#3787)
* impl --log-new, --log-append * Update common/log.h Co-authored-by: cebtenzzre <[email protected]> * Update common/log.h Co-authored-by: cebtenzzre <[email protected]> * Apply suggestions from code review Co-authored-by: cebtenzzre <[email protected]> --------- Co-authored-by: cebtenzzre <[email protected]>
1 parent e75dfdd commit a2758d0

File tree

1 file changed

+82
-40
lines changed

1 file changed

+82
-40
lines changed

Diff for: common/log.h

+82-40
Original file line numberDiff line numberDiff line change
@@ -97,38 +97,56 @@
9797
#define LOG_TEE_TARGET stderr
9898
#endif
9999

100-
// NOTE: currently disabled as it produces too many log files
100+
// Utility for synchronizing log configuration state
101+
// since std::optional was introduced only in c++17
102+
enum LogTriState
103+
{
104+
LogTriStateSame,
105+
LogTriStateFalse,
106+
LogTriStateTrue
107+
};
108+
101109
// Utility to obtain "pid" like unique process id and use it when creating log files.
102-
//inline std::string log_get_pid()
103-
//{
104-
// static std::string pid;
105-
// if (pid.empty())
106-
// {
107-
// // std::this_thread::get_id() is the most portable way of obtaining a "process id"
108-
// // it's not the same as "pid" but is unique enough to solve multiple instances
109-
// // trying to write to the same log.
110-
// std::stringstream ss;
111-
// ss << std::this_thread::get_id();
112-
// pid = ss.str();
113-
// }
114-
//
115-
// return pid;
116-
//}
110+
inline std::string log_get_pid()
111+
{
112+
static std::string pid;
113+
if (pid.empty())
114+
{
115+
// std::this_thread::get_id() is the most portable way of obtaining a "process id"
116+
// it's not the same as "pid" but is unique enough to solve multiple instances
117+
// trying to write to the same log.
118+
std::stringstream ss;
119+
ss << std::this_thread::get_id();
120+
pid = ss.str();
121+
}
122+
123+
return pid;
124+
}
117125

118126
// Utility function for generating log file names with unique id based on thread id.
119127
// invocation with log_filename_generator( "llama", "log" ) creates a string "llama.<number>.log"
120128
// where the number is a runtime id of the current thread.
121129

122-
#define log_filename_generator(log_file_basename, log_file_extension) log_filename_generator_impl(log_file_basename, log_file_extension)
130+
#define log_filename_generator(log_file_basename, log_file_extension) log_filename_generator_impl(LogTriStateSame, log_file_basename, log_file_extension)
123131

124132
// INTERNAL, DO NOT USE
125-
inline std::string log_filename_generator_impl(const std::string & log_file_basename, const std::string & log_file_extension)
133+
inline std::string log_filename_generator_impl(LogTriState multilog, const std::string & log_file_basename, const std::string & log_file_extension)
126134
{
135+
static bool _multilog = false;
136+
137+
if (multilog != LogTriStateSame)
138+
{
139+
_multilog = multilog == LogTriStateTrue;
140+
}
141+
127142
std::stringstream buf;
128143

129144
buf << log_file_basename;
130-
//buf << ".";
131-
//buf << log_get_pid();
145+
if (_multilog)
146+
{
147+
buf << ".";
148+
buf << log_get_pid();
149+
}
132150
buf << ".";
133151
buf << log_file_extension;
134152

@@ -213,15 +231,6 @@ inline std::string log_filename_generator_impl(const std::string & log_file_base
213231
#define LOG_TEE_FLF_VAL ,""
214232
#endif
215233

216-
// Utility for synchronizing log configuration state
217-
// since std::optional was introduced only in c++17
218-
enum LogTriState
219-
{
220-
LogTriStateSame,
221-
LogTriStateFalse,
222-
LogTriStateTrue
223-
};
224-
225234
// INTERNAL, DO NOT USE
226235
// USE LOG() INSTEAD
227236
//
@@ -315,16 +324,23 @@ enum LogTriState
315324
#endif
316325

317326
// INTERNAL, DO NOT USE
318-
inline FILE *log_handler1_impl(bool change = false, LogTriState disable = LogTriStateSame, const std::string & filename = LOG_DEFAULT_FILE_NAME, FILE *target = nullptr)
327+
inline FILE *log_handler1_impl(bool change = false, LogTriState append = LogTriStateSame, LogTriState disable = LogTriStateSame, const std::string & filename = LOG_DEFAULT_FILE_NAME, FILE *target = nullptr)
319328
{
320-
static bool _initialized{false};
321-
static bool _disabled{(filename.empty() && target == nullptr)};
329+
static bool _initialized = false;
330+
static bool _append = false;
331+
static bool _disabled = filename.empty() && target == nullptr;
322332
static std::string log_current_filename{filename};
323333
static FILE *log_current_target{target};
324334
static FILE *logfile = nullptr;
325335

326336
if (change)
327337
{
338+
if (append != LogTriStateSame)
339+
{
340+
_append = append == LogTriStateTrue;
341+
return logfile;
342+
}
343+
328344
if (disable == LogTriStateTrue)
329345
{
330346
// Disable primary target
@@ -377,7 +393,7 @@ inline FILE *log_handler1_impl(bool change = false, LogTriState disable = LogTri
377393
}
378394
}
379395

380-
logfile = fopen(filename.c_str(), "w");
396+
logfile = fopen(filename.c_str(), _append ? "a" : "w");
381397
}
382398

383399
if (!logfile)
@@ -398,9 +414,9 @@ inline FILE *log_handler1_impl(bool change = false, LogTriState disable = LogTri
398414
}
399415

400416
// INTERNAL, DO NOT USE
401-
inline FILE *log_handler2_impl(bool change = false, LogTriState disable = LogTriStateSame, FILE *target = nullptr, const std::string & filename = LOG_DEFAULT_FILE_NAME)
417+
inline FILE *log_handler2_impl(bool change = false, LogTriState append = LogTriStateSame, LogTriState disable = LogTriStateSame, FILE *target = nullptr, const std::string & filename = LOG_DEFAULT_FILE_NAME)
402418
{
403-
return log_handler1_impl(change, disable, filename, target);
419+
return log_handler1_impl(change, append, disable, filename, target);
404420
}
405421

406422
// Disables logs entirely at runtime.
@@ -411,7 +427,7 @@ inline FILE *log_handler2_impl(bool change = false, LogTriState disable = LogTri
411427
// INTERNAL, DO NOT USE
412428
inline FILE *log_disable_impl()
413429
{
414-
return log_handler1_impl(true, LogTriStateTrue);
430+
return log_handler1_impl(true, LogTriStateSame, LogTriStateTrue);
415431
}
416432

417433
// Enables logs at runtime.
@@ -420,19 +436,31 @@ inline FILE *log_disable_impl()
420436
// INTERNAL, DO NOT USE
421437
inline FILE *log_enable_impl()
422438
{
423-
return log_handler1_impl(true, LogTriStateFalse);
439+
return log_handler1_impl(true, LogTriStateSame, LogTriStateFalse);
424440
}
425441

426442
// Sets target fir logs, either by a file name or FILE* pointer (stdout, stderr, or any valid FILE*)
427443
#define log_set_target(target) log_set_target_impl(target)
428444

429445
// INTERNAL, DO NOT USE
430-
inline FILE *log_set_target_impl(const std::string & filename) { return log_handler1_impl(true, LogTriStateSame, filename); }
431-
inline FILE *log_set_target_impl(FILE *target) { return log_handler2_impl(true, LogTriStateSame, target); }
446+
inline FILE *log_set_target_impl(const std::string & filename) { return log_handler1_impl(true, LogTriStateSame, LogTriStateSame, filename); }
447+
inline FILE *log_set_target_impl(FILE *target) { return log_handler2_impl(true, LogTriStateSame, LogTriStateSame, target); }
432448

433449
// INTERNAL, DO NOT USE
434450
inline FILE *log_handler() { return log_handler1_impl(); }
435451

452+
// Enable or disable creating separate log files for each run.
453+
// can ONLY be invoked BEFORE first log use.
454+
#define log_multilog(enable) log_filename_generator_impl((enable) ? LogTriStateTrue : LogTriStateFalse, "", "")
455+
// Enable or disable append mode for log file.
456+
// can ONLY be invoked BEFORE first log use.
457+
#define log_append(enable) log_append_impl(enable)
458+
// INTERNAL, DO NOT USE
459+
inline FILE *log_append_impl(bool enable)
460+
{
461+
return log_handler1_impl(true, enable ? LogTriStateTrue : LogTriStateFalse, LogTriStateSame);
462+
}
463+
436464
inline void log_test()
437465
{
438466
log_disable();
@@ -494,6 +522,18 @@ inline bool log_param_single_parse(const std::string & param)
494522
return true;
495523
}
496524

525+
if (param == "--log-new")
526+
{
527+
log_multilog(true);
528+
return true;
529+
}
530+
531+
if (param == "--log-append")
532+
{
533+
log_append(true);
534+
return true;
535+
}
536+
497537
return false;
498538
}
499539

@@ -523,7 +563,9 @@ inline void log_print_usage()
523563
printf(" --log-disable Disable trace logs\n");
524564
printf(" --log-enable Enable trace logs\n");
525565
printf(" --log-file Specify a log filename (without extension)\n");
526-
printf(" Log file will be tagged with unique ID and written as \"<name>.<ID>.log\"\n"); /* */
566+
printf(" --log-new Create a separate new log file on start. "
567+
"Each log file will have unique name: \"<name>.<ID>.log\"\n");
568+
printf(" --log-append Don't truncate the old log file.\n");
527569
}
528570

529571
#define log_dump_cmdline(argc, argv) log_dump_cmdline_impl(argc, argv)

0 commit comments

Comments
 (0)