blob: 4d33ab3b1aa868753e7ebe737249270a1220b8b2 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#ifndef CEPH_LOG_SUBSYSTEMS
#define CEPH_LOG_SUBSYSTEMS
#include <string>
#include <vector>
#include <algorithm>
#include "common/likely.h"
#include "common/subsys_types.h"
#include "include/ceph_assert.h"
namespace ceph {
namespace logging {
class SubsystemMap {
// Access to the current gathering levels must be *FAST* as they are
// read over and over from all places in the code (via should_gather()
// by i.e. dout).
std::array<uint8_t, ceph_subsys_get_num()> m_gather_levels;
// The rest. Should be as small as possible to not unnecessarily
// enlarge md_config_t and spread it other elements across cache
// lines. Access can be slow.
std::vector<ceph_subsys_item_t> m_subsys;
friend class Log;
public:
SubsystemMap() {
constexpr auto s = ceph_subsys_get_as_array();
m_subsys.reserve(s.size());
std::size_t i = 0;
for (const ceph_subsys_item_t& item : s) {
m_subsys.emplace_back(item);
m_gather_levels[i++] = std::max(item.log_level, item.gather_level);
}
}
constexpr static std::size_t get_num() {
return ceph_subsys_get_num();
}
constexpr static std::size_t get_max_subsys_len() {
return ceph_subsys_max_name_length();
}
int get_log_level(unsigned subsys) const {
if (subsys >= get_num())
subsys = 0;
return m_subsys[subsys].log_level;
}
int get_gather_level(unsigned subsys) const {
if (subsys >= get_num())
subsys = 0;
return m_subsys[subsys].gather_level;
}
// TODO(rzarzynski): move to string_view?
constexpr const char* get_name(unsigned subsys) const {
if (subsys >= get_num())
subsys = 0;
return ceph_subsys_get_as_array()[subsys].name;
}
template <unsigned SubV, int LvlV>
bool should_gather() const {
static_assert(SubV < get_num(), "wrong subsystem ID");
static_assert(LvlV >= -1 && LvlV <= 200);
if constexpr (LvlV <= 0) {
// handle the -1 and 0 levels entirely at compile-time.
// Such debugs are intended to be gathered regardless even
// of the user configuration.
return true;
} else {
// we expect that setting level different than the default
// is rather unusual.
return expect(LvlV <= static_cast<int>(m_gather_levels[SubV]),
LvlV <= ceph_subsys_get_max_default_level(SubV));
}
}
bool should_gather(const unsigned sub, int level) const {
ceph_assert(sub < m_subsys.size());
return level <= static_cast<int>(m_gather_levels[sub]);
}
void set_log_level(unsigned subsys, uint8_t log)
{
ceph_assert(subsys < m_subsys.size());
m_subsys[subsys].log_level = log;
m_gather_levels[subsys] = \
std::max(log, m_subsys[subsys].gather_level);
}
void set_gather_level(unsigned subsys, uint8_t gather)
{
ceph_assert(subsys < m_subsys.size());
m_subsys[subsys].gather_level = gather;
m_gather_levels[subsys] = \
std::max(m_subsys[subsys].log_level, gather);
}
};
}
}
#endif
|