From d2e8185d6fb40d0299c81c3fdfc244a9ccc6bade Mon Sep 17 00:00:00 2001 From: shash256 <111925100+shash256@users.noreply.github.com> Date: Mon, 18 Aug 2025 18:57:13 +0530 Subject: [PATCH 1/2] chore: reduce terminal log noise --- library/libsds.nim | 12 +++++++++++- .../requests/sds_message_request.nim | 2 +- src/reliability.nim | 6 +++--- src/rolling_bloom_filter.nim | 4 ++-- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/library/libsds.nim b/library/libsds.nim index 53d2a4e..ea95844 100644 --- a/library/libsds.nim +++ b/library/libsds.nim @@ -104,13 +104,23 @@ proc libsdsNimMain() {.importc.} # To control when the library has been initialized var initialized: Atomic[bool] -if defined(android): +when defined(android): # Redirect chronicles to Android System logs when compiles(defaultChroniclesStream.outputs[0].writer): defaultChroniclesStream.outputs[0].writer = proc( logLevel: LogLevel, msg: LogOutputStr ) {.raises: [].} = echo logLevel, msg +else: + # For non-android, configure Chronicles with a null writer to suppress logs + # or redirect to a proper logging mechanism + when compiles(defaultChroniclesStream.outputs[0].writer): + defaultChroniclesStream.outputs[0].writer = proc( + logLevel: LogLevel, msg: LogOutputStr + ) {.raises: [].} = + # Only log ERROR and FATAL levels to reduce verbosity + if logLevel >= LogLevel.ERROR: + echo "[nim-sds] ", logLevel, ": ", msg proc initializeLibrary() {.exported.} = if not initialized.exchange(true): diff --git a/library/sds_thread/inter_thread_communication/requests/sds_message_request.nim b/library/sds_thread/inter_thread_communication/requests/sds_message_request.nim index ea42519..704ce91 100644 --- a/library/sds_thread/inter_thread_communication/requests/sds_message_request.nim +++ b/library/sds_thread/inter_thread_communication/requests/sds_message_request.nim @@ -63,7 +63,7 @@ proc process*( let messageBytes = self.message.toSeq() let (unwrappedMessage, missingDeps, channelId) = unwrapReceivedMessage(rm[], messageBytes).valueOr: - error "UNWRAP_MESSAGE failed", error = error + debug "UNWRAP_MESSAGE failed", error = error return err("error processing UNWRAP_MESSAGE request: " & $error) let res = SdsUnwrapResponse(message: unwrappedMessage, missingDeps: missingDeps, channelId: channelId) diff --git a/src/reliability.nim b/src/reliability.nim index a39fac3..1c25445 100644 --- a/src/reliability.nim +++ b/src/reliability.nim @@ -55,7 +55,7 @@ proc reviewAckStatus(rm: ReliabilityManager, msg: SdsMessage) {.gcsafe.} = ) ) else: - error "Failed to deserialize bloom filter", error = bfResult.error + debug "Failed to deserialize bloom filter", error = bfResult.error rbf = none[RollingBloomFilter]() else: rbf = none[RollingBloomFilter]() @@ -106,7 +106,7 @@ proc wrapOutgoingMessage*( let bfResult = serializeBloomFilter(channel.bloomFilter.filter) if bfResult.isErr: - error "Failed to serialize bloom filter", channelId = channelId + debug "Failed to serialize bloom filter", channelId = channelId return err(ReliabilityError.reSerializationError) let msg = SdsMessage( @@ -230,7 +230,7 @@ proc unwrapReceivedMessage*( return ok((msg.content, missingDeps, channelId)) except Exception: - error "Failed to unwrap message", msg = getCurrentExceptionMsg() + debug "Failed to unwrap message", msg = getCurrentExceptionMsg() return err(ReliabilityError.reDeserializationError) proc markDependenciesMet*( diff --git a/src/rolling_bloom_filter.nim b/src/rolling_bloom_filter.nim index 190ab8a..cc9b98e 100644 --- a/src/rolling_bloom_filter.nim +++ b/src/rolling_bloom_filter.nim @@ -78,7 +78,7 @@ proc clean*(rbf: var RollingBloomFilter) {.gcsafe.} = # Initialize new filter var newFilter = initializeBloomFilter(rbf.maxCapacity, rbf.filter.errorRate).valueOr: - error "Failed to create new bloom filter", error = $error + debug "Failed to create new bloom filter", error = $error return # Keep most recent messages up to minCapacity @@ -93,7 +93,7 @@ proc clean*(rbf: var RollingBloomFilter) {.gcsafe.} = rbf.messages = newMessages rbf.filter = newFilter except Exception: - error "Failed to clean bloom filter", error = getCurrentExceptionMsg() + debug "Failed to clean bloom filter", error = getCurrentExceptionMsg() proc add*(rbf: var RollingBloomFilter, messageId: SdsMessageID) {.gcsafe.} = ## Adds a message ID to the rolling bloom filter. From f2cfd04cd3da69a05ab502bd6ce80bd611e9fdce Mon Sep 17 00:00:00 2001 From: shash256 <111925100+shash256@users.noreply.github.com> Date: Tue, 19 Aug 2025 11:33:12 +0530 Subject: [PATCH 2/2] feat: add file logging --- library/libsds.h | 3 +++ library/libsds.nim | 55 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/library/libsds.h b/library/libsds.h index 886d3cb..3453a9d 100644 --- a/library/libsds.h +++ b/library/libsds.h @@ -55,6 +55,9 @@ int SdsMarkDependenciesMet(void* ctx, int SdsStartPeriodicTasks(void* ctx, SdsCallBack callback, void* userData); +// Configure log file path for nim-sds logging +int SdsSetLogFile(const char* logFilePath); + #ifdef __cplusplus diff --git a/library/libsds.nim b/library/libsds.nim index ea95844..f4e4776 100644 --- a/library/libsds.nim +++ b/library/libsds.nim @@ -5,7 +5,7 @@ when defined(linux): {.passl: "-Wl,-soname,libsds.so".} -import std/[typetraits, tables, atomics], chronos, chronicles +import std/[typetraits, tables, atomics], chronos, chronicles, os, times, strutils import ./sds_thread/sds_thread, ./alloc, @@ -104,23 +104,52 @@ proc libsdsNimMain() {.importc.} # To control when the library has been initialized var initialized: Atomic[bool] +proc getLogFilePath(): string = + # Check for environment variable first, fallback to default location + let envPath = getEnv("SDS_LOG_FILE") + if envPath.len > 0: + return envPath + + # Default to a location that status-go can manage + let defaultDir = getEnv("SDS_LOG_DIR", "/tmp") + return joinPath(defaultDir, "nim-sds.log") + +proc writeToLogFile(logLevel: LogLevel, msg: LogOutputStr) {.raises: [].} = + try: + let logFile = getLogFilePath() + let timestamp = now().format("yyyy-MM-dd HH:mm:ss.fff") + let logLine = "[$1] [$2] $3\n".format(timestamp, $logLevel, $msg) + + # Create directory if it doesn't exist + let logDir = parentDir(logFile) + if not dirExists(logDir): + createDir(logDir) + + # Append to log file + let file = open(logFile, fmAppend) + defer: file.close() + file.write(logLine) + except: + # Fallback to console if file writing fails + echo "[nim-sds-fallback] ", logLevel, ": ", msg + when defined(android): - # Redirect chronicles to Android System logs when compiles(defaultChroniclesStream.outputs[0].writer): defaultChroniclesStream.outputs[0].writer = proc( logLevel: LogLevel, msg: LogOutputStr ) {.raises: [].} = echo logLevel, msg else: - # For non-android, configure Chronicles with a null writer to suppress logs - # or redirect to a proper logging mechanism when compiles(defaultChroniclesStream.outputs[0].writer): defaultChroniclesStream.outputs[0].writer = proc( logLevel: LogLevel, msg: LogOutputStr ) {.raises: [].} = - # Only log ERROR and FATAL levels to reduce verbosity + # Critical logs (ERROR, FATAL) are written to console if logLevel >= LogLevel.ERROR: echo "[nim-sds] ", logLevel, ": ", msg + else: + # All other logs are written to a file + writeToLogFile(logLevel, msg) proc initializeLibrary() {.exported.} = if not initialized.exchange(true): @@ -332,5 +361,21 @@ proc SdsStartPeriodicTasks( userData, ) +proc SdsSetLogFile( + logFilePath: cstring +): cint {.dynlib, exportc.} = + ## Sets the log file path for nim-sds logging + ## This allows applications to configure where nim-sds logs should be written + initializeLibrary() + + if logFilePath == nil: + return RET_ERR + + try: + putEnv("SDS_LOG_FILE", $logFilePath) + return RET_OK + except: + return RET_ERR + ### End of exported procs ################################################################################