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