LibraryLink Utilities  3.0.1
Modern C++ wrapper over LibraryLink and WSTP
Logger.h
Go to the documentation of this file.
1 
6 #ifndef LLU_ERRORLOG_LOGGER_H
7 #define LLU_ERRORLOG_LOGGER_H
8 
9 #include <initializer_list>
10 #include <mutex>
11 #include <string>
12 #include <utility>
13 
14 #include "LLU/LibraryData.h"
15 #include "LLU/WSTP/WSStream.hpp"
16 
17 // Configuration macros to set desired level of logging at build time:
18 
23 #ifdef LLU_LOG_DEBUG
24 #define LLU_LOG_LEVEL_DEBUG
25 #define LLU_LOG_WARNING
26 #define LLU_LOG_DEBUG // workaround for a Doxygen bug
27 #endif
28 
33 #ifdef LLU_LOG_WARNING
34 #define LLU_LOG_LEVEL_WARNING
35 #define LLU_LOG_ERROR
36 #endif
37 
42 #ifdef LLU_LOG_ERROR
43 #define LLU_LOG_LEVEL_ERROR
44 #endif
45 
46 // Convenience macros to use in the code:
47 
48 #ifdef LLU_LOG_LEVEL_DEBUG
49 
55 #define LLU_DEBUG(...) LLU::Logger::log<LLU::Logger::Level::Debug>(__LINE__, __FILE__, __func__, __VA_ARGS__)
56 #else
57 #define LLU_DEBUG(...) ((void)0)
58 #endif
59 
60 #ifdef LLU_LOG_LEVEL_WARNING
61 
67 #define LLU_WARNING(...) LLU::Logger::log<LLU::Logger::Level::Warning>(__LINE__, __FILE__, __func__, __VA_ARGS__)
68 #else
69 #define LLU_WARNING(...) ((void)0)
70 #endif
71 
72 #ifdef LLU_LOG_LEVEL_ERROR
73 
79 #define LLU_ERROR(...) LLU::Logger::log<LLU::Logger::Level::Error>(__LINE__, __FILE__, __func__, __VA_ARGS__)
80 #else
81 #define LLU_ERROR(...) ((void)0)
82 #endif
83 
84 namespace LLU {
85 
90  class Logger {
91  public:
93  enum class Level { Debug, Warning, Error };
94 
107  template<Level L, typename... T>
108  static void log(WolframLibraryData libData, int line, const std::string& fileName, const std::string& function, T&&... args);
109 
121  template<Level L, typename... T>
122  static void log(int line, const std::string& fileName, const std::string& function, T&&... args);
123 
129  static std::string to_string(Level l);
130 
135  static void setContext(std::string context) {
136  logSymbolContext = std::move(context);
137  }
138 
143  static std::string getSymbol() {
144  return logSymbolContext + topLevelLogCallback;
145  }
146 
147  private:
149  static constexpr const char* topLevelLogCallback = "Logger`LogHandler";
150  static std::mutex mlinkGuard;
151  static std::string logSymbolContext;
152  };
153 
162  template<WS::Encoding EIn, WS::Encoding EOut>
163  static WSStream<EIn, EOut>& operator<<(WSStream<EIn, EOut>& ms, Logger::Level l) {
164  return ms << Logger::to_string(l);
165  }
166 
167  template<Logger::Level L, typename... T>
168  void Logger::log(WolframLibraryData libData, int line, const std::string& fileName, const std::string& function, T&&... args) {
169  if (!libData) {
170  return;
171  }
172  std::lock_guard<std::mutex> lock(mlinkGuard);
173 
174  WSStream<WS::Encoding::UTF8> mls {libData->getWSLINK(libData)};
175  mls << WS::Function("EvaluatePacket", 1);
176  mls << WS::Function(getSymbol(), 4 + sizeof...(T));
177  mls << L << line << fileName << function;
178  Unused((mls << ... << args));
179  libData->processWSLINK(mls.get());
180  auto pkt = WSNextPacket(mls.get());
181  if (pkt == RETURNPKT) {
182  mls << WS::NewPacket;
183  }
184  }
185 
186  template<Logger::Level L, typename... T>
187  void Logger::log(int line, const std::string& fileName, const std::string& function, T&&... args) {
188  log<L>(LibraryData::API(), line, fileName, function, std::forward<T>(args)...);
189  }
190 
191 } // namespace LLU
192 #endif // LLU_ERRORLOG_LOGGER_H
LLU::Logger::to_string
static std::string to_string(Level l)
Converts Logger::Level value to std::string.
Definition: Logger.cpp:15
LLU::Logger::setContext
static void setContext(std::string context)
Set new context for the top-level symbol that will handle logging.
Definition: Logger.h:135
LLU
Main namespace of LibraryLink Utilities.
Definition: Queue.h:13
LLU::WSStream
Wrapper class over WSTP with a stream-like interface.
Definition: WSTP/Utilities.h:21
LLU::WS::Function
Structure representing any function in Wolfram Language, i.e. a head plus number of arguments.
Definition: WSTP/Utilities.h:65
LLU::Logger
Logger class is responsible for sending log messages via WSTP to Mathematica.
Definition: Logger.h:90
LibraryData.h
WSStream.hpp
Header file for WSStream class.
LLU::LibraryData::API
static WolframLibraryData API()
Get currently owned WolframLibraryData, if any.
Definition: LibraryData.cpp:22
LLU::Logger::log
static void log(WolframLibraryData libData, int line, const std::string &fileName, const std::string &function, T &&... args)
Send a log message of given severity.
Definition: Logger.h:168
LLU::Unused
void Unused(Ts &&...)
Dummy function called on otherwise unused parameters to eliminate compiler warnings.
Definition: Utilities.hpp:115
LLU::WS::NewPacket
WSStream< EIn, EOut > & NewPacket(WSStream< EIn, EOut > &ms)
NewPacket is a WSStream token which tells WSTP to skip to the end of the current packet.
Definition: WSTP/Utilities.h:203
LLU::Logger::Level
Level
Possible log severity levels.
Definition: Logger.h:93
LLU::operator<<
std::ostream & operator<<(std::ostream &os, const MArray< T > &c)
Insertion operator to allow pretty-printing of MArray.
Definition: MArray.hpp:167
LLU::Logger::getSymbol
static std::string getSymbol()
Get the top-level symbol with full context, to which all logs are sent.
Definition: Logger.h:143