[lttng-dev] [PATCH lttng-tools 1/3] Metadata: add env fields to ease lttng path hierarchy creation for viewer

Mathieu Desnoyers mathieu.desnoyers at efficios.com
Tue Aug 13 16:20:38 EDT 2019


Merging those 3 patches (backported) to my current dev branch at
https://github.com/compudj/lttng-tools-dev/tree/trace-chunk-remote-wip-compudj1

----- On Aug 13, 2019, at 2:26 PM, Jonathan Rajotte jonathan.rajotte-julien at efficios.com wrote:

> Add the following fields in the env section of the metadata:
> 
>  - trace_name
>      The session name without datetime information.
>      Hence when the session is an auto-generated one, only print
>      LTTNG_DEFAULT_NAME.
>  - trace_creation_datetime:
>      The datetime at which the session was created.
>      We use session->creation time for it.
>  - tracer_buffering_scheme
>      The buffering scheme used. The value can be uid or pid.
>  - tracer_buffering_id
>      The key used by the buffering scheme (uid/pid).
>  - architecture_bit_width
>      The bit width of the computer architecture (e.g 32 or 64)
>  - vpid_datetime
>      The registration time of the vpid for per-pid mode.
> 
> Adding these fields ensure that the trace itself carry information that
> is normally carried via folder hierarchy. e.g
> 
> test-20190417-174951/                      <- trace_name,
> trace_creation_datetime
> └── ust                                    <- domain
>    └── uid                                <- tracer_buffering_scheme
>        └── 1000                           <- tracer_buffering_id
>            └── 64-bit                     <- architecture_bit_width
>                ├── channel0_0
>                ├── index
>                │   ├── channel0_0.idx
>                └── metadata
> 
> Per-pid buffering is quite similar.
> 
> auto-20190722-174816                        <- trace_name,
> trace_creation_datetime
> └── ust                                     <- domain
>    └── pid                                 <- tracer_buffering_scheme
>        └── sample-ust-7640-20190722-174818 <- procname, tracer_buffering_id,
>        vpid_datetime
>            ├── my-channel_0
>            ├── index
>            │   ├── my-channel_0.idx
>            ├── metadata
> 
> Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien at efficios.com>
> ---
> 
> This should also be backported to 2.11 allowing Babeltrace 2 to merge
> traces from archived data (rotation) and output a trace with a similar
> lttng tree hierarchy.
> 
> ---
> src/bin/lttng-sessiond/ust-app.c      |   5 +-
> src/bin/lttng-sessiond/ust-metadata.c | 171 ++++++++++++++++++++++----
> src/bin/lttng-sessiond/ust-registry.c |   7 +-
> src/bin/lttng-sessiond/ust-registry.h |  18 ++-
> src/common/time.c                     |  32 +++++
> src/common/time.h                     |   9 ++
> 6 files changed, 215 insertions(+), 27 deletions(-)
> 
> diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c
> index 443232e79..8b3028c57 100644
> --- a/src/bin/lttng-sessiond/ust-app.c
> +++ b/src/bin/lttng-sessiond/ust-app.c
> @@ -1990,7 +1990,7 @@ static int setup_buffer_reg_pid(struct ust_app_session
> *ua_sess,
> 			app->byte_order, app->version.major,
> 			app->version.minor, reg_pid->root_shm_path,
> 			reg_pid->shm_path,
> -			ua_sess->euid, ua_sess->egid);
> +			ua_sess->euid, ua_sess->egid, ua_sess->tracing_id, app->uid);
> 	if (ret < 0) {
> 		/*
> 		 * reg_pid->registry->reg.ust is NULL upon error, so we need to
> @@ -2057,7 +2057,8 @@ static int setup_buffer_reg_uid(struct ltt_ust_session
> *usess,
> 			app->uint64_t_alignment, app->long_alignment,
> 			app->byte_order, app->version.major,
> 			app->version.minor, reg_uid->root_shm_path,
> -			reg_uid->shm_path, usess->uid, usess->gid);
> +			reg_uid->shm_path, usess->uid, usess->gid,
> +			ua_sess->tracing_id, app->uid);
> 	if (ret < 0) {
> 		/*
> 		 * reg_uid->registry->reg.ust is NULL upon error, so we need to
> diff --git a/src/bin/lttng-sessiond/ust-metadata.c
> b/src/bin/lttng-sessiond/ust-metadata.c
> index a657f7c5d..2641c0be1 100644
> --- a/src/bin/lttng-sessiond/ust-metadata.c
> +++ b/src/bin/lttng-sessiond/ust-metadata.c
> @@ -217,6 +217,41 @@ void sanitize_ctf_identifier(char *out, const char *in)
> 	}
> }
> 
> +static
> +int print_escaped_ctf_string(struct ust_registry_session *session, const char
> *string)
> +{
> +	int ret;
> +	size_t i;
> +	char cur;
> +
> +	i = 0;
> +	cur = string[i];
> +	while (cur != '\0') {
> +		switch (cur) {
> +		case '\n':
> +			ret = lttng_metadata_printf(session, "%s", "\\n");
> +			break;
> +		case '\\':
> +		case '"':
> +			ret = lttng_metadata_printf(session, "%c", '\\');
> +			if (ret)
> +				goto error;
> +			/* We still print the current char */
> +			/* Fallthrough */
> +		default:
> +			ret = lttng_metadata_printf(session, "%c", cur);
> +			break;
> +		}
> +
> +		if (ret)
> +			goto error;
> +
> +		cur = string[++i];
> +	}
> +error:
> +	return ret;
> +}
> +
> /* Called with session registry mutex held. */
> static
> int ust_metadata_enum_statedump(struct ust_registry_session *session,
> @@ -869,6 +904,104 @@ int64_t measure_clock_offset(void)
> 	return offset_best_sample.offset;
> }
> 
> +static
> +int print_metadata_session_information(struct ust_registry_session *registry)
> +{
> +	int ret;
> +	struct ltt_session *session = NULL;
> +	char creation_datetime[ISO8601_LEN];
> +
> +	rcu_read_lock();
> +	session = session_find_by_id(registry->tracing_id);
> +	if (!session) {
> +		ret = -1;
> +		goto error;
> +	}
> +
> +
> +	/* Print the trace name */
> +	ret = lttng_metadata_printf(registry, "	trace_name = \"");
> +	if (ret) {
> +		goto error;
> +	}
> +
> +	/*
> +	 * This is necessary since the creation time is present in the session
> +	 * name when it is generated.
> +	 */
> +	if (session->has_auto_generated_name) {
> +		ret = print_escaped_ctf_string(registry, DEFAULT_SESSION_NAME);
> +	} else {
> +		ret = print_escaped_ctf_string(registry, session->name);
> +	}
> +	if (ret) {
> +		goto error;
> +	}
> +
> +	ret = lttng_metadata_printf(registry, "\";\n");
> +	if (ret) {
> +		goto error;
> +	}
> +
> +	/* Prepare creation time */
> +	ret = time_t_to_ISO8601(creation_datetime, sizeof(creation_datetime),
> +			session->creation_time);
> +
> +	if (ret) {
> +		goto error;
> +	}
> +
> +	/* Output the reste of the information */
> +	ret = lttng_metadata_printf(registry,
> +		"	trace_creation_datetime = \"%s\";\n"
> +		"	hostname = \"%s\";\n",
> +		creation_datetime,
> +		session->hostname);
> +	if (ret) {
> +		goto error;
> +	}
> +
> +error:
> +	if (session) {
> +		session_put(session);
> +	}
> +	rcu_read_unlock();
> +	return ret;
> +}
> +
> +static
> +int print_metadata_app_information(struct ust_registry_session *registry,
> +		struct ust_app *app)
> +{
> +	int ret;
> +	char datetime[ISO8601_LEN];
> +
> +	if (!app) {
> +		ret = 0;
> +		goto end;
> +	}
> +
> +	ret = time_t_to_ISO8601(datetime, sizeof(datetime),
> +			app->registration_time);
> +	if (ret) {
> +		goto end;
> +	}
> +
> +	ret = lttng_metadata_printf(registry,
> +			"	tracer_patchlevel = %u;\n"
> +			"	vpid = %d;\n"
> +			"	procname = \"%s\";\n"
> +			"	vpid_datetime = \"%s\";\n" ,
> +			app->version.patchlevel,
> +			(int) app->pid,
> +			app->name,
> +			datetime
> +	);
> +
> +end:
> +	return ret;
> +}
> +
> /*
>  * Should be called with session registry mutex held.
>  */
> @@ -880,7 +1013,6 @@ int ust_metadata_session_statedump(struct
> ust_registry_session *session,
> 	char uuid_s[UUID_STR_LEN],
> 		clock_uuid_s[UUID_STR_LEN];
> 	int ret = 0;
> -	char hostname[HOST_NAME_MAX];
> 
> 	assert(session);
> 
> @@ -930,41 +1062,36 @@ int ust_metadata_session_statedump(struct
> ust_registry_session *session,
> 	if (ret)
> 		goto end;
> 
> -	/* ignore error, just use empty string if error. */
> -	hostname[0] = '\0';
> -	ret = gethostname(hostname, sizeof(hostname));
> -	if (ret && errno == ENAMETOOLONG)
> -		hostname[HOST_NAME_MAX - 1] = '\0';
> 	ret = lttng_metadata_printf(session,
> 		"env {\n"
> -		"	hostname = \"%s\";\n"
> 		"	domain = \"ust\";\n"
> 		"	tracer_name = \"lttng-ust\";\n"
> 		"	tracer_major = %u;\n"
> -		"	tracer_minor = %u;\n",
> -		hostname,
> +		"	tracer_minor = %u;\n"
> +		"	tracer_buffering_scheme = \"%s\";\n"
> +		"	tracer_buffering_id = %u;\n"
> +		"	architecture_bit_width = %u;\n",
> 		major,
> -		minor
> +		minor,
> +		app ? "pid" : "uid",
> +		app ? (int) app->pid : (int) session->tracing_uid,
> +		session->bits_per_long
> 		);
> 	if (ret)
> 		goto end;
> 
> +	ret = print_metadata_session_information(session);
> +	if (ret)
> +		goto end;
> +
> 	/*
> 	 * If per-application registry, we can output extra information
> 	 * about the application.
> 	 */
> -	if (app) {
> -		ret = lttng_metadata_printf(session,
> -			"	tracer_patchlevel = %u;\n"
> -			"	vpid = %d;\n"
> -			"	procname = \"%s\";\n",
> -			app->version.patchlevel,
> -			(int) app->pid,
> -			app->name
> -			);
> -		if (ret)
> -			goto end;
> -	}
> +	ret = print_metadata_app_information(session, app);
> +	if (ret)
> +		goto end;
> +
> 
> 	ret = lttng_metadata_printf(session,
> 		"};\n\n"
> diff --git a/src/bin/lttng-sessiond/ust-registry.c
> b/src/bin/lttng-sessiond/ust-registry.c
> index a8db79ea6..c495d86b7 100644
> --- a/src/bin/lttng-sessiond/ust-registry.c
> +++ b/src/bin/lttng-sessiond/ust-registry.c
> @@ -880,7 +880,9 @@ int ust_registry_session_init(struct ust_registry_session
> **sessionp,
> 		const char *root_shm_path,
> 		const char *shm_path,
> 		uid_t euid,
> -		gid_t egid)
> +		gid_t egid,
> +		uint64_t tracing_id,
> +		uid_t tracing_uid)
> {
> 	int ret;
> 	struct ust_registry_session *session;
> @@ -962,6 +964,9 @@ int ust_registry_session_init(struct ust_registry_session
> **sessionp,
> 		goto error;
> 	}
> 
> +	session->tracing_id = tracing_id;
> +	session->tracing_uid = tracing_uid;
> +
> 	pthread_mutex_lock(&session->lock);
> 	ret = ust_metadata_session_statedump(session, app, major, minor);
> 	pthread_mutex_unlock(&session->lock);
> diff --git a/src/bin/lttng-sessiond/ust-registry.h
> b/src/bin/lttng-sessiond/ust-registry.h
> index 2940ab7ac..2fc2dff87 100644
> --- a/src/bin/lttng-sessiond/ust-registry.h
> +++ b/src/bin/lttng-sessiond/ust-registry.h
> @@ -131,6 +131,10 @@ struct ust_registry_session {
> 	 */
> 	uint32_t major;
> 	uint32_t minor;
> +
> +	/* The id of the parent session */
> +	uint64_t tracing_id;
> +	uid_t tracing_uid;
> };
> 
> struct ust_registry_channel {
> @@ -291,7 +295,9 @@ int ust_registry_session_init(struct ust_registry_session
> **sessionp,
> 		const char *root_shm_path,
> 		const char *shm_path,
> 		uid_t euid,
> -		gid_t egid);
> +		gid_t egid,
> +		uint64_t tracing_id,
> +		uid_t tracing_uid);
> void ust_registry_session_destroy(struct ust_registry_session *session);
> 
> int ust_registry_create_event(struct ust_registry_session *session,
> @@ -351,7 +357,15 @@ int ust_registry_session_init(struct ust_registry_session
> **sessionp,
> 		uint32_t uint32_t_alignment,
> 		uint32_t uint64_t_alignment,
> 		uint32_t long_alignment,
> -		int byte_order)
> +		int byte_order,
> +		uint32_t major,
> +		uint32_t minor,
> +		const char *root_shm_path,
> +		const char *shm_path,
> +		uid_t euid,
> +		gid_t egid,
> +		uint64_t tracing_id,
> +		uid_t tracing_uid);
> {
> 	return 0;
> }
> diff --git a/src/common/time.c b/src/common/time.c
> index a01c16df5..387db3e32 100644
> --- a/src/common/time.c
> +++ b/src/common/time.c
> @@ -16,6 +16,7 @@
>  */
> 
> #include <common/time.h>
> +#include <common/error.h>
> #include <common/macros.h>
> #include <stddef.h>
> #include <stdint.h>
> @@ -68,6 +69,37 @@ struct timespec timespec_abs_diff(struct timespec t1, struct
> timespec t2)
> 	return res;
> }
> 
> +LTTNG_HIDDEN
> +int time_t_to_ISO8601(char *dest, size_t dest_size, time_t time)
> +{
> +	int ret;
> +	struct tm tm, *timeinfo;
> +
> +	if (dest_size < ISO8601_LEN) {
> +		ERR("Failed to format time to ISO8601 destination too small");
> +		ret = -1;
> +		goto end;
> +	}
> +
> +	timeinfo = localtime_r(&time, &tm);
> +	if (!timeinfo) {
> +		PERROR("localtime");
> +		ret = -1;
> +		goto end;
> +	}
> +
> +	ret = strftime(dest, dest_size, ISO8601_FORMAT, timeinfo);
> +	if (ret == 0) {
> +		ERR("Failed to format time to ISO8601");
> +		ret = -1;
> +		goto end;
> +	}
> +
> +	ret = 0;
> +end:
> +	return ret;
> +}
> +
> static
> void __attribute__((constructor)) init_locale_utf8_support(void)
> {
> diff --git a/src/common/time.h b/src/common/time.h
> index 24513d30b..5ea8c6628 100644
> --- a/src/common/time.h
> +++ b/src/common/time.h
> @@ -46,6 +46,9 @@ bool locale_supports_utf8(void);
> #define MIN_UNIT        "m"
> #define HR_UNIT         "h"
> 
> +#define ISO8601_FORMAT  "%Y%m%dT%H%M%S%z"
> +#define ISO8601_LEN     26
> +
> /*
>  * timespec_to_ms: Convert timespec to milliseconds.
>  *
> @@ -61,4 +64,10 @@ int timespec_to_ms(struct timespec ts, unsigned long *ms);
> LTTNG_HIDDEN
> struct timespec timespec_abs_diff(struct timespec ts_a, struct timespec ts_b);
> 
> +/*
> + * Format time_t to ISO8601 compatible format.
> + */
> +LTTNG_HIDDEN
> +int time_t_to_ISO8601(char *s, size_t s_size, time_t time);
> +
> #endif /* LTTNG_TIME_H */
> --
> 2.17.1
> 
> _______________________________________________
> lttng-dev mailing list
> lttng-dev at lists.lttng.org
> https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

-- 
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com


More information about the lttng-dev mailing list