From 185cf706a7380ffab42bbdd9fe9943e66805a5c2 Mon Sep 17 00:00:00 2001 From: andrewlalis Date: Tue, 18 Nov 2025 20:40:22 -0500 Subject: [PATCH] Upgrade to SLF4D 4.2.0, simplify config. --- finnow-api/dub.json | 1 + finnow-api/dub.selections.json | 14 ++++----- finnow-api/source/app.d | 47 ++------------------------- finnow-api/source/util/config.d | 56 +++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 51 deletions(-) create mode 100644 finnow-api/source/util/config.d diff --git a/finnow-api/dub.json b/finnow-api/dub.json index 35fae6d..fd42f97 100644 --- a/finnow-api/dub.json +++ b/finnow-api/dub.json @@ -7,6 +7,7 @@ "d2sqlite3": "~>1.0", "handy-http-starter": "~>1.6", "jwt4d": "~>0.0.2", + "scheduled": "~>1.4.0", "secured": "~>3.0" }, "description": "Backend API for Finnow.", diff --git a/finnow-api/dub.selections.json b/finnow-api/dub.selections.json index 86cc434..8297f07 100644 --- a/finnow-api/dub.selections.json +++ b/finnow-api/dub.selections.json @@ -1,26 +1,26 @@ { "fileVersion": 1, "versions": { - "asdf": { - "repository": "git+https://github.com/libmir/asdf.git", - "version": "7f77a3031975816b604a513ddeefbc9e514f236c" - }, + "asdf": "0.7.17+commit.5.g7f77a30", "d2sqlite3": "1.0.0", - "dxml": "0.4.4", + "dxml": "0.4.5", "handy-http-data": "1.3.0", "handy-http-handlers": "1.1.0", "handy-http-primitives": "1.8.1", "handy-http-starter": "1.6.0", - "handy-http-transport": "1.8.0", + "handy-http-transport": "1.10.0", "handy-http-websockets": "1.2.0", "jwt4d": "0.0.2", "mir-algorithm": "3.22.4", "mir-core": "1.7.3", "openssl": "3.3.4", "path-matcher": "1.2.0", + "photon": "0.18.11", + "scheduled": "1.4.0", "secured": "3.0.0", + "sharded-map": "2.7.0", "silly": "1.1.1", - "slf4d": "4.1.1", + "slf4d": "4.2.0", "streams": "3.6.0" } } diff --git a/finnow-api/source/app.d b/finnow-api/source/app.d index 4b3d203..9aeeeb8 100644 --- a/finnow-api/source/app.d +++ b/finnow-api/source/app.d @@ -3,25 +3,11 @@ import slf4d; import slf4d.default_provider; import api_mapping; - -struct AppConfig { - ushort port; - string webOrigin; - string logLevel; -} +import util.config; void main() { - const AppConfig config = readConfig(); - Level logLevel = Levels.INFO; - if (config.logLevel == "TRACE") { - logLevel = Levels.TRACE; - } else if (config.logLevel == "DEBUG") { - logLevel = Levels.DEBUG; - } else if (config.logLevel == "WARN") { - logLevel = Levels.WARN; - } else if (config.logLevel == "ERROR") { - logLevel = Levels.ERROR; - } + const config = readConfig(); + Level logLevel = getConfiguredLoggingLevel(config); auto provider = new DefaultProvider(logLevel); configureLoggingProvider(provider); infoF!"Loaded app config: port = %d, webOrigin = %s"(config.port, config.webOrigin); @@ -31,30 +17,3 @@ void main() { HttpTransport transport = new TaskPoolHttp1Transport(mapApiHandlers(config.webOrigin), transportConfig); transport.start(); } - -AppConfig readConfig() { - import std.file : exists, readText; - import std.json; - import std.conv : to; - - AppConfig defaultConfig = AppConfig( - 8080, - "http://localhost:5173", - "INFO" - ); - // Local dev environment if no config is given. - if (!exists("finnow-api-config.json")) { - return defaultConfig; - } - JSONValue obj = parseJSON(readText("finnow-api-config.json")); - if ("port" in obj.object) { - defaultConfig.port = obj.object["port"].integer.to!ushort; - } - if ("webOrigin" in obj.object) { - defaultConfig.webOrigin = obj.object["webOrigin"].str; - } - if ("logLevel" in obj.object) { - defaultConfig.logLevel = obj.object["logLevel"].str; - } - return defaultConfig; -} diff --git a/finnow-api/source/util/config.d b/finnow-api/source/util/config.d new file mode 100644 index 0000000..75a1831 --- /dev/null +++ b/finnow-api/source/util/config.d @@ -0,0 +1,56 @@ +module util.config; + +import std.stdio; +import slf4d; + +private const CONFIG_FILE = "finnow-api-config.json"; + +struct AppConfig { + ushort port; + string webOrigin; + string logLevel; +} + +Level getConfiguredLoggingLevel(in AppConfig cfg) { + try { + return parseLoggingLevel(cfg.logLevel); + } catch (LoggingException e) { + return Levels.INFO; + } +} + +AppConfig readConfig() { + import std.file : exists, readText; + import std.json; + import std.conv : to; + + AppConfig defaultConfig = AppConfig( + 8080, + "http://localhost:5173", + "INFO" + ); + // Local dev environment if no config is given. + if (!exists(CONFIG_FILE)) { + return defaultConfig; + } + JSONValue obj; + try { + obj = parseJSON(readText(CONFIG_FILE)); + } catch (Exception e) { + stderr.writefln!"Failed to read config from file %s, using default config as a fallback: %s"( + CONFIG_FILE, + e.msg + ); + return defaultConfig; + } + if ("port" in obj.object) { + defaultConfig.port = obj.object["port"].integer.to!ushort; + } + if ("webOrigin" in obj.object) { + defaultConfig.webOrigin = obj.object["webOrigin"].str; + } + if ("logLevel" in obj.object) { + defaultConfig.logLevel = obj.object["logLevel"].str; + } + return defaultConfig; +} \ No newline at end of file