[Development] Tracing Qt

Blasche Alexander Alexander.Blasche at digia.com
Fri Aug 23 13:59:45 CEST 2013


Hi Robin,

I am not sure whether you are aware of http://qt.gitorious.org/qtplayground/qlogger

It is pretty much what you describe. It was even close to a merge into qtcore already (only rejected due to feature freeze). It gives you a complete API including ways to integrate with qDebug/qWarning, runtime activation, little to no overhead when deactivated and there was reasonably broad agreement already. Also see:

http://lists.qt-project.org/pipermail/development/2012-December/008886.html

If you have spare cycles to actually make this happen I would propose you start with a 95% done system rather than new.

--
Alex

________________________________________
From: development-bounces+alexander.blasche=digia.com at qt-project.org [development-bounces+alexander.blasche=digia.com at qt-project.org] on behalf of Robin Burchell [robin+qt at viroteck.net]
Sent: Friday, August 23, 2013 13:20
To: development at qt-project.org
Cc: Poenitz Andre
Subject: [Development] Tracing Qt

Hi,

(apologies in advance for the wall of text)

It's inevitable when working with Qt that sooner or later, you
probably have a desire to work on tracing Qt - or at least part of it.
Qt Creator's QML profiler is one such very prominent example of an
area where this may be useful, but there are many others: usually
sprinkled around Qt hidden behind various defines, environment
variables, and other hard-to-find places. This makes digging into a
problem somewhat hard, unless you are (or can be handheld by) a Qt
expert when you start digging.

It's also a bit of a problem in that each of these methods uses
different ways to communicate information, meaning it is difficult to
write tooling to inspect this data and visualise it. We also miss out
on tracing in a number of areas that *could* potentially be valuable,
such as touch event processing, the event loop, the sky's the limit.

Thanks to Carsten and Andre for their input in hashing the details of
this proposal out.

Proposal
========

Let's look at unifying tracing inside Qt. Let's add code to Qt itself
to enable easy introspection of what exactly is going on.

When looking at tracing, it can be boiled down into two levels - an
area (which may be a feature being inspected, or a subsystem - for
instance, QML performance, vsync timestamps, ...) containing events,
so from this, we can gather that we need a way to categorise logging
by area, and the capability to switch logging on by area.

An area should be associated with a simple numeric identifier to avoid
expensive code when manipulating events, but there will be some form
of name => id mapping (for the environment variable below, for
instance).

Suggested area-based API:
enum TraceArea {
    TraceAreaDrawing (drawing event, frame event)
    ... other areas as required
    TraceAreaUser = 1000 // held for possible future expansion into
allowing dynamic area registration
}

QT_ENABLE_TRACE=inputevents,frameevents,magicalmonkeyevents
rationale: providing system-wide defaults enables tracing of
system-wide behaviour is very useful. Being able to inspect exactly
what an entire set of Qt-based applications are doing while a user is
interacting with it would be a useful thing.

enable_trace(TraceArea area)
disable_trace(TraceArea area)
rationale: a developer may want to turn tracing of an individual area
on/off at runtime, as they start something they are particularly
interested in tracing. This has some inspiration in
CALLGRIND_START_INSTRUMENTATION/CALLGRIND_STOP_INSTRUMENTATION also.

Along with this user-facing API, we also need some mechanism to enable
different applications of the tracing data (for instance, the QML
profiler from Creator, Android's systrace
https://developer.android.com/tools/help/systrace.html, plain console
logging, etc). Multiple tracers should be able to handle a single
area. Tracers would live in seperate plugins.

Example tracer API:
class QTracer { virtual void logStart() = 0; virtual void logEnd() = 0; }

QTracer subclasses would register their interest in a particular event
type on construction:

struct MyCoolConsoleTracer : public QTracer {
    MyCoolConsoleTracer() : QTracer() {
        q_register_tracer_for_area(this, TraceAreaDrawing); // we are
interested in this particular event type
    }

    virtual void logStart() {
        qDebug() << "Trace event for drawing, start: " <<
QDateTime::currentMSecsSinceEpoch()
    }
    virtual void logEnd() {
        qDebug() << "Trace event for drawing, end: " <<
QDateTime::currentMSecsSinceEpoch()
    }
};

The invocation of tracer subclasses is controlled by a simple RAII class:

struct QTraceEvent {
    QTraceEvent(TraceArea area); // invokes logStart on all interested tracers
    ~QTraceEvent(); // invokes logEnd on all interested tracers
}

Example use being something like:

void draw() {
    QTraceEvent e(TraceAreaDrawing);
    // do painting
    paintOnScreen();
}

Thoughts, flames, cookies?

BR,
Robin
(with jolla hat on)
_______________________________________________
Development mailing list
Development at qt-project.org
http://lists.qt-project.org/mailman/listinfo/development



More information about the Development mailing list