QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
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
27struct TraceItem
28{
29 QgsEventTracing::EventType type;
30 uint threadId;
31 qint64 timestamp;
32 QString category;
33 QString name;
34 QString id;
35};
36
38static bool sIsTracing = false;
40Q_GLOBAL_STATIC( QElapsedTimer, sTracingTimer )
42Q_GLOBAL_STATIC( QVector<TraceItem>, sTraceEvents )
44Q_GLOBAL_STATIC( QMutex, sTraceEventsMutex )
45
46
47bool QgsEventTracing::startTracing()
48{
49 if ( sIsTracing )
50 return false;
51
52 sIsTracing = true;
53 sTraceEventsMutex()->lock();
54 sTracingTimer()->start();
55 sTraceEvents()->clear();
56 sTraceEvents()->reserve( 1000 );
57 sTraceEventsMutex()->unlock();
58 return true;
59}
60
61bool QgsEventTracing::stopTracing()
62{
63 if ( !sIsTracing )
64 return false;
65
66 sIsTracing = false;
67 sTracingTimer()->invalidate();
68 return false;
69}
70
71bool QgsEventTracing::isTracingEnabled()
72{
73 return sIsTracing;
74}
75
76static char _eventTypeToChar( QgsEventTracing::EventType type )
77{
78 switch ( type )
79 {
80 case QgsEventTracing::Begin:
81 return 'B';
82 case QgsEventTracing::End:
83 return 'E';
84 case QgsEventTracing::Instant:
85 return 'i';
86 case QgsEventTracing::AsyncBegin:
87 return 'b';
88 case QgsEventTracing::AsyncEnd:
89 return 'e';
90 }
91 return '?';
92}
93
94bool QgsEventTracing::writeTrace( const QString &fileName )
95{
96 if ( sIsTracing )
97 return false;
98
99 QFile f( fileName );
100 if ( !f.open( QIODevice::WriteOnly ) )
101 return false;
102
103 f.write( "{\n\"traceEvents\": [\n" );
104
105 bool first = true;
106 for ( const auto &item : *sTraceEvents() )
107 {
108 if ( !first )
109 f.write( ",\n" );
110 else
111 first = false;
112 const char t = _eventTypeToChar( item.type );
113 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 );
114
115 // for instant events we always set them as global (currently not supporting instant events at thread scope)
116 if ( item.type == Instant )
117 msg += ", \"s\": \"g\""_L1;
118
119 // async events also need to have ID associated
120 if ( item.type == AsyncBegin || item.type == AsyncEnd )
121 msg += u", \"id\": \"%1\""_s.arg( item.id );
122
123 msg += " }";
124
125 f.write( msg.toUtf8() );
126 }
127
128 f.write( "\n]\n}\n" );
129 f.close();
130 return true;
131}
132
133void QgsEventTracing::addEvent( QgsEventTracing::EventType type, const QString &category, const QString &name, const QString &id )
134{
135 if ( !sIsTracing )
136 return;
137
138 sTraceEventsMutex()->lock();
139 TraceItem item;
140 item.type = type;
141 item.timestamp = sTracingTimer()->nsecsElapsed() / 1000;
142 if ( QThread::currentThread() == QCoreApplication::instance()->thread() )
143 item.threadId = 0; // to make it show up first
144 else
145 item.threadId = static_cast<uint>( reinterpret_cast<quint64>( QThread::currentThreadId() ) );
146 item.category = category;
147 item.name = name;
148 item.id = id;
149 sTraceEvents()->append( item );
150 sTraceEventsMutex()->unlock();
151}
152
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)