Commit 1369a85a authored by Philip Withnall's avatar Philip Withnall

soup-message-io: Add sysprof profiling support for HTTP connections

This adds very basic support for dumping HTTP connection information to
sysprof, if the process is being run under a sysprof session.

See sysprof#43 for plans of how
this could be expanded in future. This is just a starting point.

The code in this commit dumps a message to the sysprof capture which
includes the URI, total time for the connection (request + response),
and the amount of data transferred in the request and response.

It adds an optional dependency on `libsysprof-capture-4.a`, and a
subproject for building that if it’s not available on the system.
Signed-off-by: Philip Withnall's avatarPhilip Withnall <withnall@endlessm.com>
parent 38e28398
Pipeline #199464 passed with stage
in 1 minute and 9 seconds
image: registry.gitlab.gnome.org/gnome/libsoup/master:v3
image: registry.gitlab.gnome.org/gnome/libsoup/master:v4
.build:
tags:
......
......@@ -4,6 +4,7 @@ RUN dnf update -y \
&& dnf install -y 'dnf-command(builddep)' \
&& dnf builddep -y libsoup \
&& dnf install -y which \
git \
gtk-doc \
libpsl-devel \
make \
......
......@@ -2,7 +2,7 @@
set -e
TAG="registry.gitlab.gnome.org/gnome/libsoup/master:v3"
TAG="registry.gitlab.gnome.org/gnome/libsoup/master:v4"
SUDO_CMD="sudo"
if docker -v |& grep -q podman; then
......
......@@ -242,6 +242,7 @@ libsoup_c_args = [
]
deps = [
libsysprof_capture_dep,
glib_deps,
libxml_dep,
sqlite_dep,
......
......@@ -11,6 +11,10 @@
#include <glib/gi18n-lib.h>
#ifdef HAVE_SYSPROF
#include <sysprof-capture.h>
#endif
#include "soup.h"
#include "soup-body-input-stream.h"
#include "soup-body-output-stream.h"
......@@ -89,6 +93,10 @@ typedef struct {
gpointer header_data;
SoupMessageCompletionFn completion_cb;
gpointer completion_data;
#ifdef HAVE_SYSPROF
gint64 begin_time_nsec;
#endif
} SoupMessageIOData;
static void io_run (SoupMessage *msg, gboolean blocking);
......@@ -1018,6 +1026,32 @@ io_run_until (SoupMessage *msg, gboolean blocking,
return FALSE;
}
#ifdef HAVE_SYSPROF
/* Allow profiling of network requests. */
if (io->read_state == SOUP_MESSAGE_IO_STATE_DONE &&
io->write_state == SOUP_MESSAGE_IO_STATE_DONE) {
SoupURI *uri = soup_message_get_uri (msg);
char *uri_str = soup_uri_to_string (uri, FALSE);
const gchar *last_modified = soup_message_headers_get_one (msg->request_headers, "Last-Modified");
const gchar *etag = soup_message_headers_get_one (msg->request_headers, "ETag");
/* FIXME: Expand and generalise sysprof support:
* https://gitlab.gnome.org/GNOME/sysprof/-/issues/43 */
sysprof_collector_mark_printf (io->begin_time_nsec, SYSPROF_CAPTURE_CURRENT_TIME - io->begin_time_nsec,
"libsoup", "message",
"%s request/response to %s: "
"read %" G_GOFFSET_FORMAT "B, "
"wrote %" G_GOFFSET_FORMAT "B, "
"Last-Modified: %s, "
"ETag: %s",
soup_message_get_https_status (msg, NULL, NULL) ? "HTTPS" : "HTTP",
uri_str, io->read_length, io->write_length,
(last_modified != NULL) ? last_modified : "(unset)",
(etag != NULL) ? etag : "(unset)");
g_free (uri_str);
}
#endif /* HAVE_SYSPROF */
g_object_unref (msg);
return done;
}
......@@ -1188,6 +1222,11 @@ new_iostate (SoupMessage *msg, GIOStream *iostream,
if (soup_message_get_io_data (msg))
soup_message_io_cleanup (msg);
soup_message_set_io_data (msg, io);
#ifdef HAVE_SYSPROF
io->begin_time_nsec = SYSPROF_CAPTURE_CURRENT_TIME;
#endif
return io;
}
......
......@@ -151,6 +151,22 @@ if cc.has_function('gmtime_r', prefix : '#include <time.h>', args : default_sour
cdata.set('HAVE_GMTIME_R', '1')
endif
# sysprof support
libsysprof_capture_dep = dependency('sysprof-capture-4',
required: get_option('sysprof'),
default_options: [
'enable_examples=false',
'enable_gtk=false',
'enable_tests=false',
'enable_tools=false',
'libsysprof=false',
'with_sysprofd=none',
'help=false',
],
fallback: ['sysprof', 'libsysprof_capture_dep'],
)
cdata.set('HAVE_SYSPROF', libsysprof_capture_dep.found())
###################
# GIO TLS support #
###################
......
......@@ -70,3 +70,9 @@ option('installed_tests',
value: false,
description: 'Install tests for as-installed testing'
)
option('sysprof',
type: 'feature',
value: 'auto',
description: 'enable sysprof-capture support for profiling'
)
[wrap-git]
directory=sysprof
url=https://gitlab.gnome.org/GNOME/sysprof.git
revision=1bb0eb7798f6a88667681229dde415ed663b1053
depth=1
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment