From e98abcdda78e68da22e088d5a9aa881f59ad30ca Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Sat, 24 May 2025 22:01:21 -0500 Subject: [PATCH] initial logging try --- .moth/log | 20 ++++++++++ scripts/core/engine.js | 90 ++++++++++++++++++++++++++++++++++++++++++ test_log.js | 29 ++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 .moth/log create mode 100644 test_log.js diff --git a/.moth/log b/.moth/log new file mode 100644 index 00000000..9fa2e9bf --- /dev/null +++ b/.moth/log @@ -0,0 +1,20 @@ +{ + "console": { + "outputs": ["console"] + }, + "info": { + "outputs": ["file:logs/info.log"] + }, + "warning": { + "outputs": ["console", "file:logs/warnings.log"] + }, + "error": { + "outputs": ["console", "file:logs/errors.log", "actor:localhost:5678"] + }, + "debug": { + "outputs": ["file:logs/debug.log"] + }, + "audit": { + "outputs": ["file:logs/audit.log", "actor:audit-server:9000"] + } +} \ No newline at end of file diff --git a/scripts/core/engine.js b/scripts/core/engine.js index 038765bf..50fd93ca 100644 --- a/scripts/core/engine.js +++ b/scripts/core/engine.js @@ -166,6 +166,96 @@ console[prosperon.DOC] = { clear: "Clear console." } +// Initialize log system +var logConfig = {} +var logPath = '.moth/log' + +// Default configuration if no .moth/log exists +var defaultLogConfig = { + console: { outputs: ['console'] } +} + +// Try to load log configuration +if (io.exists(logPath)) { + try { + var logContent = io.slurp(logPath) + logConfig = JSON.parse(logContent) + } catch (e) { + console.warn(`Failed to parse ${logPath}, using default configuration: ${e.message}`) + logConfig = defaultLogConfig + } +} else { + logConfig = defaultLogConfig +} + +// Create global log object +globalThis.log = {} + +// Helper function to create a log function for a specific log level +function createLogFunction(logName, config) { + return function(expr) { + // If logging is not enabled for this level, do nothing + if (!config || !config.outputs || config.outputs.length === 0) return + + var timestamp = time.text(time.now(), "mb d yyyy h:nn:ss") + var message = `[${logName}] ${timestamp}: ${String(expr)}` + + // Process each output destination + for (var output of config.outputs) { + if (output === 'console') { + // Output to console + console.print(message + '\n') + } else if (output.startsWith('file:')) { + // Output to file + var filename = output.substring(5) + try { + var existing = io.exists(filename) ? io.slurp(filename) : '' + io.slurpwrite(filename, existing + message + '\n') + } catch (e) { + console.error(`Failed to write to log file ${filename}: ${e.message}`) + } + } else if (output.startsWith('actor:')) { + // Send to actor + var parts = output.substring(6).split(':') + var address = parts[0] + var port = parseInt(parts[1]) + + // Create an actor reference with the address and port + var logActor = create_actor({ + address: address, + port: port + }) + + // Send log message to the actor (defer if send not available yet) + try { + // Check if send is available + if (typeof send !== 'undefined') { + send(logActor, { + type: 'log', + level: logName, + message: expr, + timestamp: timestamp, + source: prosperon.id + }) + } else { + // If send is not available yet, just print to console as fallback + console.print(`[${logName}] (actor output pending): ${expr}\n`) + } + } catch (e) { + console.error(`Failed to send log to actor ${address}:${port}: ${e.message}`) + } + } else { + console.warn(`Unknown log output type: ${output}`) + } + } + } +} + +// Create log functions for each configured log level +for (var logName in logConfig) { + log[logName] = createLogFunction(logName, logConfig[logName]) +} + var BASEPATH = 'scripts/core/base.js' var script = io.slurp(BASEPATH) var fnname = "base" diff --git a/test_log.js b/test_log.js new file mode 100644 index 00000000..9aaab497 --- /dev/null +++ b/test_log.js @@ -0,0 +1,29 @@ +// Test script for the log statement system + +// Test console logging +log.console("This is a console log message"); + +// Test info logging (goes to file) +log.info("Application started"); +log.info("User logged in: user123"); + +// Test warning logging (goes to console and file) +log.warning("Memory usage is high"); + +// Test error logging (goes to console, file, and actor) +log.error("Failed to connect to database"); + +// Test debug logging (goes to file only) +log.debug("index: " + 42); +log.debug("Processing item: " + JSON.stringify({id: 1, name: "test"})); + +// Test audit logging (goes to file and actor) +if (log.audit) { + log.audit("User performed sensitive action"); +} + +// Test with expressions as per the spec +var index = 5; +log.debug("index value is: " + index); + +console.log("Log test completed. Check console output and log files."); \ No newline at end of file