TrueReality  v0.1.1912
Log.cpp
Go to the documentation of this file.
1 /*
2 * True Reality Open Source Game and Simulation Engine
3 * Copyright © 2021 Acid Rain Studios LLC
4 *
5 * The Base of this class has been adopted from the Delta3D engine
6 *
7 * This library is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU Lesser General Public License as published by the Free
9 * Software Foundation; either version 3.0 of the License, or (at your option)
10 * any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15 * details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * @author Matthew W. Campbell
22 * @author Erik Johnson
23 * @author David Guthrie
24 * @author Maxim Serebrennik
25 */
26 
27 #include <trUtil/Logging/Log.h>
28 
29 #include <trUtil/Bits.h>
32 #include <trUtil/StringUtils.h>
33 
34 
35 #include <osg/Referenced>
36 #include <osg/ref_ptr>
37 #include <osg/observer_ptr>
38 #include <osgDB/FileNameUtils>
39 
40 
41 #include <algorithm>
42 #include <stdarg.h>
43 
44 namespace trUtil::Logging
45 {
46  static osg::ref_ptr<LogManager> LOG_MANAGER(NULL);
48 
50  class LogImpl //: std::stringbuf
51  {
52  public:
53  explicit LogImpl(const std::string& name)
54  : mOutputStreamBit(Log::STANDARD)
55  , mName(name)
57  , mWriters()
58  {
59  }
60 
61  unsigned int mOutputStreamBit;
62  std::string mName;
63  LogLevel mLevel;
65  };
66 
68  const std::string Log::LOG_DEFAULT_NAME("MainLog");
69 
71  Log::Log(const std::string& name)
72  :
73  mImpl(new LogImpl(name))
74  {
75  }
76 
79  {
80  delete mImpl;
81  mImpl = nullptr;
82  }
83 
85  void Log::LogMessage(const std::string& cppFile, const std::string& method, int line, const std::string& msg, LogLevel logLevel) const
86  {
88  {
89  return;
90  }
91 
92  if (logLevel < mImpl->mLevel)
93  {
94  return;
95  }
96 
97  OpenThreads::ScopedLock<OpenThreads::Mutex> lock(LOG_MANAGER->GetMutex());
98  bool hasLogTimeProvider = LOG_MANAGER->IsLogTimeProviderValid();
99 
100  LogWriter::LogData logData;
101  if (hasLogTimeProvider)
102  {
103  logData.frameNumber = LOG_MANAGER->GetFrameNumber();
104  logData.time = LOG_MANAGER->GetDateTime();
105  }
106  else
107  {
108  logData.time.SetToLocalTime();
109  }
110 
111  logData.logLevel = logLevel;
112  logData.logName = mImpl->mName;
113  logData.file = osgDB::getSimpleFileName(cppFile);
114  logData.method = method;
115  logData.line = line;
116  logData.msg = msg;
117 
118  // If testing is enabled, copy the logg data to an accessible variable
119  if (mTestingMode)
120  {
122  mLogTestData.time = logData.time;
123  mLogTestData.logLevel = logData.logLevel;
124  mLogTestData.logName = logData.logName;
125  mLogTestData.file = logData.file;
126  mLogTestData.method = logData.method;
127  mLogTestData.line = logData.line;
128  mLogTestData.msg = logData.msg;
129  }
130 
132  {
133  LOG_MANAGER->LogMessageToFile(logData);
134  }
135 
137  {
138  LOG_MANAGER->LogMessageToConsole(logData);
139  }
140 
142  {
143  Log::LogWriterContainer::iterator itr = mImpl->mWriters.begin();
144  while (itr != mImpl->mWriters.end())
145  {
146  (*itr)->LogMessage(logData);
147  ++itr;
148  }
149  }
150  }
151 
153  void Log::LogMessage(LogLevel logLevel, const std::string& source, int line, const char* msg, va_list list) const
154  {
155  char buffer[2049];
156 
157  vsnprintf(buffer, 2049, msg, list);
158 
159  LogMessage("", source, line, buffer, logLevel);
160  }
161 
163  void Log::LogMessage(LogLevel logLevel, const std::string& source, const char* msg, ...) const
164  {
165  va_list list;
166 
167  va_start(list, msg);
168  LogMessage(logLevel, source, -1, msg, list);
169  va_end(list);
170  }
171 
173  void Log::LogMessage(LogLevel logLevel, const std::string& source, int line, const char* msg, ...) const
174  {
175  va_list list;
176 
177  va_start(list, msg);
178  LogMessage(logLevel, source, line, msg, list);
179  va_end(list);
180  }
181 
183  void Log::LogMessage(LogLevel logLevel, const std::string& source, int line, const std::string& msg) const
184  {
185  LogMessage("", source, line, msg, logLevel);
186  }
187 
190  {
192  {
193  return;
194  }
195 
197  {
198  LOG_MANAGER->LogHorizRule();
199  }
200  }
201 
203  Log& Log::GetInstance(const std::string& name)
204  {
205  if (LOG_MANAGER == nullptr)
206  {
207  LOG_MANAGER = new LogManager;
208  }
209 
210  Log* l = LOG_MANAGER->GetInstance(name);
211  if (l == nullptr)
212  {
213  l = new Log(name);
214  LOG_MANAGER->AddInstance(name, l);
215  }
216 
217  return *l;
218  }
219 
222  {
223  return *LOG_MANAGER;
224  }
225 
227  void Log::SetTestMode(bool state)
228  {
229  OpenThreads::ScopedLock<OpenThreads::Mutex> lock(LOG_MANAGER->GetMutex());
230  mTestingMode = state;
231  }
232 
235  {
236  OpenThreads::ScopedLock<OpenThreads::Mutex> lock(LOG_MANAGER->GetMutex());
237  return &mLogTestData;
238  }
239 
241  void Log::SetDefaultLogLevel(LogLevel newLevel)
242  {
243  DEFAULT_LOG_LEVEL = newLevel;
244  }
245 
247  const std::string Log::GetLogLevelString(LogLevel logLevel) //static
248  {
249  return LogLevelToString(logLevel);
250  }
251 
253  LogLevel Log::GetLogLevelForString(const std::string& levelString) //static
254  {
255  return LogLevelFromString(levelString);
256  }
257 
259  void Log::SetOutputStreamBit(unsigned int option)
260  {
261  mImpl->mOutputStreamBit = option;
262  }
263 
265  void Log::SetAllOutputStreamBits(unsigned int option)
266  {
267  if (LOG_MANAGER.valid())
268  {
269  LOG_MANAGER->SetAllOutputStreamBits(option);
270  }
271  }
272 
274  unsigned int Log::GetOutputStreamBit() const
275  {
276  return mImpl->mOutputStreamBit;
277  }
278 
280  const std::string& Log::GetName() const
281  {
282  return mImpl->mName;
283  }
284 
286  bool Log::IsLevelEnabled(LogLevel logLevel) const
287  {
288  return logLevel >= mImpl->mLevel;
289  }
290 
292  void Log::SetLogLevel(LogLevel logLevel)
293  {
294  mImpl->mLevel = logLevel;
295  }
296 
298  LogLevel Log::GetLogLevel() const
299  {
300  return mImpl->mLevel;
301  }
302 
304  void Log::SetAllLogLevels(LogLevel newLevel) //static
305  {
306  if (LOG_MANAGER.valid())
307  {
308  LOG_MANAGER->SetAllLogLevels(newLevel);
309  }
310  }
311 
314  {
315  if (LOG_MANAGER.valid())
316  {
317  LOG_MANAGER->SetLogTimeProvider(ltp);
318 
319  if (ltp != NULL && !LOG_MANAGER->IsLogTimeProviderValid())
320  {
321  LOG_E("Unable to assign log time provider because it did not provide a referenced object as a key for deletion");
322  LOG_MANAGER->SetLogTimeProvider(NULL);
323  }
324  }
325  }
326 
328  void Log::AddWriter(LogWriter& writer)
329  {
330  mImpl->mWriters.push_back(&writer);
331  }
332 
335  {
336  return mImpl->mWriters;
337  }
338 
341  {
342  return mImpl->mWriters;
343  }
344 
347  {
348  LogWriterContainer::iterator found = std::find(mImpl->mWriters.begin(),
349  mImpl->mWriters.end(), &writer);
350  if (found != mImpl->mWriters.end())
351  {
352  mImpl->mWriters.erase(found);
353  }
354  }
355 
357  LoggingOff::LoggingOff(const std::string& name)
358  : mLog(trUtil::Logging::Log::GetInstance(name))
359  {
361  // Only ALWAYS log levels are on.
362  mLog.SetLogLevel(trUtil::Logging::LogLevel::LOG_ALWAYS);
363  }
366  {
368  }
369 }
LogManager & GetLogManagerRef()
Returns a reference to the internal Log Manager.
Definition: Log.cpp:221
Log class which the engine uses for all of its logging needs.
Definition: Log.h:197
std::string logName
The frame number.
Definition: LogWriter.h:75
bool Has(N number, B bits)
See if the "bits" are in "number".
Definition: Bits.h:59
std::string file
The name of the Log instance (could be empty)
Definition: LogWriter.h:76
void LogMessage(const std::string &cppFile, const std::string &method, int line, const std::string &msg, LogLevel logLevel) const
Logs a time-stamped message.
Definition: Log.cpp:85
trUtil::Logging::LogLevel logLevel
Definition: Log.h:208
Interface class get the time for the logger.
int line
The calling method of the message.
Definition: LogWriter.h:78
bool mTestingMode
Definition: Log.h:550
void SetToLocalTime()
Changes time to be system local time.
Definition: DateTime.cpp:205
static void SetAllOutputStreamBits(unsigned int option)
The same as above, but it sets the bits on ALL active log instances.
Definition: Log.cpp:265
~Log()
Writes any closing html tags and closes the log file.
Definition: Log.cpp:78
bool IsLevelEnabled(LogLevel logLevel) const
Queries if a level is enabled.
Definition: Log.cpp:286
std::string file
The name of the Log instance (could be empty)
Definition: Log.h:212
int line
The calling method of the message.
Definition: Log.h:214
static const std::string GetLogLevelString(LogLevel logLevel)
Gets log level string.
Definition: Log.cpp:247
void SetLogLevel(LogLevel logLevel)
Sets the lowest level of logging that will be logged.
Definition: Log.cpp:292
LogImpl * mImpl
Definition: Log.h:548
LogTestData * GetLastLogData() const
Gets the last log data that was in the queue for testing.
Definition: Log.cpp:234
std::string msg
The line number of the source code of the message.
Definition: Log.h:215
void LogHorizRule()
Inserts a horizontal rule into the log file.
Definition: Log.cpp:189
std::vector< osg::ref_ptr< LogWriter > > LogWriterContainer
The log writer container.
Definition: Log.h:425
LoggingOff(const std::string &name=Log::LOG_DEFAULT_NAME)
Constructor.
Definition: Log.cpp:357
Manager for logs.
Definition: LogManager.h:56
unsigned int GetOutputStreamBit() const
Get the currently defined output stream options.
Definition: Log.cpp:274
A data structure that is used for Unit Tests.
Definition: Log.h:206
static LogLevel DEFAULT_LOG_LEVEL(LogLevel::LOG_WARNING)
const LogWriterContainer & GetWriters() const
Get all registered LogWriters that are registered to receive log messages.
Definition: Log.cpp:334
void RemoveWriter(LogWriter &writer)
Remove an existing LogWriter from the container.
Definition: Log.cpp:346
static void SetDefaultLogLevel(LogLevel newLevel)
Sets the default LogLevel for new logs.
Definition: Log.cpp:241
void AddWriter(LogWriter &writer)
Add an writer that receives all log messages via callback.
Definition: Log.cpp:328
TR_UTIL_EXPORT LogLevel LogLevelFromString(const std::string &levelString)
Logs level from string.
Definition: LogLevel.cpp:32
Interface class to receive messages from the Log.
Definition: LogWriter.h:51
std::string logName
The frame number.
Definition: Log.h:211
static void SetAllLogLevels(LogLevel newLevel)
Set the LogLevel for all existing Log instances.
Definition: Log.cpp:304
#define LOG_E(msg)
Log an ERROR message.
Definition: Log.h:165
LogImpl(const std::string &name)
Definition: Log.cpp:53
std::string method
The source file of the message.
Definition: LogWriter.h:77
trUtil::DateTime time
Log level.
Definition: Log.h:209
static const std::string LOG_DEFAULT_NAME
Definition: Log.h:218
Namespace that holds various utility classes for the engine.
Definition: SmrtPtr.h:208
unsigned int mOutputStreamBit
the current output stream option
Definition: Log.cpp:61
const std::string & GetName() const
Returns the name of this logger.
Definition: Log.cpp:280
unsigned frameNumber
Time of message.
Definition: Log.h:210
static LogLevel GetLogLevelForString(const std::string &levelString)
Gets log level for string.
Definition: Log.cpp:253
void SetOutputStreamBit(unsigned int option)
Tell the Log where to send output messages.
Definition: Log.cpp:259
std::string method
The source file of the message.
Definition: Log.h:213
LOG_WARNING
Definition: LogLevel.h:64
Log(const std::string &name)
Opens the log file and writes the html header information.
Definition: Log.cpp:71
LogLevel GetLogLevel() const
Gets log level.
Definition: Log.cpp:298
void SetTestMode(bool state)
Enables the use of unit test mode which enables capturing of certain data.
Definition: Log.cpp:227
Log::LogWriterContainer mWriters
Definition: Log.cpp:64
~LoggingOff()
Destructor.
Definition: Log.cpp:365
unsigned frameNumber
Time of message.
Definition: LogWriter.h:74
std::string msg
The line number of the source code of the message.
Definition: LogWriter.h:79
trUtil::DateTime time
Log level.
Definition: LogWriter.h:73
trUtil::Logging::LogLevel logLevel
Definition: LogWriter.h:70
static void SetLogTimeProvider(LogTimeProvider *ltp)
This sets a Log time source.
Definition: Log.cpp:313
const TR_UTIL_EXPORT std::string & LogLevelToString(LogLevel logLevel)
Logs level to string.
Definition: LogLevel.cpp:61
static Log & GetInstance(const std::string &name=Log::LOG_DEFAULT_NAME)
Retrieve singleton instance of the log class for a give string name.
Definition: Log.cpp:203
std::string mName
Definition: Log.cpp:62
trUtil::Logging::Log & mLog
Definition: Log.h:580
static osg::ref_ptr< LogManager > LOG_MANAGER(NULL)
LogTestData mLogTestData
Definition: Log.h:551