Agora  1.2.0
Agora project
logger-inl.h
Go to the documentation of this file.
1 // Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
2 // Distributed under the MIT License (http://opensource.org/licenses/MIT)
3 
4 #pragma once
5 
6 #ifndef SPDLOG_HEADER_ONLY
7 # include <spdlog/logger.h>
8 #endif
9 
10 #include <spdlog/sinks/sink.h>
13 
14 #include <cstdio>
15 
16 namespace spdlog {
17 
18 // public methods
20  : name_(other.name_)
21  , sinks_(other.sinks_)
22  , level_(other.level_.load(std::memory_order_relaxed))
23  , flush_level_(other.flush_level_.load(std::memory_order_relaxed))
24  , custom_err_handler_(other.custom_err_handler_)
25  , tracer_(other.tracer_)
26 {}
27 
28 SPDLOG_INLINE logger::logger(logger &&other) SPDLOG_NOEXCEPT : name_(std::move(other.name_)),
29  sinks_(std::move(other.sinks_)),
30  level_(other.level_.load(std::memory_order_relaxed)),
31  flush_level_(other.flush_level_.load(std::memory_order_relaxed)),
32  custom_err_handler_(std::move(other.custom_err_handler_)),
33  tracer_(std::move(other.tracer_))
34 
35 {}
36 
38 {
39  this->swap(other);
40  return *this;
41 }
42 
44 {
45  name_.swap(other.name_);
46  sinks_.swap(other.sinks_);
47 
48  // swap level_
49  auto other_level = other.level_.load();
50  auto my_level = level_.exchange(other_level);
51  other.level_.store(my_level);
52 
53  // swap flush level_
54  other_level = other.flush_level_.load();
55  my_level = flush_level_.exchange(other_level);
56  other.flush_level_.store(my_level);
57 
58  custom_err_handler_.swap(other.custom_err_handler_);
59  std::swap(tracer_, other.tracer_);
60 }
61 
63 {
64  a.swap(b);
65 }
66 
68 {
69  level_.store(log_level);
70 }
71 
73 {
74  return static_cast<level::level_enum>(level_.load(std::memory_order_relaxed));
75 }
76 
77 SPDLOG_INLINE const std::string &logger::name() const
78 {
79  return name_;
80 }
81 
82 // set formatting for the sinks in this logger.
83 // each sink will get a separate instance of the formatter object.
84 SPDLOG_INLINE void logger::set_formatter(std::unique_ptr<formatter> f)
85 {
86  for (auto it = sinks_.begin(); it != sinks_.end(); ++it)
87  {
88  if (std::next(it) == sinks_.end())
89  {
90  // last element - we can be move it.
91  (*it)->set_formatter(std::move(f));
92  break; // to prevent clang-tidy warning
93  }
94  else
95  {
96  (*it)->set_formatter(f->clone());
97  }
98  }
99 }
100 
101 SPDLOG_INLINE void logger::set_pattern(std::string pattern, pattern_time_type time_type)
102 {
103  auto new_formatter = details::make_unique<pattern_formatter>(std::move(pattern), time_type);
104  set_formatter(std::move(new_formatter));
105 }
106 
107 // create new backtrace sink and move to it all our child sinks
109 {
110  tracer_.enable(n_messages);
111 }
112 
113 // restore orig sinks and level and delete the backtrace sink
115 {
116  tracer_.disable();
117 }
118 
120 {
121  dump_backtrace_();
122 }
123 
124 // flush functions
126 {
127  flush_();
128 }
129 
131 {
132  flush_level_.store(log_level);
133 }
134 
136 {
137  return static_cast<level::level_enum>(flush_level_.load(std::memory_order_relaxed));
138 }
139 
140 // sinks
141 SPDLOG_INLINE const std::vector<sink_ptr> &logger::sinks() const
142 {
143  return sinks_;
144 }
145 
146 SPDLOG_INLINE std::vector<sink_ptr> &logger::sinks()
147 {
148  return sinks_;
149 }
150 
151 // error handler
153 {
154  custom_err_handler_ = std::move(handler);
155 }
156 
157 // create new logger with same sinks and configuration.
158 SPDLOG_INLINE std::shared_ptr<logger> logger::clone(std::string logger_name)
159 {
160  auto cloned = std::make_shared<logger>(*this);
161  cloned->name_ = std::move(logger_name);
162  return cloned;
163 }
164 
165 // protected methods
166 SPDLOG_INLINE void logger::log_it_(const spdlog::details::log_msg &log_msg, bool log_enabled, bool traceback_enabled)
167 {
168  if (log_enabled)
169  {
170  sink_it_(log_msg);
171  }
172  if (traceback_enabled)
173  {
174  tracer_.push_back(log_msg);
175  }
176 }
177 
179 {
180  for (auto &sink : sinks_)
181  {
182  if (sink->should_log(msg.level))
183  {
184  SPDLOG_TRY
185  {
186  sink->log(msg);
187  }
189  }
190  }
191 
192  if (should_flush_(msg))
193  {
194  flush_();
195  }
196 }
197 
199 {
200  for (auto &sink : sinks_)
201  {
202  SPDLOG_TRY
203  {
204  sink->flush();
205  }
207  }
208 }
209 
211 {
212  using details::log_msg;
213  if (tracer_.enabled())
214  {
215  sink_it_(log_msg{name(), level::info, "****************** Backtrace Start ******************"});
216  tracer_.foreach_pop([this](const log_msg &msg) { this->sink_it_(msg); });
217  sink_it_(log_msg{name(), level::info, "****************** Backtrace End ********************"});
218  }
219 }
220 
222 {
223  auto flush_level = flush_level_.load(std::memory_order_relaxed);
224  return (msg.level >= flush_level) && (msg.level != level::off);
225 }
226 
227 SPDLOG_INLINE void logger::err_handler_(const std::string &msg)
228 {
230  {
231  custom_err_handler_(msg);
232  }
233  else
234  {
235  using std::chrono::system_clock;
236  static std::mutex mutex;
237  static std::chrono::system_clock::time_point last_report_time;
238  static size_t err_counter = 0;
239  std::lock_guard<std::mutex> lk{mutex};
240  auto now = system_clock::now();
241  err_counter++;
242  if (now - last_report_time < std::chrono::seconds(1))
243  {
244  return;
245  }
246  last_report_time = now;
247  auto tm_time = details::os::localtime(system_clock::to_time_t(now));
248  char date_buf[64];
249  std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time);
250 #if defined(USING_R) && defined(R_R_H) // if in R environment
251  REprintf("[*** LOG ERROR #%04zu ***] [%s] [%s] {%s}\n", err_counter, date_buf, name().c_str(), msg.c_str());
252 #else
253  std::fprintf(stderr, "[*** LOG ERROR #%04zu ***] [%s] [%s] {%s}\n", err_counter, date_buf, name().c_str(), msg.c_str());
254 #endif
255  }
256 }
257 } // namespace spdlog
spdlog::logger::should_flush_
bool should_flush_(const details::log_msg &msg)
Definition: logger-inl.h:221
spdlog::logger::logger
logger(std::string name)
Definition: logger.h:58
spdlog::logger::sinks_
std::vector< sink_ptr > sinks_
Definition: logger.h:348
SPDLOG_NOEXCEPT
#define SPDLOG_NOEXCEPT
Definition: common.h:64
logger.h
spdlog::logger::clone
virtual std::shared_ptr< logger > clone(std::string logger_name)
Definition: logger-inl.h:158
SPDLOG_LOGGER_CATCH
#define SPDLOG_LOGGER_CATCH(location)
Definition: logger.h:31
spdlog::level::off
@ off
Definition: common.h:219
spdlog::logger::flush_level_
spdlog::level_t flush_level_
Definition: logger.h:350
spdlog::logger::set_formatter
void set_formatter(std::unique_ptr< formatter > f)
Definition: logger-inl.h:84
spdlog::logger::custom_err_handler_
err_handler custom_err_handler_
Definition: logger.h:351
spdlog::logger::tracer_
details::backtracer tracer_
Definition: logger.h:352
spdlog::logger::disable_backtrace
void disable_backtrace()
Definition: logger-inl.h:114
spdlog::logger::log_it_
void log_it_(const details::log_msg &log_msg, bool log_enabled, bool traceback_enabled)
Definition: logger-inl.h:166
spdlog::logger
Definition: logger.h:54
spdlog::level::info
@ info
Definition: common.h:215
std::swap
void swap(nlohmann::basic_json< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType > &j1, nlohmann::basic_json< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType > &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::basic_json< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType > >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::basic_json< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberUnsignedType, NumberFloatType, AllocatorType, JSONSerializer, BinaryType > >::value)
exchanges the values of two JSON objects
Definition: json.hpp:24114
spdlog::details::os::now
SPDLOG_INLINE spdlog::log_clock::time_point now() SPDLOG_NOEXCEPT
Definition: os-inl.h:71
spdlog::level::level_enum
level_enum
Definition: common.h:211
spdlog::logger::set_level
void set_level(level::level_enum log_level)
Definition: logger-inl.h:67
spdlog::logger::enable_backtrace
void enable_backtrace(size_t n_messages)
Definition: logger-inl.h:108
spdlog::logger::dump_backtrace
void dump_backtrace()
Definition: logger-inl.h:119
spdlog::logger::name_
std::string name_
Definition: logger.h:347
spdlog::swap
SPDLOG_INLINE void swap(logger &a, logger &b)
Definition: logger-inl.h:62
spdlog::logger::flush
void flush()
Definition: logger-inl.h:125
spdlog::details::backtracer::enabled
bool enabled() const
Definition: backtracer-inl.h:46
spdlog
Definition: async.h:25
spdlog::logger::level_
spdlog::level_t level_
Definition: logger.h:349
spdlog::logger::level
level::level_enum level() const
Definition: logger-inl.h:72
spdlog::details::os::localtime
SPDLOG_INLINE std::tm localtime(const std::time_t &time_tt) SPDLOG_NOEXCEPT
Definition: os-inl.h:84
fmt::v8::fprintf
auto fprintf(std::FILE *f, const S &fmt, const T &... args) -> int
Definition: printf.h:607
spdlog::source_loc
Definition: common.h:290
SPDLOG_INLINE
#define SPDLOG_INLINE
Definition: common.h:42
spdlog::details::log_msg::level
level::level_enum level
Definition: log_msg.h:21
spdlog::logger::sinks
const std::vector< sink_ptr > & sinks() const
Definition: logger-inl.h:141
spdlog::err_handler
std::function< void(const std::string &err_msg)> err_handler
Definition: common.h:129
spdlog::details::backtracer::foreach_pop
void foreach_pop(std::function< void(const details::log_msg &)> fun)
Definition: backtracer-inl.h:58
spdlog::logger::dump_backtrace_
void dump_backtrace_()
Definition: logger-inl.h:210
spdlog::logger::flush_on
void flush_on(level::level_enum log_level)
Definition: logger-inl.h:130
spdlog::logger::name
const std::string & name() const
Definition: logger-inl.h:77
spdlog::details::log_msg
Definition: log_msg.h:11
sink.h
spdlog::pattern_time_type
pattern_time_type
Definition: common.h:267
std
Definition: json.hpp:5213
pattern_formatter.h
spdlog::logger::sink_it_
virtual void sink_it_(const details::log_msg &msg)
Definition: logger-inl.h:178
spdlog::logger::set_error_handler
void set_error_handler(err_handler)
Definition: logger-inl.h:152
spdlog::details::backtracer::push_back
void push_back(const log_msg &msg)
Definition: backtracer-inl.h:51
spdlog::details::backtracer::enable
void enable(size_t size)
Definition: backtracer-inl.h:33
spdlog::logger::flush_
virtual void flush_()
Definition: logger-inl.h:198
load
end load("results.mat") colors
spdlog::details::log_msg::source
source_loc source
Definition: log_msg.h:29
spdlog::logger::operator=
logger & operator=(logger other) SPDLOG_NOEXCEPT
Definition: logger-inl.h:37
SPDLOG_TRY
#define SPDLOG_TRY
Definition: common.h:102
spdlog::logger::flush_level
level::level_enum flush_level() const
Definition: logger-inl.h:135
backtracer.h
spdlog::details::backtracer::disable
void disable()
Definition: backtracer-inl.h:40
spdlog::logger::err_handler_
void err_handler_(const std::string &msg)
Definition: logger-inl.h:227
spdlog::logger::set_pattern
void set_pattern(std::string pattern, pattern_time_type time_type=pattern_time_type::local)
Definition: logger-inl.h:101
spdlog::logger::swap
void swap(spdlog::logger &other) SPDLOG_NOEXCEPT
Definition: logger-inl.h:43