code wiki / (root) / nx_log_gate.nx

nx_log_gate.nx source

↩ module page · 116 lines · 5417 B

1// nx_log_gate.nx -- the gate for the structured logger 32 modules import. 2// WHY: nx_gensota gen-3 worklist. The module's header makes a STRONG, testable promise -- 3// "deterministic by default: monotonic sequence counter, not wall-clock. Tests can snapshot 4// logs BYTE-FOR-BYTE" -- and a byte-for-byte snapshot claim is only true if the format is 5// fixed-width and the counter has no holes. 6// ★THE TOOTH THAT MATTERS (T4): A FILTERED EVENT MUST NOT ADVANCE THE SEQUENCE. If a dropped 7// event consumed a sequence number, every snapshot would depend on the CURRENT LOG LEVEL -- 8// two runs at different verbosity could never be diffed, which is the whole point of the design. 9// Nothing else in the system would notice; the lines still look perfectly well-formed. 10// The context takes an out_fd directly, so this gate writes to a real file and READS THE BYTES 11// BACK -- a writer is only tested by a read-back. 12// ⚠DELIBERATELY NOT TESTED: nx_log_fatal, which exits the process by contract (NX_LOG_EXIT=200). 13// A gate that called it would kill its own harness; its exit path is proven by inspection here 14// and would need a fork to test honestly -- declared, not silently skipped. 15// license_tier: ORIGINAL expect_exit: 0 No hw writes (Rule 26). 16import "nx_syscalls.nx" 17import "nx_gate_verdict.nx" 18import "nx_log.nx" 19 20const NLG_MODE: i64 = 0x1a4 21const NLG_CAP: i64 = 4096 22 23func nlg_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 24func nlg_eqn(a: *u8, b: *u8, n: i64) -> i64 { 25 var i: i64 = 0 26 while i < n { if a[i] != b[i] { return 0 } i = i + 1 } 27 return 1 28} 29// read whole file into buf; returns length or -1 30func nlg_slurp(path: *u8, buf: *u8) -> i64 { 31 let lenp: *i64 = sys_mmap(16) as *i64 32 lenp[0] = 0 33 let src: *u8 = sys_read_file(path, lenp) 34 if (src as i64) == 0 { return 0 - 1 } 35 var n: i64 = lenp[0] 36 if n > NLG_CAP - 1 { n = NLG_CAP - 1 } 37 var i: i64 = 0 38 while i < n { buf[i] = src[i]; i = i + 1 } 39 buf[n] = 0 as u8 40 return n 41} 42 43func main() -> i64 { 44 let ctr: *i64 = gv_ctr() 45 gv_head("NX-LOG-GATE -- the byte-for-byte snapshot promise, made testable" as *u8) 46 let path: *u8 = "knowledge/status/log_gate_capture.tmp\x00" as *u8 47 let buf: *u8 = sys_mmap(NLG_CAP) 48 49 var t1: i64 = 1 50 if nlg_eqn(nx_log_level_name(NX_LOG_TRACE), "TRACE" as *u8, 5) == 0 { t1 = 0 } 51 if nlg_eqn(nx_log_level_name(NX_LOG_ERROR), "ERROR" as *u8, 5) == 0 { t1 = 0 } 52 if nlg_eqn(nx_log_level_name(NX_LOG_FATAL), "FATAL" as *u8, 5) == 0 { t1 = 0 } 53 if nlg_eqn(nx_log_level_name(99), "?????" as *u8, 5) == 0 { t1 = 0 } 54 gv_check("T1 level names are FIXED-WIDTH 5 and an unknown level is ????? not a crash" as *u8, t1, ctr) 55 56 var t2: i64 = 1 57 if NX_LOG_TRACE >= NX_LOG_DEBUG { t2 = 0 } 58 if NX_LOG_DEBUG >= NX_LOG_INFO { t2 = 0 } 59 if NX_LOG_INFO >= NX_LOG_WARN { t2 = 0 } 60 if NX_LOG_WARN >= NX_LOG_ERROR { t2 = 0 } 61 if NX_LOG_ERROR >= NX_LOG_FATAL { t2 = 0 } 62 gv_check("T2 levels STRICTLY ORDERED, so a >= filter is meaningful" as *u8, t2, ctr) 63 64 let fd: i64 = sys_openat_wr(path, NLG_MODE) 65 var t3: i64 = 0 66 if fd >= 0 { t3 = 1 } 67 gv_check("T3 capture file opened (instrument is able to observe)" as *u8, t3, ctr) 68 69 let c: *NxLogContext = nx_log_new(NX_LOG_INFO, fd) 70 nx_log_emit(c, NX_LOG_INFO, "gate.tag" as *u8, "first" as *u8) 71 nx_log_emit(c, NX_LOG_DEBUG, "gate.tag" as *u8, "dropped-below-min" as *u8) 72 nx_log_emit(c, NX_LOG_TRACE, "gate.tag" as *u8, "also-dropped" as *u8) 73 nx_log_emit(c, NX_LOG_ERROR, "gate.tag" as *u8, "second" as *u8) 74 sys_close(fd) 75 76 // ★THE LOAD-BEARING TOOTH 77 var t4: i64 = 0 78 if c.seq == 2 { if c.drop_cnt == 2 { t4 = 1 } } 79 gv_check("T4 a FILTERED event does NOT advance seq (snapshot stays level-independent)" as *u8, t4, ctr) 80 81 let n: i64 = nlg_slurp(path, buf) 82 var t5: i64 = 0 83 if n > 0 { t5 = 1 } 84 gv_check("T5 read-back returned bytes (not an empty-file false pass)" as *u8, t5, ctr) 85 86 // '00000000 INFO gate.tag first\n' -- 8-digit zero-padded seq, then a space 87 var t6: i64 = 0 88 if n > 9 { 89 if nlg_eqn(buf, "00000000 " as *u8, 9) == 1 { t6 = 1 } 90 } 91 gv_check("T6 seq is 8-digit ZERO-PADDED and starts at 0 for a fresh context" as *u8, t6, ctr) 92 93 var t7: i64 = 0 94 if n > 14 { if nlg_eqn(buf, "00000000 INFO " as *u8, 14) == 1 { t7 = 1 } } 95 gv_check("T7 line shape: <seq> <LEVEL-padded> ... exactly as documented" as *u8, t7, ctr) 96 97 // the SECOND emitted line must be seq 1 -- the dropped pair left no hole 98 var t8: i64 = 0 99 var i: i64 = 0 100 var nl: i64 = 0 - 1 101 while i < n { if buf[i] == (10 as u8) { if nl < 0 { nl = i } } i = i + 1 } 102 if nl > 0 { if n > nl + 9 { 103 let p2: *u8 = ((buf as i64) + nl + 1) as *u8 104 if nlg_eqn(p2, "00000001 " as *u8, 9) == 1 { t8 = 1 } 105 } } 106 gv_check("T8 the next EMITTED line is seq 00000001 -- the drops left NO HOLE" as *u8, t8, ctr) 107 108 // NEGATIVE CONTROL: the byte comparator must be able to fail. 109 var t9: i64 = 0 110 if nlg_eqn(buf, "00000001 " as *u8, 9) == 0 { if nlg_eqn(nx_log_level_name(NX_LOG_INFO), "WARN " as *u8, 5) == 0 { t9 = 1 } } 111 gv_check("T9 NEG-CONTROL: wrong seq and wrong level name are REJECTED" as *u8, t9, ctr) 112 113 let rc: i64 = gv_verdict("LOG-GATE" as *u8, ctr, "filter does not perturb the sequence; format read back" as *u8) 114 sys_exit(rc) 115 return rc 116}