2016-12-05 21:12:24 +00:00
|
|
|
|
# Tracing
|
|
|
|
|
|
|
|
|
|
This subsystem will provide a mechanism to get structured tracing info
|
|
|
|
|
from GStreamer applications. This can be used for post-run analysis as
|
|
|
|
|
well as for live introspection.
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
## Use cases
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
- I’d like to get statistics from a running application.
|
|
|
|
|
|
|
|
|
|
- I’d like to to understand which parts of my pipeline use how many
|
|
|
|
|
resources.
|
|
|
|
|
|
|
|
|
|
- I’d like to know which parts of the pipeline use how much memory.
|
|
|
|
|
|
|
|
|
|
- I’d like to know about ref-counts of parts in the pipeline to find
|
|
|
|
|
ref-count issues.
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
## Non use-cases
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
- Some element in the pipeline does not play along the rules, find out
|
|
|
|
|
which one. This could be done with generic tests.
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
## Design
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
The system brings the following new items: core hooks: probes in the
|
|
|
|
|
core api, that will expose internal state when tracing is in use
|
|
|
|
|
tracers: plugin features that can process data from the hooks and emit a
|
|
|
|
|
log tracing front-ends: applications that consume logs from tracers
|
|
|
|
|
|
|
|
|
|
Like the logging, the tracer hooks can be compiled out and if not use a
|
|
|
|
|
local condition to check if active.
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
Certain GStreamer core function (such as `gst_pad_push()` or
|
|
|
|
|
`gst_element_add_pad()`) will call into the tracer subsystem to dispatch
|
2016-12-05 21:12:24 +00:00
|
|
|
|
into active tracing modules. Developers will be able to select a list of
|
|
|
|
|
plugins by setting an environment variable, such as
|
2016-12-30 09:12:41 +00:00
|
|
|
|
`GST_TRACERS="meminfo;dbus"`. One can also pass parameters to plugins:
|
|
|
|
|
`GST_TRACERS="log(events,buffers);stats(all)"`. When then plugins are
|
2016-12-05 21:12:24 +00:00
|
|
|
|
loaded, we’ll add them to certain hooks according to which they are
|
|
|
|
|
interested in.
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
Right now tracing info is logged as `GstStructures` to the TRACE level.
|
|
|
|
|
Idea: Another env var `GST_TRACE_CHANNEL` could be used to send the
|
2016-12-05 21:12:24 +00:00
|
|
|
|
tracing to a file or a socket. See
|
|
|
|
|
<https://bugzilla.gnome.org/show_bug.cgi?id=733188> for discussion on
|
|
|
|
|
these environment variables.
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
## Hook api
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
We’ll wrap interesting api calls with two macros, e.g. `gst_pad_push()`:
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
``` c
|
2016-12-05 21:12:24 +00:00
|
|
|
|
GstFlowReturn gst_pad_push (GstPad * pad, GstBuffer * buffer) {
|
2016-12-30 09:12:41 +00:00
|
|
|
|
GstFlowReturn res;
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
|
|
|
|
|
g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
|
|
|
|
|
g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
|
|
|
|
|
|
|
|
|
|
GST_TRACER_PAD_PUSH_PRE (pad, buffer);
|
|
|
|
|
res = gst_pad_push_data (pad,
|
|
|
|
|
GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH, buffer);
|
|
|
|
|
GST_TRACER_PAD_PUSH_POST (pad, res);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
TODO(ensonic): gcc has some magic for wrapping functions -
|
|
|
|
|
<http://gcc.gnu.org/onlinedocs/gcc/Constructing-Calls.html> -
|
|
|
|
|
<http://www.clifford.at/cfun/gccfeat/#gccfeat05.c>
|
|
|
|
|
|
|
|
|
|
TODO(ensonic): we should eval if we can use something like jump_label
|
|
|
|
|
in the kernel - <http://lwn.net/Articles/412072/> +
|
|
|
|
|
<http://lwn.net/Articles/435215/> -
|
|
|
|
|
<http://lxr.free-electrons.com/source/kernel/jump_label.c> -
|
|
|
|
|
<http://lxr.free-electrons.com/source/include/linux/jump_label.h> -
|
|
|
|
|
<http://lxr.free-electrons.com/source/arch/x86/kernel/jump_label.c>
|
|
|
|
|
TODO(ensonic): liblttng-ust provides such a mechanism for user-space -
|
|
|
|
|
but this is mostly about logging traces - it is linux specific :/
|
|
|
|
|
|
|
|
|
|
In addition to api hooks we should also provide timer hooks. Interval
|
|
|
|
|
timers are useful to get e.g. resource usage snapshots. Also absolute
|
|
|
|
|
timers might make sense. All this could be implemented with a clock
|
2016-12-30 09:12:41 +00:00
|
|
|
|
thread. We can use another env-var `GST_TRACE_TIMERS="100ms,75ms"` to
|
2016-12-05 21:12:24 +00:00
|
|
|
|
configure timers and then pass them to the tracers like,
|
2016-12-30 09:12:41 +00:00
|
|
|
|
`GST_TRACERS="rusage(timer=100ms);meminfo(timer=75ms)"`. Maybe we can
|
|
|
|
|
create them ad-hoc and avoid the `GST_TRACE_TIMERS` var.
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
Hooks (\* already implemented)
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
```
|
2016-12-05 21:12:24 +00:00
|
|
|
|
* gst_bin_add
|
|
|
|
|
* gst_bin_remove
|
|
|
|
|
* gst_element_add_pad
|
|
|
|
|
* gst_element_post_message
|
|
|
|
|
* gst_element_query
|
|
|
|
|
* gst_element_remove_pad
|
|
|
|
|
* gst_element_factory_make
|
|
|
|
|
* gst_pad_link
|
|
|
|
|
* gst_pad_pull_range
|
|
|
|
|
* gst_pad_push
|
|
|
|
|
* gst_pad_push_list
|
|
|
|
|
* gst_pad_push_event
|
|
|
|
|
* gst_pad_unlink
|
2016-12-30 09:12:41 +00:00
|
|
|
|
```
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
## Tracer api
|
|
|
|
|
|
|
|
|
|
Tracers are plugin features. They have a simple api:
|
|
|
|
|
|
|
|
|
|
class init Here the tracers describe the data the will emit.
|
|
|
|
|
|
|
|
|
|
instance init Tracers attach handlers to one or more hooks using
|
2016-12-30 09:12:41 +00:00
|
|
|
|
`gst_tracing_register_hook()`. In case the are configurable, they can
|
2016-12-05 21:12:24 +00:00
|
|
|
|
read the options from the *params* property. This is the extra detail
|
|
|
|
|
from the environment var.
|
|
|
|
|
|
|
|
|
|
hook functions Hooks marshal the parameters given to a trace hook into
|
|
|
|
|
varargs and also add some extra into such as a timestamp. Hooks will be
|
|
|
|
|
called from misc threads. The trace plugins should only consume (=read)
|
|
|
|
|
the provided data. Expensive computation should be avoided to not affect
|
|
|
|
|
the execution too much. Most trace plugins will log data to a trace
|
|
|
|
|
channel.
|
|
|
|
|
|
|
|
|
|
instance destruction Tracers can output results and release data. This
|
2016-12-30 09:12:41 +00:00
|
|
|
|
would ideally be done at the end of the applications, but `gst_deinit()`
|
|
|
|
|
is not mandatory. `gst_tracelib` was using a `gcc_destructor`. Ideally
|
2016-12-05 21:12:24 +00:00
|
|
|
|
tracer modules log data as they have them and leave aggregation to a
|
|
|
|
|
tool that processes the log.
|
|
|
|
|
|
|
|
|
|
## tracer event classes
|
|
|
|
|
|
|
|
|
|
Most tracers will log some kind of *events* : a data transfer, an event,
|
2016-12-13 12:22:23 +00:00
|
|
|
|
a message, a query or a measurement. Every tracer should describe the
|
2016-12-05 21:12:24 +00:00
|
|
|
|
data format. This way tools that process tracer logs can show the data
|
|
|
|
|
in a meaningful way without having to know about the tracer plugin.
|
|
|
|
|
|
2017-07-08 10:07:16 +00:00
|
|
|
|
Tracers can use `gst_tracer_record_new` in their `tracer_class_init()`
|
|
|
|
|
to describe their format:
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
2017-07-08 10:07:16 +00:00
|
|
|
|
``` c
|
|
|
|
|
fmt = gst_tracer_record_new ("thread-rusage.class",
|
2016-12-05 21:12:24 +00:00
|
|
|
|
// value in the log record (order does not matter)
|
|
|
|
|
// *thread-id* is a *key* to related the record to something as indicated
|
2017-07-08 10:07:16 +00:00
|
|
|
|
// by *scope* substructure
|
|
|
|
|
"thread-id", GST_TYPE_STRUCTURE, gst_structure_new ("scope",
|
|
|
|
|
"type", G_TYPE_GTYPE, G_TYPE_GUINT64,
|
|
|
|
|
"related-to", GST_TYPE_TRACER_VALUE_SCOPE, GST_TRACER_VALUE_SCOPE_THREAD,
|
2016-12-05 21:12:24 +00:00
|
|
|
|
NULL),
|
2017-07-08 10:07:16 +00:00
|
|
|
|
// next value in the record
|
|
|
|
|
// *average-cpuload* is a measurement as indicated by the *value*
|
|
|
|
|
// substructure
|
|
|
|
|
"average-cpuload", GST_TYPE_STRUCTURE, gst_structure_new ("value",
|
|
|
|
|
// value type
|
2016-12-05 21:12:24 +00:00
|
|
|
|
"type", G_TYPE_GTYPE, G_TYPE_UINT,
|
|
|
|
|
// human readable description, that can be used as a graph label
|
|
|
|
|
"description", G_TYPE_STRING, "average cpu usage per thread",
|
|
|
|
|
// flags that help to use the right graph type
|
|
|
|
|
// flags { aggregated, windowed, cumulative, … }
|
|
|
|
|
"flags", GST_TYPE_TRACER_VALUE_FLAGS, GST_TRACER_VALUE_FLAGS_AGGREGATED,
|
|
|
|
|
// value range
|
2017-07-08 10:07:16 +00:00
|
|
|
|
"min", G_TYPE_UINT, 0,
|
|
|
|
|
"max", G_TYPE_UINT, 100,
|
|
|
|
|
NULL),
|
|
|
|
|
…
|
|
|
|
|
NULL);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Later tracers can use the `GstTracerRecord` instance to log values efficiently:
|
|
|
|
|
|
|
|
|
|
``` c
|
|
|
|
|
gst_tracer_record_log (fmt, (guint64) (guintptr) thread_id, avg_cpuload);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Below a few more example for parts of tracer classes:
|
|
|
|
|
|
|
|
|
|
An optional value. Since the PTS can be GST_CLOCK_TIME_NONE and that is (-1),
|
|
|
|
|
we don't want to log this.
|
|
|
|
|
``` c
|
|
|
|
|
"buffer-pts", GST_TYPE_STRUCTURE, gst_structure_new ("value",
|
|
|
|
|
"type", G_TYPE_GTYPE, G_TYPE_UINT64,
|
|
|
|
|
"description", G_TYPE_STRING, "presentation timestamp of the buffer in ns",
|
|
|
|
|
"flags", GST_TYPE_TRACER_VALUE_FLAGS, GST_TRACER_VALUE_FLAGS_OPTIONAL,
|
|
|
|
|
"min", G_TYPE_UINT64, G_GUINT64_CONSTANT (0),
|
|
|
|
|
"max", G_TYPE_UINT64, G_MAXUINT64,
|
|
|
|
|
NULL),
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
In the tracer code an optional value is logged using a boolean + the value,
|
|
|
|
|
where the boolean indicated the presence:
|
|
|
|
|
|
|
|
|
|
``` c
|
|
|
|
|
GstClockTime pts = GST_BUFFER_PTS (buf);
|
|
|
|
|
|
|
|
|
|
gst_tracer_record_log (fmt, ..., GST_CLOCK_TIME_IS_VALID (pts), pts, ...);
|
|
|
|
|
|
2016-12-05 21:12:24 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
2016-12-13 12:22:23 +00:00
|
|
|
|
A few ideas that are not yet in the above spec:
|
|
|
|
|
|
|
|
|
|
- it would be nice to describe the unit of values
|
|
|
|
|
- putting it into the description is not flexible though, e.g. time
|
|
|
|
|
would be a guint64 but a ui would reformat it to e.g. h:m:s.ms
|
|
|
|
|
- other units are e.g.: percent, per-mille, or kbit/s
|
|
|
|
|
- we’d like to have some metadata on scopes
|
|
|
|
|
- e.g. we’d like to log the thread-names, so that a UI can show
|
|
|
|
|
that instead of thread-ids
|
2017-07-08 10:07:16 +00:00
|
|
|
|
- ordering: e.g. in the latency tracer we'd like to order by 'sink'
|
|
|
|
|
and then by 'src'
|
|
|
|
|
|
|
|
|
|
- unique instance ids
|
2016-12-13 12:22:23 +00:00
|
|
|
|
- the stats tracer logs *new-element* and *new-pad* messages
|
2017-07-08 10:07:16 +00:00
|
|
|
|
- they add a unique *ix* to each instance as the memory ptr or the object
|
|
|
|
|
name can be reused for new instances, the data is attached to the
|
|
|
|
|
objects as qdata
|
2016-12-13 12:22:23 +00:00
|
|
|
|
- the latency tracer would like to also reference this metadata
|
2017-07-08 10:07:16 +00:00
|
|
|
|
(right now, it relies on unique element names)
|
|
|
|
|
- the relationship between a scope 'element-ix' ('related-to'=_ELEMENT)
|
|
|
|
|
and an earlier message 'new-element' that has scope 'ix'
|
|
|
|
|
('related-to'=_ELEMENT) and value 'name' is not obvious
|
2016-12-13 12:22:23 +00:00
|
|
|
|
|
|
|
|
|
Right now we log the classes as structures, this is important so that the log
|
|
|
|
|
is self contained. It would be nice to add them to the registry, so that
|
|
|
|
|
gst-inspect can show them. We could also consider to add each value as a
|
|
|
|
|
READONLY gobject property. The property has name/description. We could use
|
|
|
|
|
qdata for scope and flags (or have some new property flags). We would also
|
|
|
|
|
need a new "notify" signal, so that value-change notifications would include a
|
2016-12-05 21:12:24 +00:00
|
|
|
|
time-stamp. This way the tracers would not needs to be aware of the
|
|
|
|
|
logging. The core tracer would register the notify handlers and emit the
|
2016-12-30 09:12:41 +00:00
|
|
|
|
log. Or we just add a `gst_tracer_class_install_event()` and that
|
|
|
|
|
mimics the `g_object_class_install_property()`.
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
2016-12-13 12:22:23 +00:00
|
|
|
|
Frontends can:
|
|
|
|
|
- do an events over time histogram
|
|
|
|
|
- plot curves of values over time or deltas
|
|
|
|
|
- show gauges
|
|
|
|
|
- collect statistics (min, max, avg, …)
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
## latency
|
|
|
|
|
|
2019-03-21 10:25:38 +00:00
|
|
|
|
- register to buffer, event and query flow
|
2016-12-13 12:22:23 +00:00
|
|
|
|
- send custom event on buffer flow at source elements
|
2019-03-21 10:25:38 +00:00
|
|
|
|
- catch events on event transfer at sink pads
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
## meminfo (not yet implemented)
|
|
|
|
|
|
2016-12-13 12:22:23 +00:00
|
|
|
|
- register to an interval-timer hook.
|
2016-12-30 09:12:41 +00:00
|
|
|
|
- call `mallinfo()` and log memory usage rusage
|
2016-12-13 12:22:23 +00:00
|
|
|
|
- register to an interval-timer hook.
|
2016-12-30 09:12:41 +00:00
|
|
|
|
- call `getrusage()` and log resource usage
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
## dbus (not yet implemented)
|
|
|
|
|
|
2016-12-13 12:22:23 +00:00
|
|
|
|
- provide a dbus iface to announce applications that are traced
|
|
|
|
|
- tracing UIs can use the dbus iface to find the channels where logging and
|
|
|
|
|
tracing is getting logged to
|
|
|
|
|
- one would start the tracing UI first and when the application is started with
|
|
|
|
|
tracing activated, the dbus plugin will announce the new application,
|
|
|
|
|
upon which the tracing UI can start reading from the log channels, this avoid
|
|
|
|
|
missing some data
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
## topology (not yet implemented)
|
|
|
|
|
|
2016-12-13 12:22:23 +00:00
|
|
|
|
- register to pipeline topology hooks
|
|
|
|
|
- tracing UIs can show a live pipeline graph
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
## stats
|
|
|
|
|
|
2016-12-13 12:22:23 +00:00
|
|
|
|
- register to buffer, event, message and query flow
|
|
|
|
|
- tracing apps can do e.g. statistics
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
## refcounts (not yet implemented)
|
|
|
|
|
|
2016-12-13 12:22:23 +00:00
|
|
|
|
- log ref-counts of objects
|
|
|
|
|
- just logging them outside of glib/gobject would still make it hard to detect
|
|
|
|
|
issues though
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
## opengl (not yet implemented)
|
|
|
|
|
|
2016-12-13 12:22:23 +00:00
|
|
|
|
- upload/download times
|
|
|
|
|
- there is not hardware agnostic way to get e.g. memory usage info (gl
|
|
|
|
|
extensions)
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
## memory (not yet implemented)
|
|
|
|
|
|
2016-12-13 12:22:23 +00:00
|
|
|
|
- trace live instance (and pointer to the memory)
|
|
|
|
|
- use an atexit handler to dump leaked instance
|
|
|
|
|
https://bugzilla.gnome.org/show_bug.cgi?id=756760#c6
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
## leaks
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
- track creation/destruction of `GstObject` and `GstMiniObject`
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
2016-12-13 12:22:23 +00:00
|
|
|
|
- log those which are still alive when app is exiting and raise an
|
|
|
|
|
error if any
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
- The tracer takes several parameters in a `GstStructure` like syntax (without the structure name):
|
2016-12-20 18:37:38 +00:00
|
|
|
|
- check-refs (boolean): Whether to also track object ref and unref operations
|
2016-12-30 09:12:41 +00:00
|
|
|
|
example: `GST_TRACERS=leaks(check-refs=true)` COMMAND
|
2016-12-20 18:37:38 +00:00
|
|
|
|
- stack-traces-flags: Flags to use when generating stack trace (does not generate stack trace
|
|
|
|
|
if not set), valid values are “full” to retrieve as much information as possible in the
|
|
|
|
|
backtrace, or “none” for a simple backtrace (usually does not contain line number or source files).
|
|
|
|
|
This may significantly increase memory consumption. (You can also set the `GST_LEAKS_TRACER_STACK_TRACE`
|
|
|
|
|
environment variable for that).
|
|
|
|
|
- filters: (string): A comma separated list of object types to trace (make sure to enclose in
|
|
|
|
|
quotation marks)
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
**Run the leaks tracer on all `GstProxyPad` objects logging the references with a full backtraces**
|
2016-12-20 18:37:38 +00:00
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
GST_TRACERS=leaks(stack-traces-flags=full,filters=”GstProxyPad”,check-refs=true) COMMAND
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Run the leaks tracer on all (mini)objects logging the references with less complete backtraces**
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
GST_TRACERS=leaks(stack-traces-flags=fast,check-refs=true) COMMAND
|
|
|
|
|
```
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
- If the `GST_LEAKS_TRACER_SIG` env variable is defined the tracer
|
2016-12-13 12:22:23 +00:00
|
|
|
|
will handle the following UNIX signals:
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
2016-12-13 12:22:23 +00:00
|
|
|
|
- SIGUSR1: log alive objects
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
2016-12-13 12:22:23 +00:00
|
|
|
|
- SIGUSR2: create a checkpoint and print a list of objects created and
|
|
|
|
|
destroyed since the previous checkpoint.
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
## gst-debug-viewer
|
|
|
|
|
|
|
|
|
|
gst-debug-viewer could be given the trace log in addition to the debug
|
|
|
|
|
log (or a combined log). Alternatively it would show a dialog that shows
|
|
|
|
|
all local apps (if the dbus plugin is loaded) and read the log streams
|
|
|
|
|
from the sockets/files that are configured for the app.
|
|
|
|
|
|
|
|
|
|
## gst-tracer
|
|
|
|
|
|
|
|
|
|
Counterpart of gst-tracelib-ui.
|
|
|
|
|
|
|
|
|
|
## gst-stats
|
|
|
|
|
|
|
|
|
|
A terminal app that shows summary/running stats like the summary
|
|
|
|
|
gst-tracelib shows at the end of a run. Currently only shows an
|
|
|
|
|
aggregated status.
|
|
|
|
|
|
|
|
|
|
## live-graphers
|
|
|
|
|
|
|
|
|
|
Maybe we can even feed the log into existing live graphers, with a
|
|
|
|
|
little driver * <https://github.com/dkogan/feedgnuplot>
|
|
|
|
|
|
|
|
|
|
- should tracers log into the debug.log or into a separate log?
|
|
|
|
|
|
|
|
|
|
- separate log
|
|
|
|
|
|
|
|
|
|
- use a binary format?
|
|
|
|
|
|
|
|
|
|
- worse performance (we’re writing two logs at the same time)
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
- need to be careful when people to `GST_DEBUG_CHANNEL=stderr` and
|
2017-06-16 06:24:38 +00:00
|
|
|
|
`GST_TRACE_CHANNEL=stderr` (use a shared channel, but what about the
|
2016-12-05 21:12:24 +00:00
|
|
|
|
formats?)
|
|
|
|
|
|
|
|
|
|
- debug log
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
- the tracer subsystem would need to log the `GST_TRACE` at a level
|
2016-12-05 21:12:24 +00:00
|
|
|
|
that is active
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
- should the tracer call `gst_debug_category_set_threshold()` to
|
2016-12-05 21:12:24 +00:00
|
|
|
|
ensure things work, even though the levels don’t make a lot of sense
|
|
|
|
|
here
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
- make logging a tracer (a hook in `gst_debug_log_valist()`, move
|
|
|
|
|
`gst_debug_log_default()` to the tracer module)
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
- log all debug log to the tracer log, some of the current logging
|
|
|
|
|
statements can be replaced by generic logging as shown in the
|
|
|
|
|
log-tracer
|
|
|
|
|
|
|
|
|
|
- add tools/gst-debug to extract a human readable debug log from the
|
|
|
|
|
trace log
|
|
|
|
|
|
|
|
|
|
- we could maintain a list of log functions, where
|
2017-06-16 06:24:38 +00:00
|
|
|
|
`gst_tracer_log_trace()` is the default one. This way e.g.
|
|
|
|
|
`gst-validate` could consume the traces directly.
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
- when hooking into a timer, should we just have some predefined
|
|
|
|
|
intervals?
|
|
|
|
|
|
|
|
|
|
- can we add a tracer module that registers the timer hook? then we
|
2016-12-30 09:12:41 +00:00
|
|
|
|
could do `GST_TRACER="timer(10ms);rusage"` right now the tracer hooks
|
2016-12-05 21:12:24 +00:00
|
|
|
|
are defined as an enum though.
|
|
|
|
|
|
|
|
|
|
- when connecting to a running app, we can’t easily get the *current*
|
|
|
|
|
state if logging is using a socket, as past events are not
|
|
|
|
|
explicitly stored, we could determine the current topology and emit
|
2016-12-30 09:12:41 +00:00
|
|
|
|
events with `GST_CLOCK_TIME_NONE` as ts to indicate that the events
|
2016-12-05 21:12:24 +00:00
|
|
|
|
are synthetic.
|
|
|
|
|
|
|
|
|
|
- we need stable ids for scopes (threads, elements, pads)
|
|
|
|
|
|
|
|
|
|
- the address can be reused
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
- we can use `gst_util_seqnum_next()`
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
- something like `gst_object_get_path_string()` won’t work as
|
2016-12-05 21:12:24 +00:00
|
|
|
|
objects are initially without parent
|
|
|
|
|
|
|
|
|
|
- right now the tracing-hooks are enabled/disabled from configure with
|
2016-12-30 09:12:41 +00:00
|
|
|
|
`--{enable,disable}-gst-tracer-hooks` The tracer code and the plugins
|
2016-12-05 21:12:24 +00:00
|
|
|
|
are still built though. We should add a
|
2016-12-30 09:12:41 +00:00
|
|
|
|
`--{enable,disable}-gst-tracer` to disabled the whole system,
|
|
|
|
|
allthough this is a bit confusing with the `--{enable,disable}-trace`
|
2016-12-05 21:12:24 +00:00
|
|
|
|
option we have already.
|
|
|
|
|
|
|
|
|
|
## Try it
|
|
|
|
|
|
2016-12-07 20:11:22 +00:00
|
|
|
|
### Traces for buffer flow, events and messages in TRACE level:
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
```
|
|
|
|
|
GST_DEBUG="GST_TRACER:7,GST_BUFFER*:7,GST_EVENT:7,GST_MESSAGE:7"
|
|
|
|
|
GST_TRACERS=log gst-launch-1.0 fakesrc num-buffers=10 ! fakesink -
|
|
|
|
|
```
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
### Print some pipeline stats on exit:
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
```
|
|
|
|
|
GST_DEBUG="GST_TRACER:7" GST_TRACERS="stats;rusage"
|
|
|
|
|
GST_DEBUG_FILE=trace.log gst-launch-1.0 fakesrc num-buffers=10
|
|
|
|
|
sizetype=fixed ! queue ! fakesink && gst-stats-1.0 trace.log
|
|
|
|
|
```
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
### get ts, average-cpuload, current-cpuload, time and plot
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
```
|
|
|
|
|
GST_DEBUG="GST_TRACER:7" GST_TRACERS="stats;rusage"
|
|
|
|
|
GST_DEBUG_FILE=trace.log /usr/bin/gst-play-1.0 $HOME/Videos/movie.mp4 &&
|
|
|
|
|
./scripts/gst-plot-traces.sh --format=png | gnuplot eog trace.log.*.png
|
|
|
|
|
```
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
### print processing latencies
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
```
|
|
|
|
|
GST_DEBUG="GST_TRACER:7" GST_TRACERS=latency gst-launch-1.0 \
|
|
|
|
|
audiotestsrc num-buffers=10 ! audioconvert ! volume volume=0.7 ! \
|
|
|
|
|
autoaudiosink
|
|
|
|
|
```
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
2019-03-21 10:25:38 +00:00
|
|
|
|
### print processing latencies for each element
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
GST_DEBUG="GST_TRACER:7" GST_TRACERS=latency(flags=element) gst-launch-1.0 \
|
|
|
|
|
audiotestsrc num-buffers=10 ! audioconvert ! volume volume=0.7 ! \
|
|
|
|
|
autoaudiosink
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### print reported latencies for each element
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
GST_DEBUG="GST_TRACER:7" GST_TRACERS=latency(flags=reported) gst-launch-1.0 \
|
|
|
|
|
audiotestsrc num-buffers=10 ! audioconvert ! volume volume=0.7 ! \
|
|
|
|
|
autoaudiosink
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### print all type of latencies for a pipeline
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
GST_DEBUG="GST_TRACER:7" \
|
|
|
|
|
GST_TRACERS=latency(flags=pipeline+element+reported) gst-launch-1.0 \
|
|
|
|
|
alsasrc num-buffers=20 ! flacenc ! identity ! \
|
|
|
|
|
fakesink
|
|
|
|
|
```
|
|
|
|
|
|
2016-12-05 21:12:24 +00:00
|
|
|
|
### Raise a warning if a leak is detected
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
```
|
|
|
|
|
GST_TRACERS="leaks" gst-launch-1.0 videotestsrc num-buffers=10 !
|
|
|
|
|
fakesink
|
|
|
|
|
```
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
### check if any GstEvent or GstMessage is leaked and raise a warning
|
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
```
|
|
|
|
|
GST_DEBUG="GST_TRACER:7" GST_TRACERS="leaks(GstEvent,GstMessage)"
|
|
|
|
|
gst-launch-1.0 videotestsrc num-buffers=10 ! fakesink
|
|
|
|
|
```
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
## Performance
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
```
|
|
|
|
|
run ./tests/benchmarks/tracing.sh <tracer(s)> <media>
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
2016-12-30 09:12:41 +00:00
|
|
|
|
egrep -c "(proc|thread)-rusage" trace.log 658618 grep -c
|
|
|
|
|
"gst_tracer_log_trace" trace.log 823351
|
|
|
|
|
```
|
2016-12-05 21:12:24 +00:00
|
|
|
|
|
|
|
|
|
- we can optimize most of it by using quarks in structures or
|
|
|
|
|
eventually avoid structures totally
|