2 Support for logging to file. Logging is made to a file called
3 matilda_YYMMDD_XXXXXX.log where YYMMDD is the date and XXXXXX is a random
4 string. When logging a mask of log categories specifies the types of messages to
5 be written to file. Having a very high degree of detail in very fast matches
6 actively hurts the performance.
8 Writing to files is synchronous (with fsync) to avoid loss of data in case of
9 crashes, but it is impossible to guarantee this in all cases.
17 #include <time.h> /* localtime */
20 #include "amaf_rave.h"
24 #include "game_record.h"
30 #include "time_ctrl.h"
34 static int log_file
= -1;
37 By default print everything to standard output. Only the main matilda executable
38 changes this by default.
40 static u16 log_mode
= (LOG_MODE_ERROR
| LOG_MODE_WARN
| LOG_MODE_PROT
| LOG_MODE_INFO
| LOG_MODE_DEBUG
);
41 static u16 log_dest
= LOG_DEST_STDF
;
44 For non-default values for build_info
46 extern u64 max_size_in_mbs
;
47 extern double prior_stone_scale_factor
;
48 extern u16 prior_even
;
49 extern u16 prior_nakade
;
50 extern u16 prior_self_atari
;
51 extern u16 prior_attack
;
52 extern u16 prior_defend
;
53 extern u16 prior_pat3
;
54 extern u16 prior_near_last
;
55 extern u16 prior_line2
;
56 extern u16 prior_line3
;
57 extern u16 prior_empty
;
58 extern u16 prior_corner
;
59 extern double rave_equiv
;
60 extern u16 pl_skip_saving
;
61 extern u16 pl_skip_nakade
;
62 extern u16 pl_skip_pattern
;
63 extern u16 pl_skip_capture
;
64 extern u16 pl_ban_self_atari
;
67 static void open_log_file();
70 const char * severity
,
76 Sets the logging messages that are written to file based on a mask of the
77 combination of available message types. See flog.h for more information.
79 void flog_config_modes(
82 if (new_mode
== log_mode
) {
92 idx
+= snprintf(s
+ idx
, MAX_PAGE_SIZ
- idx
, "log mask changed: ");
94 snprintf(s
+ idx
, MAX_PAGE_SIZ
- idx
, "none");
96 if (log_mode
& LOG_MODE_ERROR
) {
97 idx
+= snprintf(s
+ idx
, MAX_PAGE_SIZ
- idx
, "crit,");
99 if (log_mode
& LOG_MODE_WARN
) {
100 idx
+= snprintf(s
+ idx
, MAX_PAGE_SIZ
- idx
, "warn,");
102 if (log_mode
& LOG_MODE_PROT
) {
103 idx
+= snprintf(s
+ idx
, MAX_PAGE_SIZ
- idx
, "prot,");
105 if (log_mode
& LOG_MODE_INFO
) {
106 idx
+= snprintf(s
+ idx
, MAX_PAGE_SIZ
- idx
, "info,");
108 if (log_mode
& LOG_MODE_DEBUG
) {
109 idx
+= snprintf(s
+ idx
, MAX_PAGE_SIZ
- idx
, "dbug,");
120 if (log_file
!= -1) {
121 flog(NULL
, NULL
, "logging disabled");
132 Define the destinations for logging.
134 void flog_config_destinations(
140 static bool ends_in_new_line(
145 return (l
> 0) && (s
[l
- 1] == '\n');
148 static bool multiline(
151 char * t
= strchr(s
, '\n');
153 return !(t
== NULL
|| t
== s
+ (strlen(s
) - 1));
157 const char * restrict severity
,
158 const char * restrict context
,
159 const char * restrict msg
165 /* Prepare payload */
170 if (severity
== NULL
) {
173 if (context
== NULL
) {
177 if (multiline(msg
)) {
178 snprintf(s
, MAX_PAGE_SIZ
, "%s | %4s | %4s | [\n%s%s]\n", ts
, severity
, context
, msg
, ends_in_new_line(msg
) ? "" : "\n");
180 snprintf(s
, MAX_PAGE_SIZ
, "%s | %4s | %4s | %s%s", ts
, severity
, context
, msg
, ends_in_new_line(msg
) ? "" : "\n");
183 if (log_dest
& LOG_DEST_FILE
) {
186 write(log_file
, s
, len
);
190 if (log_dest
& LOG_DEST_STDF
) {
191 fprintf(stderr
, "%s", s
);
198 static void open_log_file() {
199 if (log_file
== -1) {
200 char * log_filename
= alloc();
201 log_file
= create_and_open_file(log_filename
, MAX_PAGE_SIZ
, "matilda", "log");
202 release(log_filename
);
204 if (log_file
== -1) {
205 fprintf(stderr
, "Failed to create log file.\n");
206 log_dest
&= ~LOG_DEST_FILE
;
213 idx
+= snprintf(s
+ idx
, MAX_PAGE_SIZ
- idx
, "logging enabled with mask: ");
216 snprintf(s
+ idx
, MAX_PAGE_SIZ
- idx
, "none");
218 if (log_mode
& LOG_MODE_ERROR
) {
219 idx
+= snprintf(s
+ idx
, MAX_PAGE_SIZ
- idx
, "crit,");
221 if (log_mode
& LOG_MODE_WARN
) {
222 idx
+= snprintf(s
+ idx
, MAX_PAGE_SIZ
- idx
, "warn,");
224 if (log_mode
& LOG_MODE_PROT
) {
225 idx
+= snprintf(s
+ idx
, MAX_PAGE_SIZ
- idx
, "prot,");
227 if (log_mode
& LOG_MODE_INFO
) {
228 idx
+= snprintf(s
+ idx
, MAX_PAGE_SIZ
- idx
, "info,");
230 if (log_mode
& LOG_MODE_DEBUG
) {
231 idx
+= snprintf(s
+ idx
, MAX_PAGE_SIZ
- idx
, "dbug,");
244 Obtain a textual description of the capabilities and configuration options of
245 matilda. This mostly concerns compile time constants.
246 RETURNS string with build information
252 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Matilda build information\n");
254 if (MATILDA_RELEASE_MODE
) {
255 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Compiled for: release\n");
257 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Compiled for: debugging\n");
260 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Version: %s\n", MATILDA_VERSION
);
261 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Data folder: %s\n", data_folder());
263 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Board size: %ux%u\n", BOARD_SIZ
, BOARD_SIZ
);
265 char * kstr
= alloc();
266 komi_to_string(kstr
, komi
);
267 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Komidashi: %s stones\n", kstr
);
270 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Resign/pass bellow win rate: %.2f\n", UCT_RESIGN_WINRATE
);
271 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " Minimum simulations: %u\n", UCT_RESIGN_PLAYOUTS
);
273 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Can stop MCTS early: %s\n", YN(UCT_CAN_STOP_EARLY
));
275 if (UCT_CAN_STOP_EARLY
) {
276 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " At win rate: %.2f\n", UCT_EARLY_WINRATE
);
279 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Winrate for passing always: %.2f\n", JUST_PASS_WINRATE
);
282 format_mem_size(s
, max_size_in_mbs
* 1048576);
283 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Transpositions table memory: %s\n", s
);
286 if (pl_skip_saving
) {
287 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " Chance of skipping save: %u/128\n", pl_skip_saving
);
289 if (pl_skip_capture
) {
290 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " Chance of skipping capture: %u/128\n", pl_skip_capture
);
292 if (pl_skip_pattern
) {
293 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " Chance of skipping pattern: %u/128\n", pl_skip_pattern
);
295 if (pl_skip_nakade
) {
296 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " Chance of skipping nakade: %u/128\n", pl_skip_nakade
);
298 if (pl_ban_self_atari
) {
299 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " Chance of prohibiting self-atari: %u/128\n", pl_ban_self_atari
);
302 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " Use pattern weights: %s\n", YN(USE_PATTERN_WEIGHTS
));
303 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Use AMAF/RAVE: %s\n", YN(USE_AMAF_RAVE
));
306 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " MSE equiv: %.2f\n", rave_equiv
);
307 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " Criticality threshold: %u\n", CRITICALITY_THRESHOLD
);
310 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " Stone value scale factor: %.1f\n", prior_stone_scale_factor
);
311 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " Even: %u (x2)\n", prior_even
);
312 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " Nakade: %u\n", prior_nakade
);
313 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " Self-atari: -%u\n", prior_self_atari
);
314 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " Attack 1/2 lib group: %u\n", prior_attack
);
315 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " Defend 1/2 lib group: %u\n", prior_defend
);
316 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " MoGo patterns: %u\n", prior_pat3
);
317 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " Near last play: %u\n", prior_near_last
);
318 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " Empty L2/3/other: -%u/%u/%u\n", prior_line2
, prior_line3
, prior_empty
);
319 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, " Corners: -%u\n", prior_corner
);
321 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Max UCT depth: %u\n", MAX_UCT_DEPTH
);
322 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "UCT expansion delay: %u\n", UCT_EXPANSION_DELAY
);
323 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Playout depth over number of empty points: %u\n", MAX_PLAYOUT_DEPTH_OVER_EMPTY
);
324 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Mercy threshold: %u stones\n", MERCY_THRESHOLD
);
326 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Constant latency compensation: %u ms\n", LATENCY_COMPENSATION
);
327 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Time allotment factor: %.2f\n", TIME_ALLOT_FACTOR
);
333 num_threads
= omp_get_num_threads();
336 if (DEFAULT_NUM_THREADS
== 0) {
337 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Default number of threads: automatic (%u)\n", num_threads
);
339 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Default number of threads: %u (%u)\n", DEFAULT_NUM_THREADS
, num_threads
);
341 idx
+= snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "Maximum number of threads: %u\n", MAXIMUM_NUM_THREADS
);
342 snprintf(dst
+ idx
, MAX_PAGE_SIZ
- idx
, "\n");
346 Log a message with verbosity level critical.
349 const char * restrict ctx
,
350 const char * restrict msg
352 if ((log_mode
& LOG_MODE_ERROR
) != 0) {
353 flog("crit", ctx
, msg
);
354 flog(NULL
, NULL
, "execution aborted due to program panic");
356 fprintf(stderr
, "execution aborted due to program panic\n");
364 Log a message with verbosity level warning.
367 const char * restrict ctx
,
368 const char * restrict msg
370 if ((log_mode
& LOG_MODE_WARN
) != 0) {
371 flog("warn", ctx
, msg
);
377 Log a message with verbosity level communication protocol.
380 const char * restrict ctx
,
381 const char * restrict msg
383 if ((log_mode
& LOG_MODE_PROT
) != 0) {
384 flog("prot", ctx
, msg
);
390 Log a message with verbosity level informational.
393 const char * restrict ctx
,
394 const char * restrict msg
396 if ((log_mode
& LOG_MODE_INFO
) != 0) {
397 flog("info", ctx
, msg
);
403 Log a message with verbosity level debug.
406 const char * restrict ctx
,
407 const char * restrict msg
409 if ((log_mode
& LOG_MODE_DEBUG
) != 0) {
410 flog("dbug", ctx
, msg
);