ionLogger.h
Go to the documentation of this file.
1 
9 #pragma once
10 
11 #include "ionStandardLibrary.h"
12 
13 #include <tinyformat.h>
14 #ifdef ION_CONFIG_WINDOWS
15 #include <Windows.h>
16 #endif
17 
20 enum class ELogChannel
21 {
22  Error = 0,
23  Warn = 1,
24  Info = 2
25 };
26 
29 class Log
30 {
31 
32 public:
33 
34  class Output
35  {
36 
37  public:
38 
39  virtual void Write(string const & Message) = 0;
40 
41  };
42 
43  class StandardOutput : public Output
44  {
45 
46  public:
47 
48  StandardOutput(std::ostream & Stream)
49  : Stream(Stream)
50  {}
51 
52  virtual void Write(string const & Message)
53  {
54  Stream << Message << endl;
55  }
56 
57  private:
58 
59  std::ostream & Stream;
60 
61  };
62 
63 #ifdef ION_CONFIG_WINDOWS
64  class DebugLogOutput : public Output
65  {
66 
67  public:
68 
69  virtual void Write(string const & Message)
70  {
71  OutputDebugString(Message.c_str());
72  OutputDebugString("\n");
73  }
74 
75  };
76 #endif
77 
78  template <typename... Args>
79  static void Info(char const * const Format, Args const &... args)
80  {
81  Write(ELogChannel::Info, Format, args...);
82  }
83 
84  template <typename... Args>
85  static void Warn(char const * const Format, Args const &... args)
86  {
87  Write(ELogChannel::Warn, Format, args...);
88  }
89 
90  template <typename... Args>
91  static void Error(char const * const Format, Args const &... args)
92  {
93  Write(ELogChannel::Error, Format, args...);
94  }
95 
96  template <typename... Args>
97  static void Write(ELogChannel const Channel, char const * const Format, Args const &... args)
98  {
99 #ifndef _ION_CONFIG_SUPPRESS_LOG
100  WriteInternal(Channel, tfm::format(Format, args...));
101 #endif
102  }
103 
104  static vector<string> const & GetMessages()
105  {
106  return AllLoggedMessages();
107  }
108 
109  static vector<string> const & GetMessages(ELogChannel const Which)
110  {
111  return GetChannel(Which).Messages;
112  }
113 
114  static vector<pair<string, int>> const & GetMessagesDetail(ELogChannel const Which)
115  {
116  return GetChannel(Which).GetMessagesDetail();
117  }
118 
119  static void AddOutput(ELogChannel const Which, Output * Out)
120  {
121  GetChannel(Which).WriteTo.push_back(Out);
122  }
123 
124  static void AddOutputToAllChannels(Output * Out)
125  {
126  GetChannel(ELogChannel::Error).WriteTo.push_back(Out);
127  GetChannel(ELogChannel::Warn).WriteTo.push_back(Out);
128  GetChannel(ELogChannel::Info).WriteTo.push_back(Out);
129  }
130 
131  static void AddDefaultOutputs()
132  {
133  AddOutput(ELogChannel::Error, new StandardOutput(cerr));
134  AddOutput(ELogChannel::Warn, new StandardOutput(cerr));
135  AddOutput(ELogChannel::Info, new StandardOutput(cout));
136 #ifdef ION_CONFIG_WINDOWS
137  AddOutputToAllChannels(new DebugLogOutput());
138 #endif
139  }
140 
141  static void Clear()
142  {
143  AllLoggedMessages().clear();
144  GetChannel(ELogChannel::Info).Messages.clear();
145  GetChannel(ELogChannel::Info).MessageMap.clear();
146  GetChannel(ELogChannel::Warn).Messages.clear();
147  GetChannel(ELogChannel::Warn).MessageMap.clear();
148  GetChannel(ELogChannel::Error).Messages.clear();
149  GetChannel(ELogChannel::Error).MessageMap.clear();
150  }
151 
152 protected:
153 
154  class Channel
155  {
156 
157  public:
158 
159  string Label;
160  vector<Output *> WriteTo;
161  vector<string> Messages;
162  vector<pair<string, int>> MessagesDetail;
163  unordered_map<string, int> MessageMap;
164 
165  Channel(string const & Label)
166  {
167  this->Label = Label;
168  }
169 
171  bool WriteMessage(string const & ToWrite)
172  {
173  auto LookUp = MessageMap.find(ToWrite);
174 
175  for (Output * Out : WriteTo)
176  {
177  Out->Write(ToWrite);
178  }
179 
180  if (LookUp != MessageMap.end())
181  {
182  LookUp->second ++;
183 
184  return false;
185  }
186  else
187  {
188  MessageMap[ToWrite] = 1;
189  Messages.push_back(ToWrite);
190 
191  return true;
192  }
193  }
194 
195  vector<pair<string, int>> const & GetMessagesDetail()
196  {
197  MessagesDetail.clear();
198 
199  for (auto const & Message : Messages)
200  {
201  MessagesDetail.push_back(make_pair(Message, MessageMap[Message]));
202  }
203 
204  return MessagesDetail;
205  }
206 
207  };
208 
209  static Channel & GetChannel(ELogChannel const Which)
210  {
211  static Channel Info("Info");
212  static Channel Warn("Warn");
213  static Channel Error("Error");
214 
215  switch (Which)
216  {
217  default:
218  case ELogChannel::Info:
219  return Info;
220  case ELogChannel::Warn:
221  return Warn;
222  case ELogChannel::Error:
223  return Error;
224  }
225  }
226 
227  static string GetChannelLabel(ELogChannel const Which)
228  {
229  return GetChannel(Which).Label;
230  }
231 
232  static void WriteInternal(ELogChannel const Which, std::string const & Message)
233  {
234  if (GetChannel(Which).WriteMessage(Message))
235  {
236  AllLoggedMessages().push_back(GetChannelLabel(Which) + ": " + Message);
237  }
238  }
239 
240  static vector<string> & AllLoggedMessages()
241  {
242  static vector<string> AllLoggedMessages;
243  return AllLoggedMessages;
244  }
245 
246 };
static void Clear()
Definition: ionLogger.h:141
StandardOutput(std::ostream &Stream)
Definition: ionLogger.h:48
static void AddDefaultOutputs()
Definition: ionLogger.h:131
Definition: ionLogger.h:43
static vector< string > const & GetMessages(ELogChannel const Which)
Definition: ionLogger.h:109
Definition: ionLogger.h:34
Channel(string const &Label)
Definition: ionLogger.h:165
static void Error(char const *const Format, Args const &...args)
Definition: ionLogger.h:91
Brings a lot of elements from std namespace into the global namespace.
static void Write(ELogChannel const Channel, char const *const Format, Args const &...args)
Definition: ionLogger.h:97
ELogChannel
Channels used by Log.
Definition: ionLogger.h:20
Logging class.
Definition: ionLogger.h:29
vector< pair< string, int > > const & GetMessagesDetail()
Definition: ionLogger.h:195
Definition: ionLogger.h:154
vector< pair< string, int > > MessagesDetail
Definition: ionLogger.h:162
string Label
Definition: ionLogger.h:159
static vector< pair< string, int > > const & GetMessagesDetail(ELogChannel const Which)
Definition: ionLogger.h:114
vector< Output * > WriteTo
Definition: ionLogger.h:160
static void Warn(char const *const Format, Args const &...args)
Definition: ionLogger.h:85
vector< string > Messages
Definition: ionLogger.h:161
bool WriteMessage(string const &ToWrite)
Definition: ionLogger.h:171
static void WriteInternal(ELogChannel const Which, std::string const &Message)
Definition: ionLogger.h:232
unordered_map< string, int > MessageMap
Definition: ionLogger.h:163
virtual void Write(string const &Message)
Definition: ionLogger.h:52
static void Info(char const *const Format, Args const &...args)
Definition: ionLogger.h:79
static void AddOutputToAllChannels(Output *Out)
Definition: ionLogger.h:124
static vector< string > const & GetMessages()
Definition: ionLogger.h:104
static vector< string > & AllLoggedMessages()
Definition: ionLogger.h:240
static void AddOutput(ELogChannel const Which, Output *Out)
Definition: ionLogger.h:119
static string GetChannelLabel(ELogChannel const Which)
Definition: ionLogger.h:227
static Channel & GetChannel(ELogChannel const Which)
Definition: ionLogger.h:209