Medical Imaging Interaction Toolkit  2018.4.99-12ad79a3
Medical Imaging Interaction Toolkit
mitkLog.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include <mitkExceptionMacro.h>
14 #include <mitkLog.h>
15 #include <mitkLogMacros.h>
16 
17 #include <itkOutputWindow.h>
18 #include <itkSimpleFastMutexLock.h>
19 
20 #include <cstdio>
21 #include <fstream>
22 #include <iostream>
23 
24 static itk::SimpleFastMutexLock logMutex;
26 static std::ofstream *logFile = nullptr;
27 static std::string logFileName = "";
28 static std::stringstream *outputWindow = nullptr;
29 static bool logOutputWindow = false;
30 
32 {
33  logOutputWindow = enable;
34 }
35 
37 {
38  logMutex.Lock();
39 #ifdef _WIN32
40  FormatSmart(l, (int)GetCurrentThreadId());
41 #else
42  FormatSmart(l);
43 #endif
44 
45  if (logFile)
46  {
47 #ifdef _WIN32
48  FormatFull(*logFile, l, (int)GetCurrentThreadId());
49 #else
50  FormatFull(*logFile, l);
51 #endif
52  }
53  if (logOutputWindow)
54  {
55  if (outputWindow == nullptr)
56  {
57  outputWindow = new std::stringstream();
58  }
59  outputWindow->str("");
60  outputWindow->clear();
61 #ifdef _WIN32
62  FormatFull(*outputWindow, l, (int)GetCurrentThreadId());
63 #else
65 #endif
66  itk::OutputWindow::GetInstance()->DisplayText(outputWindow->str().c_str());
67  }
68  logMutex.Unlock();
69 }
70 
72 {
73  if (mitkLogBackend)
74  return;
75  mitkLogBackend = new mitk::LoggingBackend();
76  mbilog::RegisterBackend(mitkLogBackend);
77 }
78 
80 {
81  if (mitkLogBackend)
82  {
83  SetLogFile(nullptr);
84  mbilog::UnregisterBackend(mitkLogBackend);
85  delete mitkLogBackend;
86  mitkLogBackend = nullptr;
87  }
88 }
89 
90 void mitk::LoggingBackend::SetLogFile(const char *file)
91 {
92  // closing old logfile
93  {
94  bool closed = false;
95  std::string closedFileName;
96 
97  logMutex.Lock();
98  if (logFile)
99  {
100  closed = true;
101  closedFileName = logFileName;
102  logFile->close();
103  delete logFile;
104  logFile = nullptr;
105  logFileName = "";
106  }
107  logMutex.Unlock();
108  if (closed)
109  {
110  MITK_INFO << "closing logfile (" << closedFileName << ")";
111  }
112  }
113 
114  // opening new logfile
115  if (file)
116  {
117  logMutex.Lock();
118 
119  logFileName = file;
120  logFile = new std::ofstream();
121 
122  logFile->open(file, std::ios_base::out | std::ios_base::app);
123 
124  if (logFile->good())
125  {
126  logMutex.Unlock();
127  MITK_INFO << "Logfile: " << logFileName;
128  }
129  else
130  {
131  delete logFile;
132  logFile = nullptr;
133  logMutex.Unlock();
134  MITK_WARN << "opening logfile '" << file << "' for writing failed";
135  }
136 
137  // mutex is now unlocked
138  }
139 }
140 
142 {
143  return logFileName;
144 }
145 
147 {
148  int r;
149 
150  for (r = 1; r < argc; r++)
151  {
152  if (std::string(argv[r]) == "--logfile")
153  {
154  if (r + 1 >= argc)
155  {
156  --argc;
157  MITK_ERROR << "--logfile parameter found, but no file given";
158  return;
159  }
160 
162 
163  for (r += 2; r < argc; r++)
164  argv[r - 2] = argv[r];
165 
166  argc -= 2;
167  return;
168  }
169  }
170 }
171 
172 void mitk::LoggingBackend::RotateLogFiles(const std::string &prefixPath)
173 {
174  static const int numLogFiles = 10;
175  std::string newEmptyLogFileName;
176 
177  // first: rotate the old log files to get a new, free logfile name
178  newEmptyLogFileName = IncrementLogFileNames(prefixPath, numLogFiles);
179 
180  // now: use the new empty logfile name as name for this run
181  mitk::LoggingBackend::SetLogFile(newEmptyLogFileName.c_str());
182 }
183 
184 std::string mitk::LoggingBackend::IncrementLogFileNames(const std::string &prefixPath, int numLogFiles)
185 {
186  // delete last one
187  {
188  std::stringstream s;
189  s << prefixPath.c_str() << "-" << numLogFiles - 1 << ".log";
190  // check if the file exists
191  if (CheckIfFileExists(s.str())) // if yes: delete it
192  {
193  int retVal = ::remove(s.str().c_str());
194  if (retVal != 0)
195  {
196  mitkThrow()
197  << "Problem while deleting the oldest log file. Maybe the access to this files is blocked. Aborting!";
198  }
199  }
200  }
201 
202  // rename the others
203  for (int r = numLogFiles - 1; r >= 1; r--)
204  {
205  std::stringstream dst;
206  dst << prefixPath.c_str() << "-" << r << ".log";
207 
208  std::stringstream src;
209  src << prefixPath.c_str() << "-" << r - 1 << ".log";
210 
211  // check if the source exists
212  if (CheckIfFileExists(src.str())) // if yes: rename it
213  {
214  int retVal = ::rename(src.str().c_str(), dst.str().c_str());
215  if (retVal != 0)
216  {
217  mitkThrow() << "Problem while renaming the log files. Maybe the access to this files is blocked. Aborting!";
218  }
219  }
220  }
221 
222  // create new empty name and return it
223  {
224  std::stringstream s;
225  s << prefixPath.c_str() << "-0.log";
226  return s.str();
227  }
228 }
229 
230 bool mitk::LoggingBackend::CheckIfFileExists(const std::string &filename)
231 {
232  bool returnValue = false;
233  std::ifstream File(filename.c_str());
234  if (File.good())
235  {
236  returnValue = true;
237  }
238  else
239  {
240  returnValue = false;
241  }
242  File.close();
243  return returnValue;
244 }
245 
246 mbilog::OutputType mitk::LoggingBackend::GetOutputType() const
247 {
248  return mbilog::Console;
249 }
static mitk::LoggingBackend * mitkLogBackend
Definition: mitkLog.cpp:25
void MBILOG_EXPORT UnregisterBackend(BackendBase *backend)
Unregisters a backend.
Definition: mbilog.cpp:31
static void Register()
registers MITK logging backend at mbilog
Definition: mitkLog.cpp:71
#define MITK_INFO
Definition: mitkLogMacros.h:18
static bool logOutputWindow
Definition: mitkLog.cpp:29
#define MITK_ERROR
Definition: mitkLogMacros.h:20
void ProcessMessage(const mbilog::LogMessage &) override
overloaded method for receiving log message from mbilog
Definition: mitkLog.cpp:36
mbilog::OutputType GetOutputType() const override
Definition: mitkLog.cpp:246
static itk::SimpleFastMutexLock logMutex
Definition: mitkLog.cpp:24
static void RotateLogFiles(const std::string &prefixPath)
Activates and handles a rolling log file with the given prefix and path. This method handles 10 log f...
Definition: mitkLog.cpp:172
static std::stringstream * outputWindow
Definition: mitkLog.cpp:28
static bool CheckIfFileExists(const std::string &filename)
Definition: mitkLog.cpp:230
An object of this class represents a single logging message (logging event) of the mbi logging mechan...
#define MITK_WARN
Definition: mitkLogMacros.h:19
#define mitkThrow()
void MBILOG_EXPORT RegisterBackend(BackendBase *backend)
Registeres a backend to the mbi logging mechanism. If a backend is registered here, all mbilog messages are relayed to this backend through the method ProcessMessage. If no backend is registered the default backend is used.
Definition: mbilog.cpp:26
mbilog backend implementation for mitk
Definition: mitkLog.h:24
static std::ofstream * logFile
Definition: mitkLog.cpp:26
static std::string IncrementLogFileNames(const std::string &prefixPath, int numLogFiles=10)
Increments the names of logfiles with the given prefixPath. This means, if the prefixPath is "myLogFi...
Definition: mitkLog.cpp:184
static void EnableAdditionalConsoleWindow(bool enable)
Enables an additional logging output window by means of itk::outputwindow This might be relevant for ...
Definition: mitkLog.cpp:31
static void SetLogFile(const char *file)
Sets extra log file path (additionally to the console log)
Definition: mitkLog.cpp:90
static void CatchLogFileCommandLineParameter(int &argc, char **argv)
Automatically extracts and removes the "--logfile <file>" parameters from the standard C main(argc...
Definition: mitkLog.cpp:146
static std::string GetLogFile()
Definition: mitkLog.cpp:141
static void Unregister()
Unregisters MITK logging backend at mbilog.
Definition: mitkLog.cpp:79
static std::string logFileName
Definition: mitkLog.cpp:27
void FormatFull(const LogMessage &l, int threadID=0)
Method formats the given LogMessage in the full/long format and writes it to std::cout.
void FormatSmart(const LogMessage &l, int threadID=0)
Method formats the given LogMessage in the smart/short format and writes it to std::cout.