From a41641398d09f8457a33445b73a1a402c08c87cd Mon Sep 17 00:00:00 2001 From: euxane Date: Sun, 24 Nov 2024 17:17:02 +0100 Subject: logger: add module --- logger.nim | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 logger.nim diff --git a/logger.nim b/logger.nim new file mode 100644 index 0000000..a4d90a0 --- /dev/null +++ b/logger.nim @@ -0,0 +1,79 @@ +# tickwatch +# Author: Euxane TRAN-GIRARD +# Licence: EUPL-1.2 + +import std/sugar +import std/math +import std/unicode +import std/times +import std/os + + +const + TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mmZZZ " + SKIPPED_SYMBOL = "." + UNKNOWN_SYMBOL = "!" + NUMERIC_SYMBOLS* = "123456789".toRunes + UNICODE_SYMBOLS* = "_▁▂▃▄▅▆▇█".toRunes + + +type Scale* = proc(val: float): float {.noSideEffect.} + +proc indicator(symbols: seq[Rune], min, max, val: float, scale: Scale): Rune = + let division = scale(max - min) / float(symbols.len) + let bucket = int(scale(val - min) / division) + symbols[bucket.clamp(0, symbols.len - 1)] + +proc indicator*(symbols: seq[Rune], min, max, val: int, scale: Scale): Rune = + symbols.indicator(min.float, max.float, val.float, scale) + +func millisecond(t: DateTime): int = + t.nanosecond div (1_000_000) + +func msUntilNextSec(t: DateTime): int = + 1000 - t.millisecond + 1 + +proc puts(f: File, s: string) = + f.write s + f.flushFile + +proc puts(f: File, r: Rune) = + f.puts r.toUTF8 + +proc loop*(probe: (timeout: Duration) -> int, getSymbol: (int) -> Rune) = + while true: + stdout.puts now().format(TIMESTAMP_FORMAT) + + for tick in 0..<60: + let t = now() + if tick < t.second: + stdout.puts SKIPPED_SYMBOL + continue + + let timeout = initDuration(milliseconds = t.msUntilNextSec) + try: + let val = probe(timeout) + stdout.puts getSymbol(val) + except CatchableError: + stdout.puts UNKNOWN_SYMBOL + + let tAfter = now() + if tAfter < t + timeout: + sleep(tAfter.msUntilNextSec) + + stdout.puts "\n" + +proc flushAndQuit*() {.noconv.} = + stdout.puts "\n" + quit(0) + + +when defined(test): + import std/unittest + import std/sequtils + + suite "logger": + test "indicator value": + proc id(val: float): float = val + let indics = (0..30).mapIt(NUMERIC_SYMBOLS.indicator(5, 20, it, id)) + check indics.deduplicate(isSorted = true) == NUMERIC_SYMBOLS -- cgit v1.2.3