QGIS API Documentation 4.1.0-Master (376402f9aeb)
Loading...
Searching...
No Matches
qgseventtracing.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgseventtracing.cpp
3 --------------------------------------
4 Date : October 2019
5 Copyright : (C) 2019 by Martin Dobias
6 Email : wonder dot sk at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgseventtracing.h"
17
18#include <QCoreApplication>
19#include <QFile>
20#include <QString>
21#include <QThread>
22
23using namespace Qt::StringLiterals;
24
26
27using namespace Qt::StringLiterals;
28
29struct TraceItem
30{
31 QgsEventTracing::EventType type;
32 uint threadId;
33 qint64 timestamp;
34 QString category;
35 QString name;
36 QString id;
37};
38
40static bool sIsTracing = false;
42Q_GLOBAL_STATIC( QElapsedTimer, sTracingTimer )
44Q_GLOBAL_STATIC( QVector<TraceItem>, sTraceEvents )
46Q_GLOBAL_STATIC( QMutex, sTraceEventsMutex )
47
48
49bool QgsEventTracing::startTracing()
50{
51 if ( sIsTracing )
52 return false;
53
54 sIsTracing = true;
55 sTraceEventsMutex()->lock();
56 sTracingTimer()->start();
57 sTraceEvents()->clear();
58 sTraceEvents()->reserve( 1000 );
59 sTraceEventsMutex()->unlock();
60 return true;
61}
62
63bool QgsEventTracing::stopTracing()
64{
65 if ( !sIsTracing )
66 return false;
67
68 sIsTracing = false;
69 sTracingTimer()->invalidate();
70 return false;
71}
72
73bool QgsEventTracing::isTracingEnabled()
74{
75 return sIsTracing;
76}
77
78static char _eventTypeToChar( QgsEventTracing::EventType type )
79{
80 switch ( type )
81 {
82 case QgsEventTracing::Begin:
83 return 'B';
84 case QgsEventTracing::End:
85 return 'E';
86 case QgsEventTracing::Instant:
87 return 'i';
88 case QgsEventTracing::AsyncBegin:
89 return 'b';
90 case QgsEventTracing::AsyncEnd:
91 return 'e';
92 }
93 return '?';
94}
95
96bool QgsEventTracing::writeTrace( const QString &fileName )
97{
98 if ( sIsTracing )
99 return false;
100
101 QFile f( fileName );
102 if ( !f.open( QIODevice::WriteOnly ) )
103 return false;
104
105 f.write( "{\n\"traceEvents\": [\n" );
106
107 bool first = true;
108 for ( const auto &item : *sTraceEvents() )
109 {
110 if ( !first )
111 f.write( ",\n" );
112 else
113 first = false;
114 const char t = _eventTypeToChar( item.type );
115 QString msg = u" {\"cat\": \"%1\", \"pid\": 1, \"tid\": %2, \"ts\": %3, \"ph\": \"%4\", \"name\": \"%5\""_s.arg( item.category ).arg( item.threadId ).arg( item.timestamp ).arg( t ).arg( item.name );
116
117 // for instant events we always set them as global (currently not supporting instant events at thread scope)
118 if ( item.type == Instant )
119 msg += ", \"s\": \"g\""_L1;
120
121 // async events also need to have ID associated
122 if ( item.type == AsyncBegin || item.type == AsyncEnd )
123 msg += u", \"id\": \"%1\""_s.arg( item.id );
124
125 msg += " }";
126
127 f.write( msg.toUtf8() );
128 }
129
130 f.write( "\n]\n}\n" );
131 f.close();
132 return true;
133}
134
135void QgsEventTracing::addEvent( QgsEventTracing::EventType type, const QString &category, const QString &name, const QString &id )
136{
137 if ( !sIsTracing )
138 return;
139
140 sTraceEventsMutex()->lock();
141 TraceItem item;
142 item.type = type;
143 item.timestamp = sTracingTimer()->nsecsElapsed() / 1000;
144 if ( QThread::currentThread() == QCoreApplication::instance()->thread() )
145 item.threadId = 0; // to make it show up first
146 else
147 item.threadId = static_cast<uint>( reinterpret_cast<quint64>( QThread::currentThreadId() ) );
148 item.category = category;
149 item.name = name;
150 item.id = id;
151 sTraceEvents()->append( item );
152 sTraceEventsMutex()->unlock();
153}
154
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)