Coverage Report

Created: 2025-09-27 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Common++/src/Logger.cpp
Line
Count
Source
1
#include "Logger.h"
2
3
#include <iostream>
4
#include <iomanip>
5
#include <sstream>
6
#include <cstring>
7
#include <mutex>
8
9
namespace pcpp
10
{
11
12
  namespace
13
  {
14
    /// Default log printer function that prints to std::cerr.
15
    void printToCerr(LogLevel logLevel, const std::string& logMessage, const std::string& file,
16
                     const std::string& method, const int line)
17
0
    {
18
      // This mutex is used to prevent multiple threads from writing to the console at the same time.
19
0
      static std::mutex logMutex;
20
21
0
      std::ostringstream sstream;
22
0
      sstream << file << ": " << method << ":" << line;
23
24
0
      std::unique_lock<std::mutex> const lock(logMutex);
25
0
      std::cerr << std::left << "[" << std::setw(5) << Logger::logLevelAsString(logLevel) << ": " << std::setw(45)
26
0
                << sstream.str() << "] " << logMessage << std::endl;
27
0
    }
28
  }  // namespace
29
30
  // Alpine Linux incorrectly declares strerror_r
31
  // https://stackoverflow.com/questions/41953104/strerror-r-is-incorrectly-declared-on-alpine-linux
32
  char* checkError(int /*unused*/, char* buffer, int /*unused*/)
33
0
  {
34
0
    return buffer;
35
0
  }
36
37
  char* checkError(char* result, const char* /*unused*/, int /*unused*/)
38
0
  {
39
0
    return result;
40
0
  }
41
42
  std::string getErrorString(int errnum)
43
0
  {
44
0
    std::array<char, BUFSIZ> buffer{};
45
#if defined(_WIN32)
46
    strerror_s(buffer.data(), buffer.size(), errnum);
47
    return buffer.data();
48
#else
49
0
    return checkError(strerror_r(errnum, buffer.data(), BUFSIZ), buffer.data(), errnum);
50
0
#endif
51
0
  }
52
53
1
  Logger::Logger() : m_LogsEnabled(true), m_LogPrinter(&printToCerr)
54
1
  {
55
1
    m_LastError.reserve(200);
56
1
    m_LogModulesArray.fill(LogLevel::Info);
57
1
  }
58
59
  std::string Logger::logLevelAsString(LogLevel logLevel)
60
0
  {
61
0
    switch (logLevel)
62
0
    {
63
0
    case LogLevel::Off:
64
0
      return "OFF";
65
0
    case LogLevel::Error:
66
0
      return "ERROR";
67
0
    case LogLevel::Warn:
68
0
      return "WARN";
69
0
    case LogLevel::Info:
70
0
      return "INFO";
71
0
    case LogLevel::Debug:
72
0
      return "DEBUG";
73
0
    default:
74
0
      return "UNKNOWN";
75
0
    }
76
0
  }
77
78
  void Logger::resetLogPrinter()
79
0
  {
80
0
    m_LogPrinter = &printToCerr;  // Reset to the default log printer
81
0
  }
82
83
  std::unique_ptr<internal::LogContext> Logger::createLogContext()
84
0
  {
85
0
    return createLogContext(LogLevel::Info, {});  // call the other createLogContext method
86
0
  }
87
  std::unique_ptr<internal::LogContext> Logger::createLogContext(LogLevel level, LogSource const& source)
88
785
  {
89
785
    if (m_UseContextPooling)
90
785
    {
91
785
      auto ctx = m_LogContextPool.acquireObject();
92
785
      ctx->init(level, source);
93
785
      return ctx;
94
785
    }
95
0
    return std::make_unique<internal::LogContext>(level, source);
96
785
  }
97
98
  void Logger::emit(std::unique_ptr<internal::LogContext> message)
99
785
  {
100
785
    emit(message->m_Source, message->m_Level, message->m_Stream.str());
101
    // Pushes the message back to the pool if pooling is enabled. Otherwise, the message is deleted.
102
785
    if (m_UseContextPooling)
103
785
    {
104
785
      m_LogContextPool.releaseObject(std::move(message));
105
785
    }
106
785
  }
107
108
  void Logger::emit(LogSource const& source, LogLevel logLevel, std::string const& message)
109
785
  {
110
    // If the log level is an error, save the error to the last error message variable.
111
785
    if (logLevel == LogLevel::Error)
112
785
    {
113
785
      std::lock_guard<std::mutex> const lock(m_LastErrorMtx);
114
785
      m_LastError = message;
115
785
    }
116
785
    if (m_LogsEnabled)
117
0
    {
118
0
      m_LogPrinter(logLevel, message, source.file, source.function, source.line);
119
0
    }
120
785
  }
121
}  // namespace pcpp