diff options
Diffstat (limited to 'src/log/SubsystemMap.h')
-rw-r--r-- | src/log/SubsystemMap.h | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/src/log/SubsystemMap.h b/src/log/SubsystemMap.h new file mode 100644 index 000000000..4d33ab3b1 --- /dev/null +++ b/src/log/SubsystemMap.h @@ -0,0 +1,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 |