Coverage Report

Created: 2026-04-06 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pdns/pdns/logging.cc
Line
Count
Source
1
/**
2
 * This file is part of PowerDNS or dnsdist.
3
 * Copyright -- PowerDNS.COM B.V. and its contributors
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of version 2 of the GNU General Public License as
7
 * published by the Free Software Foundation.
8
 *
9
 * In addition, for the avoidance of any doubt, permission is granted to
10
 * link this program with OpenSSL and to (re)distribute the binaries
11
 * produced as the result of such linking.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
 */
22
23
#include "logging.hh"
24
#include <string>
25
#include <mutex>
26
27
namespace Logging
28
{
29
30
std::shared_ptr<const Logger> Logger::getptr() const
31
0
{
32
0
  return shared_from_this();
33
0
}
34
35
void Logger::info(Logr::Priority prio, const std::string& msg) const
36
0
{
37
0
  logMessage(msg, prio, std::nullopt);
38
0
}
39
40
void Logger::logMessage(const std::string& msg, Logr::Priority prio, const std::optional<std::string>& err) const
41
0
{
42
0
  Entry entry;
43
0
  entry.level = _level;
44
0
  entry.d_priority = prio;
45
0
  ::gettimeofday(&entry.d_timestamp, nullptr);
46
0
  entry.name = _name;
47
0
  entry.message = msg;
48
0
  entry.error = err;
49
0
  auto parent = _parent;
50
0
  entry.values.insert(_values.begin(), _values.end());
51
0
  while (parent) {
52
0
    entry.values.insert(parent->_values.begin(), parent->_values.end());
53
0
    parent = parent->_parent;
54
0
  }
55
0
  _callback(entry);
56
0
}
57
58
void Logger::error(Logr::Priority prio, int err, const std::string& msg) const
59
0
{
60
0
  logMessage(msg, prio, std::string(stringerror(err)));
61
0
}
62
63
void Logger::error(Logr::Priority prio, const std::string& err, const std::string& msg) const
64
0
{
65
0
  logMessage(msg, prio, err);
66
0
}
67
68
std::shared_ptr<Logr::Logger> Logger::v(size_t level) const
69
0
{
70
0
  auto res = std::make_shared<Logger>(getptr(), _name, level + _level, _callback);
71
0
  return res;
72
0
}
73
74
std::shared_ptr<Logr::Logger> Logger::withValues(const std::map<std::string, std::string>& values) const
75
0
{
76
0
  auto res = std::make_shared<Logger>(getptr(), _name, _level, _callback);
77
0
  res->_values = values;
78
0
  return res;
79
0
}
80
81
std::shared_ptr<Logr::Logger> Logger::withName(const std::string& name) const
82
0
{
83
0
  std::shared_ptr<Logger> res;
84
0
  if (_name) {
85
0
    res = std::make_shared<Logger>(getptr(), _name.value() + "." + name, _level, _callback);
86
0
  }
87
0
  else {
88
0
    res = std::make_shared<Logger>(getptr(), name, _level, _callback);
89
0
  }
90
0
  return res;
91
0
}
92
std::shared_ptr<Logger> Logger::create(EntryLogger callback)
93
0
{
94
0
  return std::make_shared<Logger>(callback);
95
0
}
96
std::shared_ptr<Logger> Logger::create(EntryLogger callback, const std::string& name)
97
0
{
98
0
  return std::make_shared<Logger>(callback, name);
99
0
}
100
101
Logger::Logger(EntryLogger callback) :
102
0
  _callback(callback)
103
0
{
104
0
}
105
Logger::Logger(EntryLogger callback, std::optional<std::string> name) :
106
0
  _callback(callback), _name(std::move(name))
107
0
{
108
0
}
109
Logger::Logger(std::shared_ptr<const Logger> parent, std::optional<std::string> name, size_t lvl, EntryLogger callback) :
110
0
  _parent(std::move(parent)), _callback(callback), _name(std::move(name)), _level(lvl)
111
0
{
112
0
}
113
114
0
Logger::~Logger() = default;
115
};
116
117
std::shared_ptr<Logging::Logger> g_slog{nullptr};
118
119
const char* Logging::toTimestampStringMilli(const struct timeval& tval, std::array<char, 64>& buf, const std::string& format)
120
0
{
121
0
  size_t len = 0;
122
0
  if (format != "%s") {
123
    // strftime is not thread safe, it can access locale information
124
0
    static std::mutex mutex;
125
0
    auto lock = std::scoped_lock(mutex);
126
0
    struct tm theTime // clang-format insists on formatting it like this
127
0
      {};
128
0
    len = strftime(buf.data(), buf.size(), format.c_str(), localtime_r(&tval.tv_sec, &theTime));
129
0
  }
130
0
  if (len == 0) {
131
0
    len = snprintf(buf.data(), buf.size(), "%lld", static_cast<long long>(tval.tv_sec));
132
0
  }
133
134
0
  snprintf(&buf.at(len), buf.size() - len, ".%03ld", static_cast<long>(tval.tv_usec) / 1000);
135
0
  return buf.data();
136
0
}