-
Notifications
You must be signed in to change notification settings - Fork 394
Introduce log.file config option to log to file #837
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,7 +29,7 @@ | |
|
|
||
| Implements logging functions. This file is based on the concepts from | ||
| SoftHSM v1 but extends the logging functions with support for a variable | ||
| argument list as defined in stdarg (3). | ||
| argument list as defined in stdarg (3) and logging to file. | ||
| *****************************************************************************/ | ||
|
|
||
| #include "config.h" | ||
|
|
@@ -38,9 +38,19 @@ | |
| #include <stdio.h> | ||
| #include <sstream> | ||
| #include <vector> | ||
| #include <time.h> | ||
| #ifdef _WIN32 | ||
| #include <windows.h> | ||
| #include <process.h> | ||
| #else | ||
| #include <unistd.h> | ||
| #endif | ||
| #include "log.h" | ||
| #include "MutexFactory.h" | ||
|
|
||
| int softLogLevel = LOG_DEBUG; | ||
| static FILE* logFile = nullptr; | ||
| static Mutex* logMutex = nullptr; | ||
bukka marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| bool setLogLevel(const std::string &loglevel) | ||
| { | ||
|
|
@@ -69,6 +79,95 @@ bool setLogLevel(const std::string &loglevel) | |
| return true; | ||
| } | ||
|
|
||
| bool setLogFile(const std::string &logFilePath) | ||
| { | ||
| // Quick return without creating mutex for default configuration | ||
| if (logFilePath.empty() && logFile == nullptr) | ||
| { | ||
| return true; | ||
| } | ||
|
|
||
| if (logMutex == nullptr) | ||
| { | ||
| // Create mutex for later access | ||
| logMutex = MutexFactory::i()->getMutex(); | ||
| } | ||
bukka marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| if (logFile != nullptr) | ||
| { | ||
| fclose(logFile); | ||
| logFile = nullptr; | ||
| } | ||
|
|
||
| if (logFilePath.empty()) | ||
| { | ||
| return true; | ||
| } | ||
|
|
||
| // This function needs to be called in init so it does not need locking | ||
| logFile = fopen(logFilePath.c_str(), "a"); | ||
| if (logFile == nullptr) | ||
| { | ||
| syslog(LOG_ERR, "Failed to open log file: %s, using syslog only", logFilePath.c_str()); | ||
| return false; | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| void closeLogFile() | ||
| { | ||
| if (logFile != nullptr) | ||
| { | ||
| fclose(logFile); | ||
| logFile = nullptr; | ||
| } | ||
|
|
||
| if (logMutex != nullptr) | ||
| { | ||
| MutexFactory::i()->recycleMutex(logMutex); | ||
| logMutex = nullptr; | ||
| } | ||
| } | ||
|
|
||
| static const char* getLevelString(int loglevel) | ||
| { | ||
| switch(loglevel) | ||
| { | ||
| case LOG_ERR: return "ERROR"; | ||
| case LOG_WARNING: return "WARNING"; | ||
| case LOG_INFO: return "INFO"; | ||
| case LOG_DEBUG: return "DEBUG"; | ||
| default: return "UNKNOWN"; | ||
| } | ||
| } | ||
|
|
||
| static void writeLogToFile(const int loglevel, const char* prependText, const char* msgText) | ||
| { | ||
| MutexLocker lock(logMutex); | ||
|
|
||
| #ifdef _WIN32 | ||
| SYSTEMTIME st; | ||
| GetLocalTime(&st); | ||
| fprintf(logFile, "%04d-%02d-%02d %02d:%02d:%02d.%03d [%d] %s: %s%s\n", | ||
| st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, | ||
| _getpid(), getLevelString(loglevel), prependText, msgText); | ||
| #else | ||
| struct timespec ts; | ||
| clock_gettime(CLOCK_REALTIME, &ts); | ||
| struct tm timeinfo; | ||
| localtime_r(&ts.tv_sec, &timeinfo); | ||
|
|
||
| char basetime[32]; | ||
| strftime(basetime, sizeof(basetime), "%Y-%m-%d %H:%M:%S", &timeinfo); | ||
| fprintf(logFile, "%s.%03ld [%d] %s: %s%s\n", | ||
| basetime, ts.tv_nsec / 1000000, | ||
| (int)getpid(), getLevelString(loglevel), prependText, msgText); | ||
| #endif | ||
|
|
||
| fflush(logFile); | ||
| } | ||
|
Comment on lines
+145
to
+169
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, let's explore the structure and understand the logging setup
find . -name "log.cpp" -o -name "log.h" | head -20Repository: softhsm/SoftHSMv2 Length of output: 108 🏁 Script executed: # Check the full log.cpp file to understand initialization
wc -l src/lib/common/log.cppRepository: softhsm/SoftHSMv2 Length of output: 87 🏁 Script executed: # Look for logFile and logMutex declarations
rg -n "logFile|logMutex" src/lib/common/log.cpp -B 2 -A 2Repository: softhsm/SoftHSMv2 Length of output: 2165 🏁 Script executed: # Check how these are initialized
rg -n "logFile\s*=" src/lib/common/log.cpp | head -20Repository: softhsm/SoftHSMv2 Length of output: 272 🏁 Script executed: # Look for the complete log initialization function
rg -n "void.*[Ll]og" src/lib/common/log.cpp | grep -E "(init|Init|setup|Setup)"Repository: softhsm/SoftHSMv2 Length of output: 43 🏁 Script executed: # Check if there are other calls to writeLogToFile
rg -n "writeLogToFile" src/lib/common/log.cppRepository: softhsm/SoftHSMv2 Length of output: 211 🏁 Script executed: # Check what platforms are supported - look at build configs
find . -name "*.ac" -o -name "CMakeLists.txt" -o -name "configure" | grep -E "^\./[^/]+$|CMakeLists|configure\.ac" | head -10Repository: softhsm/SoftHSMv2 Length of output: 321 🏁 Script executed: # Check for clock_gettime usage and portability handling
rg -n "clock_gettime|CLOCK_REALTIME" src/Repository: softhsm/SoftHSMv2 Length of output: 124 🏁 Script executed: # Look for platform-specific defines and portability considerations
rg -n "WIN32|_WIN32|HAVE_CLOCK|sun|solaris|aix|hpux" src/lib/common/log.cppRepository: softhsm/SoftHSMv2 Length of output: 95 🏁 Script executed: # Check the main header to understand platform support declarations
head -50 src/lib/common/log.hRepository: softhsm/SoftHSMv2 Length of output: 2166 🏁 Script executed: # Check configure.ac for platform support and clock_gettime checks
cat configure.ac | head -100Repository: softhsm/SoftHSMv2 Length of output: 2688 🏁 Script executed: # Check for specific clock_gettime checks in configure
rg -n "clock_gettime|HAVE_CLOCK" configure.acRepository: softhsm/SoftHSMv2 Length of output: 43 🏁 Script executed: # Check CMakeLists.txt for platform detection
cat CMakeLists.txt | head -80Repository: softhsm/SoftHSMv2 Length of output: 3231 🏁 Script executed: # Look for config.h template or any portability headers
find . -name "config.h*" -type fRepository: softhsm/SoftHSMv2 Length of output: 80 🏁 Script executed: # Check what syslog calls are used elsewhere
rg -n "syslog" src/lib/common/log.cpp | head -20Repository: softhsm/SoftHSMv2 Length of output: 287 🏁 Script executed: # Search more thoroughly in configure.ac for clock or time checks
cat configure.ac | grep -i "clock\|time\|posix" -C 2Repository: softhsm/SoftHSMv2 Length of output: 43 🏁 Script executed: # Search for AC_CHECK_FUNCS in configure.ac
rg -n "AC_CHECK_FUNCS" configure.acRepository: softhsm/SoftHSMv2 Length of output: 93 🏁 Script executed: # Get full context around configure.ac to see all checks
cat configure.ac | tail -100Repository: softhsm/SoftHSMv2 Length of output: 2226 🏁 Script executed: # Check if there are any ifdefs or checks for clock_gettime in the codebase
rg -n "HAVE_CLOCK|HAVE_POSIX|__POSIX__|POSIX" src/Repository: softhsm/SoftHSMv2 Length of output: 1483 🏁 Script executed: # Verify the exact context of how writeLogToFile is called
sed -n '200,215p' src/lib/common/log.cppRepository: softhsm/SoftHSMv2 Length of output: 458 🏁 Script executed: # Check README or documentation for supported platforms
find . -name "README*" -o -name "INSTALL*" | head -10Repository: softhsm/SoftHSMv2 Length of output: 94 🏁 Script executed: # Look for any platform-specific issues or CI configs
find . -name ".github" -o -name ".gitlab-ci*" -o -name ".travis*" -o -name "appveyor*" 2>/dev/null | head -20Repository: softhsm/SoftHSMv2 Length of output: 84 🏁 Script executed: # Check if there's any documentation about supported platforms
cat README.md 2>/dev/null | head -50Repository: softhsm/SoftHSMv2 Length of output: 2281 🏁 Script executed: # Check if clock_gettime is conditionally compiled elsewhere or if POSIX is assumed
rg -n "localtime_r|strftime|struct tm|timespec" src/lib/common/ -B 2 -A 2Repository: softhsm/SoftHSMv2 Length of output: 713 🏁 Script executed: # Final check: verify the exact linking and compilation context
cat src/lib/common/CMakeLists.txt | grep -A 20 "add_library\|target_link"Repository: softhsm/SoftHSMv2 Length of output: 930 🏁 Script executed: # Verify if any platform-specific handling exists for clock functions
rg -n "rt\|clock\|time" src/lib/common/CMakeLists.txtRepository: softhsm/SoftHSMv2 Length of output: 43 Consider adding null-guards and verify Two low-cost hardening points:
|
||
|
|
||
| void softHSMLog(const int loglevel, const char* functionName, const char* fileName, const int lineNo, const char* format, ...) | ||
| { | ||
| if (loglevel > softLogLevel) return; | ||
|
|
@@ -98,12 +197,22 @@ void softHSMLog(const int loglevel, const char* functionName, const char* fileNa | |
| vsnprintf(&logMessage[0], 4096, format, args); | ||
| va_end(args); | ||
|
|
||
| // And log it | ||
| syslog(loglevel, "%s%s", prepend.str().c_str(), &logMessage[0]); | ||
| const char* msgText = &logMessage[0]; | ||
| std::string prependStr = prepend.str(); | ||
| const char* prependText = prependStr.c_str(); | ||
|
|
||
| // Log to file if configured, otherwise use syslog | ||
| if (logFile != nullptr) | ||
| { | ||
| writeLogToFile(loglevel, prependText, msgText); | ||
bukka marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| else | ||
| { | ||
| syslog(loglevel, "%s%s", prependText, msgText); | ||
| } | ||
bukka marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| #ifdef DEBUG_LOG_STDERR | ||
| fprintf(stderr, "%s%s\n", prepend.str().c_str(), &logMessage[0]); | ||
| fprintf(stderr, "%s%s\n", prependText, msgText); | ||
| fflush(stderr); | ||
| #endif // DEBUG_LOG_STDERR | ||
| #endif | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.