Metadata: add env fields to ease life of viewer
authorJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Fri, 19 Apr 2019 16:45:44 +0000 (12:45 -0400)
committerJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Wed, 1 May 2019 21:34:32 +0000 (17:34 -0400)
Add the following field 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_time:
      The time 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).
  - isa_length
      The length of the ISA used. (e.g 32 or 64)

Addend these fields ensure that the trace itself carry information that
is normally carried via folder hierarchy. e.g

test-20190417-174951/                      <- trace_name
└── ust                                    <- domain
    └── uid                                <- tracer_buffering_scheme
        └── 1000                           <- tracer_buffering_id
            └── 64-bit                     <- isa_length
                ├── channel0_0
                ├── channel0_1
                ├── channel0_2
                ├── channel0_3
                ├── index
                │   ├── channel0_0.idx
                │   ├── channel0_1.idx
                │   ├── channel0_2.idx
                │   └── channel0_3.idx
                └── metadata

Per-pid buffering is quite similar.

Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
src/bin/lttng-sessiond/ust-app.c
src/bin/lttng-sessiond/ust-metadata.c
src/bin/lttng-sessiond/ust-registry.c
src/bin/lttng-sessiond/ust-registry.h
src/common/time.c
src/common/time.h

index 4bee504969bae5685782f9198a939816692008cb..faa51c75937ebc1f5ddabd820f0feca05dbebf6a 100644 (file)
@@ -1993,7 +1993,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
@@ -2060,7 +2060,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
index a657f7c5d3d26b62472e66ecef3f188e987ee121..f05c14c323505e9b35027953491a22e08a39cf88 100644 (file)
@@ -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,71 @@ 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_time[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_time, sizeof(creation_time),
+                       session->creation_time);
+
+       if (ret) {
+               goto error;
+       }
+
+       /* Output the reste of the information */
+       ret = lttng_metadata_printf(registry,
+               "       trace_creation_time = \"%s\";\n"
+               "       hostname = \"%s\";\n",
+               creation_time,
+               session->hostname);
+       if (ret) {
+               goto error;
+       }
+
+error:
+       if (session) {
+               session_put(session);
+       }
+       rcu_read_unlock();
+       return ret;
+}
+
 /*
  * Should be called with session registry mutex held.
  */
@@ -880,7 +980,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,25 +1029,28 @@ 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"
+               "       isa_length = %u;\n",
                major,
-               minor
+               minor,
+               app ? "pid" : "uid",
+               app ? (int) app->uid : (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.
index a8db79ea637d8dea53aced4240cd0aac5496ff44..c495d86b79c558aa47fa6b1aed3d149e49755b81 100644 (file)
@@ -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);
index 2940ab7accea9534b3fe63696f4b5ea6a60a55e6..2fc2dff87b8e72f074d8e524f33580aae01f1550 100644 (file)
@@ -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;
 }
index a01c16df5c44f024c00469beeaa014542c658c9f..387db3e3273224ff7f0837f02725ce36bfc92976 100644 (file)
@@ -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)
 {
index 24513d30bff11618deeeaa74de2c86974f2d5d5f..7e760599fd54ba6c2f0f8c2e400b5c4e00f1e0d1 100644 (file)
@@ -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     21
+
 /*
  * 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 */
This page took 0.033438 seconds and 5 git commands to generate.