MNE-CPP  0.1.9
A Framework for Electrophysiology
mnetracer.cpp
Go to the documentation of this file.
1 //=============================================================================================================
35 #include "mnetracer.h"
36 
37 using namespace UTILSLIB;
38 
39 //=============================================================================================================
40 // DEFINE STATIC MEMBER VARIABLES
41 //=============================================================================================================
42 
43 static const char* defaultTracerFileName("default_MNETracer_file.json");
44 bool MNETracer::ms_bIsEnabled(false);
45 std::ofstream MNETracer::ms_OutputFileStream;
46 bool MNETracer::ms_bIsFirstEvent(true);
47 std::mutex MNETracer::ms_outFileMutex;
48 long long MNETracer::ms_iZeroTime(0);
49 
50 //=============================================================================================================
51 // DEFINE MEMBER METHODS
52 //=============================================================================================================
53 
54 MNETracer::MNETracer(const std::string &file, const std::string &function, int lineNumber)
55 : m_bIsInitialized(false)
56 , m_bPrintToTerminal(false)
57 , m_sFileName(file)
58 , m_sFunctionName(function)
59 , m_iLineNumber(lineNumber)
60 , m_iThreadId("0")
61 , m_iBeginTime(0)
62 , m_iEndTime(0)
63 , m_dDurationMilis(0.)
64 {
65  if (ms_bIsEnabled)
66  {
67  initialize();
68  writeBeginEvent();
69  }
70 }
71 
72 //=============================================================================================================
73 
75 {
76  if (ms_bIsEnabled && m_bIsInitialized)
77  {
78  registerFinalTime();
79  writeEndEvent();
80  if (m_bPrintToTerminal)
81  {
82  calculateDuration();
83  printDurationMiliSec();
84  }
85  }
86 }
87 
88 //=============================================================================================================
89 
90 void MNETracer::enable(const std::string &jsonFileName)
91 {
92  ms_OutputFileStream.open(jsonFileName);
93  writeHeader();
94  setZeroTime();
95  if (ms_OutputFileStream.is_open())
96  {
97  ms_bIsEnabled = true;
98  }
99 }
100 
101 //=============================================================================================================
102 
104 {
105  enable(defaultTracerFileName);
106 }
107 
108 //=============================================================================================================
109 
111 {
112  if (ms_bIsEnabled)
113  {
114  writeFooter();
115  ms_OutputFileStream.flush();
116  ms_OutputFileStream.close();
117  ms_bIsEnabled = false;
118  }
119 }
120 
121 //=============================================================================================================
122 
123 void MNETracer::start(const std::string &jsonFileName)
124 {
125  enable(jsonFileName);
126 }
127 
128 //=============================================================================================================
129 
131 {
132  enable();
133 }
134 
135 //=============================================================================================================
136 
138 {
139  disable();
140 }
141 
142 //=============================================================================================================
143 
144 void MNETracer::traceQuantity(const std::string &name, long val)
145 {
146  long long timeNow = getTimeNow() - ms_iZeroTime;
147  std::string s;
148  s.append("{\"name\":\"").append(name).append("\",\"ph\":\"C\",\"ts\":");
149  s.append(std::to_string(timeNow)).append(",\"pid\":1,\"tid\":1");
150  s.append(",\"args\":{\"").append(name).append("\":").append(std::to_string(val)).append("}}\n");
151  writeToFile(s);
152 }
153 
154 //=============================================================================================================
155 
156 void MNETracer::initialize()
157 {
158  registerConstructionTime();
159  registerThreadId();
160  formatFileName();
161  m_bIsInitialized = true;
162 }
163 
164 //=============================================================================================================
165 
166 void MNETracer::setZeroTime()
167 {
168  ms_iZeroTime = getTimeNow();
169 }
170 
171 //=============================================================================================================
172 
173 void MNETracer::registerConstructionTime()
174 {
175  m_iBeginTime = getTimeNow() - ms_iZeroTime;
176 }
177 
178 //=============================================================================================================
179 
180 void MNETracer::registerFinalTime()
181 {
182  m_iEndTime = getTimeNow() - ms_iZeroTime;
183 }
184 
185 //=============================================================================================================
186 
187 long long MNETracer::getTimeNow()
188 {
189  auto timeNow = std::chrono::high_resolution_clock::now();
190  return std::chrono::time_point_cast<std::chrono::microseconds>(timeNow).time_since_epoch().count();
191 }
192 
193 //=============================================================================================================
194 
195 void MNETracer::registerThreadId()
196 {
197  auto longId = std::hash<std::thread::id>{}(std::this_thread::get_id());
198  m_iThreadId = std::to_string(longId).substr(0, 5);
199 }
200 
201 //=============================================================================================================
202 
203 void MNETracer::formatFunctionName()
204 {
205  const char* pattern(" __cdecl");
206  constexpr int patternLenght(8);
207  size_t pos = m_sFunctionName.find(pattern);
208  if (pos != std::string::npos) {
209  m_sFunctionName.replace(pos, patternLenght, "");
210  }
211 }
212 
213 //=============================================================================================================
214 
215 void MNETracer::formatFileName()
216 {
217  const char* patternIn("\\");
218  const char* patternOut("\\\\");
219  constexpr int patternOutLength(4);
220  size_t start_pos = 0;
221  while ((start_pos = m_sFileName.find(patternIn, start_pos)) != std::string::npos)
222  {
223  m_sFileName.replace(start_pos, 1, patternOut);
224  start_pos += patternOutLength;
225  }
226 }
227 
228 //=============================================================================================================
229 
230 void MNETracer::calculateDuration()
231 {
232  m_dDurationMilis = (m_iEndTime - m_iBeginTime) * 0.001;
233 }
234 
235 //=============================================================================================================
236 
237 void MNETracer::printDurationMiliSec()
238 {
239  std::cout << "Scope: " << m_sFileName << " - " << m_sFunctionName << " DurationMs: " << m_dDurationMilis << "ms.\n";
240 }
241 
242 //=============================================================================================================
243 
244 void MNETracer::writeHeader()
245 {
246  writeToFile("{\"displayTimeUnit\": \"ms\",\"traceEvents\":[\n");
247 }
248 
249 //=============================================================================================================
250 
251 void MNETracer::writeFooter()
252 {
253  writeToFile("]}");
254 }
255 
256 //=============================================================================================================
257 
258 void MNETracer::writeToFile(const std::string& str)
259 {
260  ms_outFileMutex.lock();
261  if(ms_OutputFileStream.is_open()) {
262  ms_OutputFileStream << str;
263  }
264  ms_outFileMutex.unlock();
265 }
266 
267 //=============================================================================================================
268 
269 void MNETracer::writeBeginEvent()
270 {
271  std::string s;
272  if (!ms_bIsFirstEvent)
273  s.append(",");
274 
275  s.append("{\"name\":\"").append(m_sFunctionName).append("\",\"cat\":\"bst\",");
276  s.append("\"ph\":\"B\",\"ts\":").append(std::to_string(m_iBeginTime)).append(",\"pid\":1,\"tid\":");
277  s.append(m_iThreadId).append(",\"args\":{\"file path\":\"").append(m_sFileName).append("\",\"line number\":");
278  s.append(std::to_string(m_iLineNumber)).append("}}\n");
279  writeToFile(s);
280  ms_bIsFirstEvent = false;
281 }
282 
283 //=============================================================================================================
284 
285 void MNETracer::writeEndEvent()
286 {
287  std::string s;
288  s.append(",{\"name\":\"").append(m_sFunctionName).append("\",\"cat\":\"bst\",");
289  s.append("\"ph\":\"E\",\"ts\":").append(std::to_string(m_iEndTime)).append(",\"pid\":1,\"tid\":");
290  s.append(m_iThreadId).append(",\"args\":{\"file path\":\"").append(m_sFileName).append("\",\"line number\":");
291  s.append(std::to_string(m_iLineNumber)).append("}}\n");
292  writeToFile(s);
293 }
294 
295 //=============================================================================================================
296 
298 {
299  return m_bPrintToTerminal;
300 }
301 
302 //=============================================================================================================
303 
305 {
306  m_bPrintToTerminal = s;
307 }
308 
mnetracer.h
Declaration of a MNETracer object. This class allows a user to easily measure executions times of a f...
UTILSLIB::MNETracer::MNETracer
MNETracer(const std::string &file, const std::string &function, int lineNumber)
MNETracer constructor will check if the class "is enabled". If it is, it will record the creation tim...
Definition: mnetracer.cpp:54
UTILSLIB::MNETracer::start
static void start()
Convenience overload of the method enable.
Definition: mnetracer.cpp:130
UTILSLIB::MNETracer::setPrintToTerminal
void setPrintToTerminal(bool s)
Definition: mnetracer.cpp:304
UTILSLIB::MNETracer::traceQuantity
static void traceQuantity(const std::string &name, long val)
traceQuantity Allows to keep track of a specific variable in the output tracing file.
Definition: mnetracer.cpp:144
UTILSLIB::MNETracer::enable
static void enable()
Definition: mnetracer.cpp:103
UTILSLIB::MNETracer::disable
static void disable()
disable If the class "is enabled" (it's static variabable ms_bIsEnabled is true), the output file has...
Definition: mnetracer.cpp:110
UTILSLIB::MNETracer::~MNETracer
~MNETracer()
Definition: mnetracer.cpp:74
UTILSLIB::MNETracer::stop
static void stop()
Convenience overload of the method disable.
Definition: mnetracer.cpp:137
UTILSLIB::MNETracer::printToTerminalIsSet
bool printToTerminalIsSet()
Definition: mnetracer.cpp:297