2#ifndef LOGIT_CPP_HEADER_LOGIT_CPP_LOGIT_DETAIL_LOGCONTEXT_HPP_INCLUDED
3#define LOGIT_CPP_HEADER_LOGIT_CPP_LOGIT_DETAIL_LOGCONTEXT_HPP_INCLUDED
13#ifndef LOGIT_HAS_FEATURE
14#if defined(__has_feature)
15#define LOGIT_HAS_FEATURE(x) __has_feature(x)
17#define LOGIT_HAS_FEATURE(x) 0
21#ifndef LOGIT_DISABLE_THREAD_LOCAL_DESTRUCTORS
22#if defined(__SANITIZE_ADDRESS__) || LOGIT_HAS_FEATURE(address_sanitizer)
23#define LOGIT_DISABLE_THREAD_LOCAL_DESTRUCTORS 0
25#define LOGIT_DISABLE_THREAD_LOCAL_DESTRUCTORS 1
31#ifdef LOGIT_WITH_CONTEXT
35 struct LogContextSnapshot {
36 std::map<std::string, std::string> mdc;
37 std::vector<std::string> ndc;
42# if LOGIT_DISABLE_THREAD_LOCAL_DESTRUCTORS
44 inline std::map<std::string, std::string>*& mdc_map_storage() {
45 static thread_local std::map<std::string, std::string>* instance =
nullptr;
49 inline std::vector<std::string>*& ndc_stack_storage() {
50 static thread_local std::vector<std::string>* instance =
nullptr;
56 inline std::unique_ptr<std::map<std::string, std::string> >& mdc_map_storage() {
57 static thread_local std::unique_ptr<std::map<std::string, std::string> > instance;
61 inline std::unique_ptr<std::vector<std::string> >& ndc_stack_storage() {
62 static thread_local std::unique_ptr<std::vector<std::string> > instance;
68 inline std::map<std::string, std::string>& mutable_mdc_map() {
69# if LOGIT_DISABLE_THREAD_LOCAL_DESTRUCTORS
70 if (!mdc_map_storage()) {
71 mdc_map_storage() =
new std::map<std::string, std::string>();
73 return *mdc_map_storage();
75 if (!mdc_map_storage()) {
76 mdc_map_storage().reset(
new std::map<std::string, std::string>());
78 return *mdc_map_storage();
82 inline std::vector<std::string>& mutable_ndc_stack() {
83# if LOGIT_DISABLE_THREAD_LOCAL_DESTRUCTORS
84 if (!ndc_stack_storage()) {
85 ndc_stack_storage() =
new std::vector<std::string>();
87 return *ndc_stack_storage();
89 if (!ndc_stack_storage()) {
90 ndc_stack_storage().reset(
new std::vector<std::string>());
92 return *ndc_stack_storage();
96 inline const std::map<std::string, std::string>* mdc_map_if_exists() {
97# if LOGIT_DISABLE_THREAD_LOCAL_DESTRUCTORS
98 return mdc_map_storage();
100 return mdc_map_storage().get();
104 inline const std::vector<std::string>* ndc_stack_if_exists() {
105# if LOGIT_DISABLE_THREAD_LOCAL_DESTRUCTORS
106 return ndc_stack_storage();
108 return ndc_stack_storage().get();
115 inline void mdc_put(
const std::string& key,
const std::string& value) {
116 detail::mutable_mdc_map()[key] = value;
120 inline void mdc_remove(
const std::string& key) {
121 std::map<std::string, std::string>* values =
122 const_cast<std::map<std::string, std::string>*
>(detail::mdc_map_if_exists());
123 if (values !=
nullptr) {
129 inline void mdc_clear() {
130 std::map<std::string, std::string>* values =
131 const_cast<std::map<std::string, std::string>*
>(detail::mdc_map_if_exists());
132 if (values !=
nullptr) {
138 inline void ndc_push(
const std::string& message) {
139 detail::mutable_ndc_stack().push_back(message);
143 inline void ndc_pop() {
144 std::vector<std::string>* stack =
145 const_cast<std::vector<std::string>*
>(detail::ndc_stack_if_exists());
146 if (stack !=
nullptr && !stack->empty()) {
152 inline void ndc_clear() {
153 std::vector<std::string>* stack =
154 const_cast<std::vector<std::string>*
>(detail::ndc_stack_if_exists());
155 if (stack !=
nullptr) {
161 inline std::shared_ptr<const LogContextSnapshot> capture_log_context() {
162 const std::map<std::string, std::string>* mdc = detail::mdc_map_if_exists();
163 const std::vector<std::string>* ndc = detail::ndc_stack_if_exists();
164 if ((mdc ==
nullptr || mdc->empty()) && (ndc ==
nullptr || ndc->empty())) {
165 return std::shared_ptr<const LogContextSnapshot>();
168 std::shared_ptr<LogContextSnapshot> snapshot(
new LogContextSnapshot());
169 if (mdc !=
nullptr) {
170 snapshot->mdc = *mdc;
172 if (ndc !=
nullptr) {
173 snapshot->ndc = *ndc;
185 explicit NdcGuard(
const std::string& message) {
193 NdcGuard(
const NdcGuard&) =
delete;
194 NdcGuard& operator=(
const NdcGuard&) =
delete;
195 NdcGuard(NdcGuard&&) =
delete;
196 NdcGuard& operator=(NdcGuard&&) =
delete;
The primary namespace for the LogIt++ library.