OSVR Framework (Internal Development Docs)  0.6-1962-g59773924
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
Logger.cpp
Go to the documentation of this file.
1 
12 // Copyright 2016 Sensics, Inc.
13 //
14 // Licensed under the Apache License, Version 2.0 (the "License");
15 // you may not use this file except in compliance with the License.
16 // You may obtain a copy of the License at
17 //
18 // http://www.apache.org/licenses/LICENSE-2.0
19 //
20 // Unless required by applicable law or agreed to in writing, software
21 // distributed under the License is distributed on an "AS IS" BASIS,
22 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 // See the License for the specific language governing permissions and
24 // limitations under the License.
25 
26 // Internal Includes
27 #include <osvr/Util/Logger.h>
28 
29 #include "LogDefaults.h"
30 #include "LogLevelTranslate.h"
31 
32 // Library/third-party includes
33 #include <spdlog/spdlog.h>
34 #include <spdlog/sinks/null_sink.h>
35 
36 // Standard includes
37 #include <iostream>
38 #include <memory> // for std::shared_ptr
39 #include <string> // for std::string
40 #include <utility> // for std::forward
41 
42 namespace osvr {
43 namespace util {
44  namespace log {
45 
46  inline LoggerPtr
47  Logger::makeLogger(std::string const &name,
48  std::shared_ptr<spdlog::logger> const &logger) {
49 
50 #ifdef OSVR_USE_UNIQUEPTR_FOR_LOGGER
51  auto ret = LoggerPtr{new Logger{
52  name, logger, static_cast<PrivateConstructor *>(nullptr)}};
53 #else
54  auto ret = std::make_shared<Logger>(
55  name, logger, static_cast<PrivateConstructor *>(nullptr));
56 #endif
57  return ret;
58  }
59 
60  Logger::Logger(std::string const &name,
61  std::shared_ptr<spdlog::logger> logger,
62  PrivateConstructor *)
63  : name_(name), logger_(std::move(logger)) {}
64 
66 
67  LoggerPtr Logger::makeFallback(std::string const &name) {
68  // First, we'll attempt to create a console logger to use as a
69  // fallback. If that fails, we'll create a do-nothing logger
70  // instead.
71  std::cerr << "WARNING: Logger created for '" << name
72  << "' is a 'fallback' logger -- an internal error has "
73  "prevented a standard logger from being created. "
74  "Please report this issue in OSVR-Core on GitHub."
75  << std::endl;
76  try {
77  auto console_logger = spdlog::stderr_logger_mt(name);
78  return makeLogger(name, console_logger);
79  } catch (...) {
80  std::cerr << "Failed to create a console logger to use as a "
81  "fallback. Logging will be disabled entirely."
82  << std::endl;
83  auto null_sink = std::make_shared<spdlog::sinks::null_sink_st>();
84  auto null_logger = std::make_shared<spdlog::logger>(name, null_sink);
85  return makeLogger(name, null_logger);
86  }
87  }
88 
90  std::string const &name, std::shared_ptr<spdlog::logger> logger) {
91  if (!logger) {
92  std::cerr
93  << "WARNING: Logger::makeFromExistingImplementation(\""
94  << name << "\", logger) called with a null logger pointer! "
95  << "Will result in a fallback logger!" << std::endl;
96  return makeFallback(name);
97  }
98  return makeLogger(name, logger);
99  }
100 
101  LoggerPtr Logger::makeWithSink(std::string const &name,
102  spdlog::sink_ptr sink) {
103  if (!sink) {
104  // bad sink!
105  std::cerr << "WARNING: Logger::makeWithSink(\"" << name
106  << "\", sink) called with a null sink! Will result "
107  "in a fallback logger!"
108  << std::endl;
109  return makeFallback(name);
110  }
111  auto spd_logger = std::make_shared<spdlog::logger>(name, sink);
112  spd_logger->set_pattern(DEFAULT_PATTERN);
113  spd_logger->flush_on(convertToLevelEnum(DEFAULT_FLUSH_LEVEL));
114  return makeLogger(name, spd_logger);
115  }
116 
117  LoggerPtr Logger::makeWithSinks(std::string const &name,
118  spdlog::sinks_init_list sinks) {
119  for (auto &sink : sinks) {
120  if (!sink) {
121  std::cerr << "WARNING: "
122  "Logger::makeWithSinks(\""
123  << name << "\", sinks) called "
124  "with at least one null sink! Will "
125  "result in a fallback logger!"
126  << std::endl;
127  // got a bad sink
132  return makeFallback(name);
133  }
134  }
135  auto spd_logger = std::make_shared<spdlog::logger>(name, sinks);
136  spd_logger->set_pattern(DEFAULT_PATTERN);
137  spd_logger->flush_on(convertToLevelEnum(DEFAULT_FLUSH_LEVEL));
138  return makeLogger(name, spd_logger);
139  }
140 
141  LogLevel Logger::getLogLevel() const {
142  return convertFromLevelEnum(logger_->level());
143  }
144 
145  void Logger::setLogLevel(LogLevel level) {
146  logger_->set_level(convertToLevelEnum(level));
147  }
148 
149  void Logger::flushOn(LogLevel level) {
150  logger_->flush_on(convertToLevelEnum(level));
151  }
152 
153  Logger::StreamProxy Logger::trace(const char *msg) {
154  return { *this, LogLevel::trace, msg };
155  }
156 
157  Logger::StreamProxy Logger::debug(const char *msg) {
158  return { *this, LogLevel::debug, msg };
159  }
160 
161  Logger::StreamProxy Logger::info(const char *msg) {
162  return { *this, LogLevel::info, msg };
163  }
164 
165  Logger::StreamProxy Logger::notice(const char *msg) {
166  return { *this, LogLevel::notice, msg };
167  }
168 
169  Logger::StreamProxy Logger::warn(const char *msg) {
170  return { *this, LogLevel::warn, msg };
171  }
172 
173  Logger::StreamProxy Logger::error(const char *msg) {
174  return { *this, LogLevel::error, msg };
175  }
176 
177  Logger::StreamProxy Logger::critical(const char *msg) {
178  return { *this, LogLevel::critical, msg };
179  }
180 
181  // logger.info() << ".." call style
182  Logger::StreamProxy Logger::trace() {
183  return { *this, LogLevel::trace };
184  }
185 
186  Logger::StreamProxy Logger::debug() {
187  return { *this, LogLevel::debug };
188  }
189 
190  Logger::StreamProxy Logger::info() {
191  return { *this, LogLevel::info };
192  }
193 
194  Logger::StreamProxy Logger::notice() {
195  return { *this, LogLevel::notice };
196  }
197 
198  Logger::StreamProxy Logger::warn() {
199  return { *this, LogLevel::warn };
200  }
201 
202  Logger::StreamProxy Logger::error() {
203  return { *this, LogLevel::error };
204  }
205 
206  Logger::StreamProxy Logger::critical() {
207  return { *this, LogLevel::critical };
208  }
209 
210  // logger.log(log_level, msg) << ".." call style
211  Logger::StreamProxy Logger::log(LogLevel level, const char *msg) {
212  switch (level) {
213  case LogLevel::trace:
214  return trace(msg);
215  case LogLevel::debug:
216  return debug(msg);
217  case LogLevel::info:
218  return info(msg);
219  case LogLevel::notice:
220  return notice(msg);
221  case LogLevel::warn:
222  return warn(msg);
223  case LogLevel::error:
224  return error(msg);
225  case LogLevel::critical:
226  return critical(msg);
227  }
228 
229  return info(msg);
230  }
231 
232  // logger.log(log_level) << ".." call style
234  switch (level) {
235  case LogLevel::trace:
236  return trace();
237  case LogLevel::debug:
238  return debug();
239  case LogLevel::info:
240  return info();
241  case LogLevel::notice:
242  return notice();
243  case LogLevel::warn:
244  return warn();
245  case LogLevel::error:
246  return error();
247  case LogLevel::critical:
248  return critical();
249  }
250 
251  return info();
252  }
253 
254  void Logger::flush() {
255  logger_->flush();
256  }
257 
258  void Logger::write(LogLevel level, const char* msg)
259  {
260  logger_->log(convertToLevelEnum(level), msg);
261  }
262 
263  } // namespace log
264 } // namespace util
265 } // namespace osvr
static LoggerPtr makeFromExistingImplementation(std::string const &name, std::shared_ptr< spdlog::logger > logger)
Definition: Logger.cpp:89
STL namespace.
void setLogLevel(LogLevel level)
Definition: Logger.cpp:145
static LoggerPtr makeWithSinks(std::string const &name, spdlog::sinks_init_list sinks)
Definition: Logger.cpp:117
~Logger()
Destructor.
Definition: Logger.cpp:65
LogLevel getLogLevel() const
Definition: Logger.cpp:141
static LoggerPtr makeWithSink(std::string const &name, spdlog::sink_ptr sink)
Definition: Logger.cpp:101
Header to include for OSVR-internal usage of the logging mechanism: provides the needed definition of...
Logger(std::string const &name, std::shared_ptr< spdlog::logger > logger, PrivateConstructor *)
Definition: Logger.cpp:60
void flushOn(LogLevel level)
Set the log level at which this logger will trigger a flush.
Definition: Logger.cpp:149
void flush()
Make sure this logger has written out its data.
Definition: Logger.cpp:254
StreamProxy log(LogLevel level, const char *msg)
Definition: Logger.cpp:211