Coverage Report

Created: 2026-02-26 06:40

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
  thread_local std::string Logger::m_LastError = [] {
54
1
    std::string str;
55
1
    str.reserve(200);
56
1
    return str;
57
1
  }();
58
59
1
  Logger::Logger() : m_LogsEnabled(true), m_LogPrinter(&printToCerr)
60
1
  {
61
1
    m_LogModulesArray.fill(LogLevel::Info);
62
1
  }
63
64
  std::string Logger::logLevelAsString(LogLevel logLevel)
65
0
  {
66
0
    switch (logLevel)
67
0
    {
68
0
    case LogLevel::Off:
69
0
      return "OFF";
70
0
    case LogLevel::Error:
71
0
      return "ERROR";
72
0
    case LogLevel::Warn:
73
0
      return "WARN";
74
0
    case LogLevel::Info:
75
0
      return "INFO";
76
0
    case LogLevel::Debug:
77
0
      return "DEBUG";
78
0
    default:
79
0
      return "UNKNOWN";
80
0
    }
81
0
  }
82
83
  void Logger::resetLogPrinter()
84
0
  {
85
0
    m_LogPrinter = &printToCerr;  // Reset to the default log printer
86
0
  }
87
88
  std::unique_ptr<internal::LogContext> Logger::createLogContext()
89
0
  {
90
0
    return createLogContext(LogLevel::Info, {});  // call the other createLogContext method
91
0
  }
92
  std::unique_ptr<internal::LogContext> Logger::createLogContext(LogLevel level, LogSource const& source)
93
1.77k
  {
94
1.77k
    if (m_UseContextPooling)
95
1.77k
    {
96
1.77k
      auto ctx = m_LogContextPool.acquireObject();
97
1.77k
      ctx->init(level, source);
98
1.77k
      return ctx;
99
1.77k
    }
100
0
    return std::make_unique<internal::LogContext>(level, source);
101
1.77k
  }
102
103
  void Logger::emit(std::unique_ptr<internal::LogContext> message)
104
1.77k
  {
105
1.77k
    emit(message->m_Source, message->m_Level, message->m_Stream.str());
106
    // Pushes the message back to the pool if pooling is enabled. Otherwise, the message is deleted.
107
1.77k
    if (m_UseContextPooling)
108
1.77k
    {
109
1.77k
      m_LogContextPool.releaseObject(std::move(message));
110
1.77k
    }
111
1.77k
  }
112
113
  void Logger::emit(LogSource const& source, LogLevel logLevel, std::string const& message)
114
1.77k
  {
115
    // If the log level is an error, save the error to the last error message variable.
116
1.77k
    if (logLevel == LogLevel::Error)
117
498
    {
118
498
      m_LastError = message;
119
498
    }
120
1.77k
    if (m_LogsEnabled)
121
0
    {
122
0
      m_LogPrinter(logLevel, message, source.file, source.function, source.line);
123
0
    }
124
1.77k
  }
125
}  // namespace pcpp