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