summaryrefslogtreecommitdiff
path: root/docs/design/draft-tracing.txt
blob: ac4ef20a09938c4195c5e6e451db33ad4fa90692 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
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.

We are going to introduce a GstTracer object. There will be only a single instance
per process or none if tracing is off (not enabled via envvar or compiled out).

Certain GStreamer core function (such as gst_pad_push or gst_element_add_pad) will
call into the tracer. The tracer will dispatch into loaded tracing plugins.
Developers will be able to select a list of plugins by setting an environment
variable, such as GST_TRACE="meminfo,dbus". One can also pass parameters to
plugins:  GST_TRACE="log(events;buffers),stats(all)".
When then plugins are loaded, we'll add them to certain hooks according to that
they are interested in.

Another env var GST_TRACE_CHANNEL can be used to send the tracing to a file or
a socket (Do the same for GST_DEBUG_CHANNEL). The syntax could be
GST_XXX_CHANNEL=file:///path/to/file or GST_XXX_CHANNEL=tcp://<ip>:<port>.
If no channel is set, the tracing goes to stderr like the debug logging.

TODO(ensonic): we might want to have GST_{DEBUG|TRACE)_FORMAT envars as well.
These could be raw, ansi-color, binary, suitable for babeltrace (see lttng), ...

With these we can deprecate GST_DEBUG_FILE and GST_DEBUG_NO_COLOR.

Hook api
--------
e.g. gst_pad_push() would become:

#ifndef GST_DISABLE_GST_DEBUG
static inline GstFlowReturn __gst_pad_push (GstPad * pad, GstBuffer * buffer);
#endif

GstFlowReturn
gst_pad_push (GstPad * pad, GstBuffer * buffer)
#ifndef GST_DISABLE_GST_DEBUG
{
  if (__tracer_enabled && __tracer_hook_is_used)
    gst_tracer_push_buffer_pre (pad, buffer);
  GstFlowReturn res = __gst_pad_push (GstPad * pad, GstBuffer * buffer);
  if (__tracer_enabled && __tracer_hook_is_used)
    gst_tracer_push_buffer_post (pad, res);
  return res;
}

static inline GstFlowReturn
__gst_pad_push (GstPad * pad, GstBuffer * buffer)
#endif
{
  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);

  return gst_pad_push_data (pad,
      GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_PUSH, buffer);
}

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 thread.

Hooks
-----
  gst_bin_add
  gst_bin_remove
  gst_element_add_pad
  gst_element_post_message
  gst_element_query
  gst_element_remove_pad
  gst_pad_link
  gst_pad_pull_range
  gst_pad_push
  gst_pad_push_list
  gst_pad_push_event
  gst_pad_unlink

Plugin api
----------

TracerPlugins are plugin features. They have a simple api:

'instance creation'
Plugins can attach handlers to one or more hooks. They use a HookMask to tell
which events they are interested in. The params are the extra detail from the
environment var.

void invoke(GstTracerHookId id, GstStructure *s);
Hooks marshall the parameters given to a trace hook into a GstStructure and also
add some extra into such as a timestamp. The hooks will receive this structure.
Hooks will be called from misc threads. The trace plugins should only consume 
(=read) the provided data. Most trace plugins will log data to a trace channel.

'instance destruction'
Plugins can output results and release data. This would ideally be done at the
end of the applications, but gst_deinit() is not mandatory. gst_tracelib was
using a gcc_destructor

Plugins ideas
=============

We can have some under gstreamer/plugins/tracers/

meminfo
-------
- register to an interval-timer hook.
- call mallinfo() and log memory usage

rusage
------
- register to an interval-timer hook.
- call getrusage() and log resource usage

dbus
----
- 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

topology
--------
- register to pipeline topology hooks
- tracing UIs can show a live pipeline graph

stats
-----
- register to buffer, event, message and query flow
- tracing apps can do e.g. statistics

UI
==

gst-debug-viewer
----------------
gst-debug-viewer could be given the tracelog in addition to the debug 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


Problems / Open items
=====================
- when hooking into a timer, should we just have some predefined intervals?
- how to trigger the shutdown processing?
- when connecting to a running app, we cant easily get the 'current' state if logging
is using a socket, as past events are not stored


Try it
======
GST_DEBUG="GST_REG*:4,GST_TRACER:4,log:7" GST_TRACE=log gst-launch-1.0 fakesrc num-buffers=10 ! fakesink
- traces for buffer flow in TRACE level and default category