LibreOffice Module comphelper (master)  1
traceevent.hxx
Go to the documentation of this file.
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9 
10 #ifndef INCLUDED_COMPHELPER_TRACEEVENT_HXX
11 #define INCLUDED_COMPHELPER_TRACEEVENT_HXX
12 
13 #include <sal/config.h>
14 
15 #include <algorithm>
16 #include <atomic>
17 #include <map>
18 #include <memory>
19 #include <vector>
20 
21 #include <osl/process.h>
22 #include <osl/thread.h>
23 #include <osl/time.h>
24 #include <com/sun/star/uno/Sequence.h>
26 #include <rtl/ustrbuf.hxx>
27 #include <rtl/ustring.hxx>
28 
29 // implementation of XToolkitExperimental profiling API
30 
31 namespace comphelper
32 {
34 {
35 private:
36  static int getPid()
37  {
38  oslProcessInfo aProcessInfo;
39  aProcessInfo.Size = sizeof(oslProcessInfo);
40  if (osl_getProcessInfo(nullptr, osl_Process_IDENTIFIER, &aProcessInfo)
41  == osl_Process_E_None)
42  return aProcessInfo.Ident;
43  return -1;
44  }
45 
46  static std::size_t s_nBufferSize;
47  static void (*s_pBufferFullCallback)();
48 
49 protected:
50  static std::atomic<bool> s_bRecording; // true during recording
51 
52  static void addRecording(const OUString& sObject);
53 
54  static long long getNow()
55  {
56  TimeValue systemTime;
57  osl_getSystemTime(&systemTime);
58  return static_cast<long long>(systemTime.Seconds) * 1000000 + systemTime.Nanosec / 1000;
59  }
60 
61  static OUString createArgsString(const std::map<OUString, OUString>& args)
62  {
63  if (args.size() == 0)
64  return "";
65 
66  OUStringBuffer sResult;
67  sResult.append(",\"args\":{");
68  bool first = true;
69  for (auto& i : args)
70  {
71  if (!first)
72  sResult.append(',');
73  sResult.append('"');
74  sResult.append(i.first);
75  sResult.append("\":\"");
76  sResult.append(i.second);
77  sResult.append('"');
78  first = false;
79  }
80  sResult.append('}');
81 
82  return sResult.makeStringAndClear();
83  }
84 
85  const int m_nPid;
86  const OUString m_sArgs;
87 
88  TraceEvent(const OUString& sArgs)
89  : m_nPid(s_bRecording ? getPid() : 1)
90  , m_sArgs(sArgs)
91  {
92  }
93 
94  TraceEvent(const std::map<OUString, OUString>& aArgs)
95  : TraceEvent(createArgsString(aArgs))
96  {
97  }
98 
99 public:
100  static void addInstantEvent(const char* sName, const std::map<OUString, OUString>& args
101  = std::map<OUString, OUString>());
102 
103  static void startRecording();
104  static void stopRecording();
105  static void setBufferSizeAndCallback(std::size_t bufferSize, void (*bufferFullCallback)());
106 
107  static std::vector<OUString> getEventVectorAndClear();
108 
109  static css::uno::Sequence<OUString> getRecordingAndClear();
110 };
111 
113 {
114 protected:
115  const char* m_sName;
116 
117  NamedEvent(const char* sName, const OUString& sArgs)
118  : TraceEvent(sArgs)
119  , m_sName(sName ? sName : "(null)")
120  {
121  }
122 
123  NamedEvent(const char* sName, const std::map<OUString, OUString>& aArgs)
124  : TraceEvent(aArgs)
125  , m_sName(sName ? sName : "(null)")
126  {
127  }
128 };
129 
130 // An AsyncEvent generates an 'S' (start) event when constructed and a 'F' (finish) event when it
131 // is destructed.
132 
133 // The Trace Event specification claims that these event types are deprecated and replaces by
134 // nestable 'b' (begin) and 'e' (end) events, but Chrome does not seem to support those.
135 
136 // To generate a pair of 'S' and 'F' events, create an AsyncEvent object using the AsyncEvent(const
137 // char* sName) constructor when you want the 'S' event to be generated, and destroy it when you
138 // want the corresponding 'F' event to be generated.
139 
141  public std::enable_shared_from_this<AsyncEvent>
142 {
143  static int s_nIdCounter;
144  int m_nId;
146 
147  AsyncEvent(const char* sName, int nId, const std::map<OUString, OUString>& args)
148  : NamedEvent(sName, args)
149  , m_nId(nId)
150  , m_bBeginRecorded(false)
151  {
152  if (s_bRecording)
153  {
154  long long nNow = getNow();
155 
156  // Generate a "Start" (type S) event
158  "\"name\":\""
159  + OUString(m_sName, strlen(m_sName), RTL_TEXTENCODING_UTF8)
160  + "\","
161  "\"ph\":\"S\""
162  ","
163  "\"id\":"
164  + OUString::number(m_nId) + m_sArgs
165  + ","
166  "\"ts\":"
167  + OUString::number(nNow)
168  + ","
169  "\"pid\":"
170  + OUString::number(m_nPid)
171  + ","
172  "\"tid\":"
173  + OUString::number(osl_getThreadIdentifier(nullptr)) + "},");
174  m_bBeginRecorded = true;
175  }
176  }
177 
178  void generateEnd()
179  {
180  if (m_bBeginRecorded)
181  {
182  m_bBeginRecorded = false;
183 
184  long long nNow = getNow();
185  // Generate a "Finish" (type F) event
187  "\"name\":\""
188  + OUString(m_sName, strlen(m_sName), RTL_TEXTENCODING_UTF8)
189  + "\","
190  "\"ph\":\"F\""
191  ","
192  "\"id\":"
193  + OUString::number(m_nId) + m_sArgs
194  + ","
195  "\"ts\":"
196  + OUString::number(nNow)
197  + ","
198  "\"pid\":"
199  + OUString::number(m_nPid)
200  + ","
201  "\"tid\":"
202  + OUString::number(osl_getThreadIdentifier(nullptr)) + "},");
203  }
204  }
205 
206 public:
207  AsyncEvent(const char* sName,
208  const std::map<OUString, OUString>& args = std::map<OUString, OUString>())
209  : AsyncEvent(sName, s_nIdCounter++, args)
210  {
211  }
212 
213  ~AsyncEvent() { generateEnd(); }
214 
215  void finish() { generateEnd(); }
216 };
217 
218 } // namespace comphelper
219 
220 #endif // INCLUDED_COMPHELPER_TRACEEVENT_HXX
221 
222 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
TraceEvent(const std::map< OUString, OUString > &aArgs)
Definition: traceevent.hxx:94
static std::atomic< bool > s_bRecording
Definition: traceevent.hxx:50
tuple args
AsyncEvent(const char *sName, const std::map< OUString, OUString > &args=std::map< OUString, OUString >())
Definition: traceevent.hxx:207
OUString m_sName
const OUString m_sArgs
Definition: traceevent.hxx:86
static long long getNow()
Definition: traceevent.hxx:54
int i
static OUString createArgsString(const std::map< OUString, OUString > &args)
Definition: traceevent.hxx:61
AsyncEvent(const char *sName, int nId, const std::map< OUString, OUString > &args)
Definition: traceevent.hxx:147
NamedEvent(const char *sName, const std::map< OUString, OUString > &aArgs)
Definition: traceevent.hxx:123
TraceEvent(const OUString &sArgs)
Definition: traceevent.hxx:88
static std::size_t s_nBufferSize
Definition: traceevent.hxx:46
static void addRecording(const OUString &sObject)
Definition: traceevent.cxx:41
#define COMPHELPER_DLLPUBLIC
NamedEvent(const char *sName, const OUString &sArgs)
Definition: traceevent.hxx:117
constexpr OUStringLiteral first
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo