LCOV - code coverage report
Current view: top level - src - Logger.h (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 95.2 % 42 40
Test Date: 2026-03-01 21:30:38 Functions: 100.0 % 8 8
Branches: 51.7 % 58 30

             Branch data     Line data    Source code
       1                 :             : #ifndef LOGGER_H
       2                 :             : #define LOGGER_H
       3                 :             : 
       4                 :             : #include <string>
       5                 :             : #include <fstream>
       6                 :             : #include <mutex>
       7                 :             : #include <memory>
       8                 :             : #include <iostream>
       9                 :             : #include <sstream>
      10                 :             : #include <iomanip>
      11                 :             : #include <chrono>
      12                 :             : #include <cstdarg>
      13                 :             : 
      14                 :             : // Simple synchronous logger that flushes every line for crash debugging
      15                 :             : class Logger {
      16                 :             : public:
      17                 :       12446 :     static Logger& Get() {
      18   [ +  +  +  -  :       12446 :         static Logger instance;
             +  -  -  - ]
      19                 :       12446 :         return instance;
      20                 :             :     }
      21                 :             : 
      22                 :           9 :     void Init(const std::string& filename) {
      23         [ +  - ]:           9 :         std::lock_guard<std::mutex> lock(m_mutex);
      24         [ +  - ]:           9 :         m_filename = filename;
      25         [ +  - ]:           9 :         m_file.open(m_filename, std::ios::out | std::ios::trunc);
      26         [ +  - ]:           9 :         if (m_file.is_open()) {
      27                 :           9 :             m_initialized = true;
      28   [ +  -  +  -  :          18 :             _LogNoLock("Logger Initialized. Version: " + std::string(LMUFFB_VERSION));
                   +  - ]
      29                 :             :         }
      30                 :           9 :     }
      31                 :             : 
      32                 :       12437 :     void Log(const char* fmt, ...) {
      33         [ +  + ]:       12437 :         if (!m_initialized) return;
      34                 :             : 
      35                 :             :         char buffer[1024];
      36                 :             :         va_list args;
      37                 :          34 :         va_start(args, fmt);
      38                 :          34 :         vsnprintf(buffer, sizeof(buffer), fmt, args);
      39                 :          34 :         va_end(args);
      40                 :             : 
      41         [ +  - ]:          34 :         std::string message(buffer);
      42                 :             : 
      43         [ +  - ]:          34 :         std::lock_guard<std::mutex> lock(m_mutex);
      44         [ +  - ]:          34 :         _LogNoLock(message);
      45                 :          34 :     }
      46                 :             : 
      47                 :             :     // Helper for std::string
      48                 :           2 :     void LogStr(const std::string& msg) {
      49                 :           2 :         Log("%s", msg.c_str());
      50                 :           2 :     }
      51                 :             : 
      52                 :             :     // Helper for error logging with GetLastError()
      53                 :           2 :     void LogWin32Error(const char* context, unsigned long errorCode) {
      54                 :           2 :         Log("Error in %s: Code %lu", context, errorCode);
      55                 :           2 :     }
      56                 :             : 
      57                 :             : private:
      58         [ +  - ]:           1 :     Logger() {}
      59                 :           1 :     ~Logger() noexcept {
      60                 :             :         try {
      61         [ +  - ]:           1 :             if (m_file.is_open()) {
      62         [ +  - ]:           1 :                 m_file << "Logger Shutdown.\n";
      63         [ +  - ]:           1 :                 m_file.close();
      64                 :             :             }
      65                 :           0 :         } catch (...) {
      66                 :             :             // Destructor must not throw
      67                 :           0 :         }
      68                 :           1 :     }
      69                 :             : 
      70                 :          43 :     void _LogNoLock(const std::string& message) {
      71         [ -  + ]:          43 :         if (!m_file.is_open()) return;
      72                 :             : 
      73                 :             :         // Timestamp
      74                 :          43 :         auto now = std::chrono::system_clock::now();
      75                 :          43 :         auto in_time_t = std::chrono::system_clock::to_time_t(now);
      76                 :             :         std::tm time_info;
      77                 :             :         #ifdef _WIN32
      78                 :             :             localtime_s(&time_info, &in_time_t);
      79                 :             :         #else
      80                 :          43 :             localtime_r(&in_time_t, &time_info);
      81                 :             :         #endif
      82                 :             : 
      83   [ +  -  +  -  :          43 :         m_file << "[" << std::put_time(&time_info, "%H:%M:%S") << "] " << message << "\n";
          +  -  +  -  +  
                      - ]
      84         [ +  - ]:          43 :         m_file.flush(); // Critical for crash debugging
      85                 :             : 
      86                 :             :         // Also print to console for consistency
      87   [ +  -  +  -  :          43 :         std::cout << "[Log] " << message << std::endl;
                   +  - ]
      88                 :             :     }
      89                 :             : 
      90                 :             :     std::string m_filename;
      91                 :             :     std::ofstream m_file;
      92                 :             :     std::mutex m_mutex;
      93                 :             :     bool m_initialized = false;
      94                 :             : };
      95                 :             : 
      96                 :             : #endif // LOGGER_H
        

Generated by: LCOV version 2.0-1