// ═══════════════════════════════════════════════════════════ // logger.ks // CSV logger with buffered writes. // // Usage: // local LOGGER to loggerCreate("0:/logs/flight.csv", list("time", "altitude", "apoapsis")). // loggerUpdate(LOGGER, list(time:seconds, altitude, apoapsis)). // loggerFlush(LOGGER). // call at end of script to flush remaining buffer // ═══════════════════════════════════════════════════════════ // ── Creates a logger and writes the CSV header. // Parameters: // filePath : string — destination path, e.g. "logs/flight.csv" // columns : list — ordered list of column name strings // flushPeriod : scalar — seconds between buffer flushes (default 1.0) // Returns a logger lexicon to be passed to loggerUpdate / loggerFlush. function loggerCreate { parameter filePath. parameter columns. parameter flushPeriod is 1.0. // Create or overwrite the file and write the header row if not archive:exists(filePath) archive:create(filePath). local f to archive:open(filePath). f:clear(). f:writeln(_loggerFormatRow(columns)). local l to lexicon( "file", f, "columns", columns, "buffer", list(), "flushPeriod", flushPeriod, "lastFlush", time:seconds ). return l. } // ── Appends a data row to the buffer. // Values must be in the same order as the columns list passed to loggerCreate. // Flushes the buffer to disk if the flush period has elapsed. function loggerUpdate { parameter l. parameter values. l["buffer"]:add(_loggerFormatRow(values)). if time:seconds - l["lastFlush"] >= l["flushPeriod"] { loggerFlush(l). } } // ── Flushes all buffered rows to disk immediately. // Call at the end of a script to ensure no data is lost. function loggerFlush { parameter l. local f to l["file"]. local buf to l["buffer"]. local i to 0. until i >= buf:length { f:writeln(buf[i]). set i to i + 1. } buf:clear(). set l["lastFlush"] to time:seconds. } // ── Formats a list of values as a CSV row string. function _loggerFormatRow { parameter values. local row to "". local i to 0. until i >= values:length { if i > 0 { set row to row + ",". } set row to row + values[i]. set i to i + 1. } return row. }