iMSTK
Interactive Medical Simulation Toolkit
imstkLoggerG3.cpp
1 /*
2 ** This file is part of the Interactive Medical Simulation Toolkit (iMSTK)
3 ** iMSTK is distributed under the Apache License, Version 2.0.
4 ** See accompanying NOTICE for details.
5 */
6 
7 #include "imstkLoggerG3.h"
8 
9 #include "g3log/crashhandler.hpp"
10 
11 #include <iostream>
12 #ifdef WIN32
13 #include <windows.h>
14 #endif
15 
16 namespace imstk
17 {
18 stdSink::FontColor
19 stdSink::GetColor(const LEVELS level) const
20 {
21  if (level.value == WARNING.value)
22  {
23  return FontColor::Yellow;
24  }
25  if (level.value == DEBUG.value)
26  {
27  return FontColor::Green;
28  }
29  if (level.value == FATAL.value)
30  {
31  return FontColor::Red;
32  }
33  return FontColor::White;
34 }
35 
36 #ifdef WIN32
37 
38 #define WIN_CONSOLE_RED 4
39 #define WIN_CONSOLE_LIGHT_GRAY 7
40 #define WIN_CONSOLE_YELLOW 14
41 
42 void
43 setColorWin(const int colCode)
44 {
45  WORD wColor = ((0 & 0x0F) << 4) + (colCode & 0x0F); // black background
46  SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor);
47 }
48 
49 #endif
50 
51 void
52 stdSink::ReceiveLogMessage(g3::LogMessageMover logEntry)
53 {
54  const auto level = logEntry.get()._level;
55  const auto message = logEntry.get().message();
56 
57 #ifndef WIN32
58  auto color = static_cast<int>(GetColor(level));
59  std::cout << "\033[" << color << "m"
60  << message
61  << "\033[m" << std::endl;
62 #else
63 
64  if (level.value == WARNING.value)
65  {
66  setColorWin(WIN_CONSOLE_YELLOW);
67  std::cerr << message << std::endl;
68  setColorWin(WIN_CONSOLE_LIGHT_GRAY);
69  }
70  else if (level.value == FATAL.value)
71  {
72  setColorWin(WIN_CONSOLE_RED);
73  std::cerr << message << std::endl;
74  setColorWin(WIN_CONSOLE_LIGHT_GRAY);
75  }
76  else
77  {
78  std::cout << message << std::endl;
79  }
80 #endif
81 }
82 
85 {
86  // Thread safe in C++11 ("magic statics")
87  static LoggerG3 instance;
88  if (instance.m_g3logWorker == nullptr)
89  {
90  instance.initialize();
91  }
92 
93  return instance;
94 }
95 
96 LoggerG3&
98 {
99  // As logger is a static object we fetch and destroy
100  // the logger this will reset all sinks
101  {
102  LoggerG3& logger = LoggerG3::getInstance();
103  logger.destroy();
104  }
105 
106  LoggerG3& logger = LoggerG3::getInstance();
107 
108  logger.addFileSink("simulation");
109  logger.addStdoutSink();
110  return logger;
111 }
112 
113 std::unique_ptr<StdoutSinkHandle>
115 {
116  return std::unique_ptr<StdoutSinkHandle>(std::move(m_g3logWorker->addSink(std2::make_unique<stdSink>(), &stdSink::ReceiveLogMessage)));
117 }
118 
119 std::unique_ptr<FileSinkHandle>
120 LoggerG3::addFileSink(const std::string& name, const std::string& path)
121 {
122  return std::unique_ptr<FileSinkHandle>(m_g3logWorker->addDefaultLogger(name, path, "imstk"));
123 }
124 
125 void
127 {
128  m_g3logWorker = g3::LogWorker::createLogWorker();
129  g3::initializeLogging(m_g3logWorker.get());
130 }
131 
132 void
134 {
135  m_g3logWorker = nullptr;
136 }
137 
138 LoggerG3::LoggerG3()
139 {
140  initialize();
141 }
142 } // namespace imstk
std::unique_ptr< StdoutSinkHandle > addStdoutSink()
Add a sink that logs to standard output.
Compound Geometry.
static LoggerG3 & getInstance()
Gets logger instances without sinks, creates if doesn&#39;t exist yet.
void destroy()
Manual destruction of the logger members.
void initialize()
Create and initialize the logger.
std::unique_ptr< FileSinkHandle > addFileSink(const std::string &name, const std::string &path="./")
Add a sink that logs to file.
static LoggerG3 & startLogger()
Starts logger with default sinks, use getInstance to create a logger with no sinks.