open Wire let max_payload_len = 64 let record_size = 76 type severity = DEBUG | INFO | WARNING | ERROR | FATAL let severity_to_int = function | DEBUG -> 0 | INFO -> 1 | WARNING -> 2 | ERROR -> 3 | FATAL -> 4 let severity_of_int = function | 0 -> Some DEBUG | 1 -> Some INFO | 2 -> Some WARNING | 3 -> Some ERROR | 4 -> Some FATAL | _ -> None let pp_severity ppf s = Fmt.string ppf (match s with | DEBUG -> "DEBUG" | INFO -> "INFO" | WARNING -> "WARNING" | ERROR -> "ERROR" | FATAL -> "FATAL") type t = { timestamp : int; severity : int; reserved : int; event_code : int; payload_len : int; reserved2 : int; payload : string; } let codec = let open Codec in record "EventLog" (fun timestamp severity reserved event_code payload_len reserved2 payload -> { timestamp; severity; reserved; event_code; payload_len; reserved2; payload; }) |+ field "timestamp" uint32be (fun t -> t.timestamp) |+ field "severity" uint8 (fun t -> t.severity) |+ field "reserved" uint8 (fun t -> t.reserved) |+ field "event_code" uint16be (fun t -> t.event_code) |+ field "payload_len" uint16be (fun t -> t.payload_len) |+ field "reserved2" uint16be (fun t -> t.reserved2) |+ field "payload" (byte_array ~size:(int max_payload_len)) (fun t -> t.payload) |> seal let pad_to n s = let slen = String.length s in if slen >= n then String.sub s 0 n else let b = Bytes.make n '\x00' in Bytes.blit_string s 0 b 0 slen; Bytes.unsafe_to_string b let v ~timestamp sev ~event_code payload = let payload_len = min max_payload_len (String.length payload) in { timestamp; severity = severity_to_int sev; reserved = 0; event_code; payload_len; reserved2 = 0; payload = pad_to max_payload_len payload; } let payload_bytes t = String.sub t.payload 0 (min t.payload_len (String.length t.payload)) let pp ppf t = let sev = match severity_of_int t.severity with | Some s -> Fmt.str "%a" pp_severity s | None -> Fmt.str "?%d" t.severity in Fmt.pf ppf "@[event(t=%d %s code=%d payload=%S)@]" t.timestamp sev t.event_code (payload_bytes t) let equal a b = a.timestamp = b.timestamp && a.severity = b.severity && a.event_code = b.event_code && a.payload_len = b.payload_len && String.equal a.payload b.payload