src.ctf.lttng-live: use `_APPEND_CAUSE` variants of logging macros
[babeltrace.git] / src / plugins / ctf / lttng-live / lttng-live.c
index 4586d9ccc6732a6d22a4f78a4bc807d100e69d36..d12b674d3f3c7c754531f4eef2ad54b4e3b7233a 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <glib.h>
 #include <inttypes.h>
+#include <stdbool.h>
 #include <unistd.h>
 
 #include "common/assert.h"
@@ -177,6 +178,8 @@ struct lttng_live_trace *lttng_live_create_trace(struct lttng_live_session *sess
 
        trace = g_new0(struct lttng_live_trace, 1);
        if (!trace) {
+               BT_COMP_LOGE_APPEND_CAUSE(self_comp,
+                       "Failed to allocate live trace");
                goto error;
        }
        trace->log_level = session->log_level;
@@ -230,6 +233,8 @@ int lttng_live_add_session(struct lttng_live_msg_iter *lttng_live_msg_iter,
 
        session = g_new0(struct lttng_live_session, 1);
        if (!session) {
+               BT_COMP_LOGE_APPEND_CAUSE(self_comp,
+                       "Failed to allocate live session");
                goto error;
        }
 
@@ -252,7 +257,7 @@ int lttng_live_add_session(struct lttng_live_msg_iter *lttng_live_msg_iter,
        g_ptr_array_add(lttng_live_msg_iter->sessions, session);
        goto end;
 error:
-       BT_COMP_LOGE("Error adding session");
+       BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Error adding session");
        g_free(session);
        ret = -1;
 end:
@@ -274,9 +279,8 @@ void lttng_live_destroy_session(struct lttng_live_session *session)
        BT_COMP_LOGD("Destroy lttng live session");
        if (session->id != -1ULL) {
                if (lttng_live_detach_session(session)) {
-                       if (session->lttng_live_msg_iter &&
-                                       !lttng_live_graph_is_canceled(
-                                               session->lttng_live_msg_iter)) {
+                       if (!lttng_live_graph_is_canceled(
+                                       session->lttng_live_msg_iter)) {
                                /* Old relayd cannot detach sessions. */
                                BT_COMP_LOGD("Unable to detach lttng live session %" PRIu64,
                                        session->id);
@@ -399,7 +403,7 @@ enum lttng_live_iterator_status lttng_live_iterator_next_handle_one_no_data_stre
        if (ret != LTTNG_LIVE_ITERATOR_STATUS_OK) {
                goto end;
        }
-       BT_ASSERT(lttng_live_stream->state != LTTNG_LIVE_STREAM_EOF);
+       BT_ASSERT_DBG(lttng_live_stream->state != LTTNG_LIVE_STREAM_EOF);
        if (lttng_live_stream->state == LTTNG_LIVE_STREAM_QUIESCENT) {
                uint64_t last_inact_ts = lttng_live_stream->last_inactivity_ts,
                         curr_inact_ts = lttng_live_stream->current_inactivity_ts;
@@ -435,18 +439,28 @@ enum lttng_live_iterator_status lttng_live_get_session(
                struct lttng_live_msg_iter *lttng_live_msg_iter,
                struct lttng_live_session *session)
 {
+       bt_logging_level log_level = lttng_live_msg_iter->log_level;
+       bt_self_component *self_comp = lttng_live_msg_iter->self_comp;
        enum lttng_live_iterator_status status;
        uint64_t trace_idx;
-       int ret = 0;
 
        if (!session->attached) {
-               ret = lttng_live_attach_session(session);
-               if (ret) {
-                       if (lttng_live_msg_iter && lttng_live_graph_is_canceled(
-                                       lttng_live_msg_iter)) {
+               enum lttng_live_attach_session_status attach_status =
+                       lttng_live_attach_session(session);
+               if (attach_status != LTTNG_LIVE_ATTACH_SESSION_STATUS_OK) {
+                       if (lttng_live_graph_is_canceled(lttng_live_msg_iter)) {
+                               /*
+                                * Clear any causes appended in
+                                * `lttng_live_attach_session()` as we want to
+                                * return gracefully since the graph was
+                                * cancelled.
+                                */
+                               bt_current_thread_clear_error();
                                status = LTTNG_LIVE_ITERATOR_STATUS_AGAIN;
                        } else {
                                status = LTTNG_LIVE_ITERATOR_STATUS_ERROR;
+                               BT_COMP_LOGE_APPEND_CAUSE(self_comp,
+                                       "Error attaching to LTTng live session");
                        }
                        goto end;
                }
@@ -457,13 +471,30 @@ enum lttng_live_iterator_status lttng_live_get_session(
                        status != LTTNG_LIVE_ITERATOR_STATUS_END) {
                goto end;
        }
-       for (trace_idx = 0; trace_idx < session->traces->len; trace_idx++) {
+       trace_idx = 0;
+       while (trace_idx < session->traces->len) {
                struct lttng_live_trace *trace =
                        g_ptr_array_index(session->traces, trace_idx);
 
                status = lttng_live_metadata_update(trace);
-               if (status != LTTNG_LIVE_ITERATOR_STATUS_OK &&
-                               status != LTTNG_LIVE_ITERATOR_STATUS_END) {
+               switch (status) {
+               case LTTNG_LIVE_ITERATOR_STATUS_OK:
+                       trace_idx++;
+                       break;
+               case LTTNG_LIVE_ITERATOR_STATUS_END:
+                       /*
+                        * The trace has ended. Remove it of the array an
+                        * continue the iteration.
+                        * We can remove the trace safely when using the
+                        * g_ptr_array_remove_index_fast because it replaces
+                        * the element at trace_idx with the array's last
+                        * element. trace_idx is not incremented because of
+                        * that.
+                        */
+                       (void) g_ptr_array_remove_index_fast(session->traces,
+                               trace_idx);
+                       break;
+               default:
                        goto end;
                }
        }
@@ -511,6 +542,8 @@ lttng_live_iterator_handle_new_streams_and_metadata(
                struct lttng_live_msg_iter *lttng_live_msg_iter)
 {
        enum lttng_live_iterator_status ret = LTTNG_LIVE_ITERATOR_STATUS_OK;
+       bt_logging_level log_level = lttng_live_msg_iter->log_level;
+       bt_self_component *self_comp = lttng_live_msg_iter->self_comp;
        uint64_t session_idx = 0, nr_sessions_opened = 0;
        struct lttng_live_session *session;
        enum session_not_found_action sess_not_found_act =
@@ -533,6 +566,8 @@ lttng_live_iterator_handle_new_streams_and_metadata(
                         */
                        if (lttng_live_create_viewer_session(lttng_live_msg_iter)) {
                                ret = LTTNG_LIVE_ITERATOR_STATUS_ERROR;
+                               BT_COMP_LOGE_APPEND_CAUSE(self_comp,
+                                       "Error creating LTTng live viewer session");
                                goto end;
                        }
                }
@@ -572,6 +607,8 @@ enum lttng_live_iterator_status emit_inactivity_message(
                bt_message **message, uint64_t timestamp)
 {
        enum lttng_live_iterator_status ret = LTTNG_LIVE_ITERATOR_STATUS_OK;
+       bt_logging_level log_level = lttng_live_msg_iter->log_level;
+       bt_self_component *self_comp = lttng_live_msg_iter->self_comp;
        bt_message *msg = NULL;
 
        BT_ASSERT(stream_iter->trace->clock_class);
@@ -580,6 +617,8 @@ enum lttng_live_iterator_status emit_inactivity_message(
                lttng_live_msg_iter->self_msg_iter,
                stream_iter->trace->clock_class, timestamp);
        if (!msg) {
+               BT_COMP_LOGE_APPEND_CAUSE(self_comp,
+                       "Error emitting message iterator inactivity message");
                goto error;
        }
 
@@ -633,8 +672,8 @@ int live_get_msg_ts_ns(struct lttng_live_stream_iterator *stream_iter,
        bt_logging_level log_level = lttng_live_msg_iter->log_level;
        bt_self_component *self_comp = lttng_live_msg_iter->self_comp;
 
-       BT_ASSERT(msg);
-       BT_ASSERT(ts_ns);
+       BT_ASSERT_DBG(msg);
+       BT_ASSERT_DBG(ts_ns);
 
        BT_COMP_LOGD("Getting message's timestamp: iter-data-addr=%p, msg-addr=%p, "
                "last-msg-ts=%" PRId64, lttng_live_msg_iter, msg,
@@ -644,7 +683,7 @@ int live_get_msg_ts_ns(struct lttng_live_stream_iterator *stream_iter,
        case BT_MESSAGE_TYPE_EVENT:
                clock_class = bt_message_event_borrow_stream_class_default_clock_class_const(
                                msg);
-               BT_ASSERT(clock_class);
+               BT_ASSERT_DBG(clock_class);
 
                clock_snapshot = bt_message_event_borrow_default_clock_snapshot_const(
                        msg);
@@ -693,11 +732,12 @@ int live_get_msg_ts_ns(struct lttng_live_stream_iterator *stream_iter,
        }
 
        clock_class = bt_clock_snapshot_borrow_clock_class_const(clock_snapshot);
-       BT_ASSERT(clock_class);
+       BT_ASSERT_DBG(clock_class);
 
        ret = bt_clock_snapshot_get_ns_from_origin(clock_snapshot, ts_ns);
        if (ret) {
-               BT_COMP_LOGE("Cannot get nanoseconds from Epoch of clock snapshot: "
+               BT_COMP_LOGE_APPEND_CAUSE(self_comp,
+                       "Cannot get nanoseconds from Epoch of clock snapshot: "
                        "clock-snapshot-addr=%p", clock_snapshot);
                goto error;
        }
@@ -777,8 +817,9 @@ enum lttng_live_iterator_status lttng_live_iterator_next_handle_one_active_data_
        case BT_MSG_ITER_STATUS_ERROR:
        default:
                ret = LTTNG_LIVE_ITERATOR_STATUS_ERROR;
-               BT_COMP_LOGW("CTF msg iterator return an error or failed msg_iter=%p",
-                       lttng_live_stream->msg_iter);
+               BT_COMP_LOGE_APPEND_CAUSE(self_comp,
+                       "CTF message iterator return an error or failed: "
+                       "msg_iter=%p", lttng_live_stream->msg_iter);
                break;
        }
 
@@ -794,6 +835,8 @@ enum lttng_live_iterator_status lttng_live_iterator_close_stream(
 {
        enum lttng_live_iterator_status live_status =
                LTTNG_LIVE_ITERATOR_STATUS_OK;
+       bt_logging_level log_level = lttng_live_msg_iter->log_level;
+       bt_self_component *self_comp = lttng_live_msg_iter->self_comp;
        /*
         * The viewer has hung up on us so we are closing the stream. The
         * `bt_msg_iter` should simply realize that it needs to close the
@@ -804,6 +847,8 @@ enum lttng_live_iterator_status lttng_live_iterator_close_stream(
                curr_msg);
 
        if (status == BT_MSG_ITER_STATUS_ERROR) {
+               BT_COMP_LOGE_APPEND_CAUSE(self_comp,
+                       "Error getting the next message from CTF message iterator");
                live_status = LTTNG_LIVE_ITERATOR_STATUS_ERROR;
                goto end;
        }
@@ -940,8 +985,8 @@ enum lttng_live_iterator_status next_stream_iterator_for_trace(
        int64_t youngest_candidate_msg_ts = INT64_MAX;
        uint64_t stream_iter_idx;
 
-       BT_ASSERT(live_trace);
-       BT_ASSERT(live_trace->stream_iterators);
+       BT_ASSERT_DBG(live_trace);
+       BT_ASSERT_DBG(live_trace->stream_iterators);
        /*
         * Update the current message of every stream iterators of this trace.
         * The current msg of every stream must have a timestamp equal or
@@ -955,16 +1000,6 @@ enum lttng_live_iterator_status next_stream_iterator_for_trace(
                        g_ptr_array_index(live_trace->stream_iterators,
                                stream_iter_idx);
 
-               /*
-                * Since we may remove elements from the GPtrArray as we
-                * iterate over it, it's possible to see the same element more
-                * than once.
-                */
-               if (stream_iter == youngest_candidate_stream_iter) {
-                       stream_iter_idx++;
-                       continue;
-               }
-
                /*
                 * Find if there is are now current message for this stream
                 * iterator get it.
@@ -986,7 +1021,7 @@ enum lttng_live_iterator_status next_stream_iterator_for_trace(
                                goto end;
                        }
 
-                       BT_ASSERT(msg);
+                       BT_ASSERT_DBG(msg);
 
                        /*
                         * Get the timestamp in nanoseconds from origin of this
@@ -1010,7 +1045,8 @@ enum lttng_live_iterator_status next_stream_iterator_for_trace(
                                 * We received a message in the past. To ensure
                                 * monotonicity, we can't send it forward.
                                 */
-                               BT_COMP_LOGE("Message's timestamp is less than "
+                               BT_COMP_LOGE_APPEND_CAUSE(self_comp,
+                                       "Message's timestamp is less than "
                                        "lttng-live's message iterator's last "
                                        "returned timestamp: "
                                        "lttng-live-msg-iter-addr=%p, ts=%" PRId64 ", "
@@ -1022,7 +1058,7 @@ enum lttng_live_iterator_status next_stream_iterator_for_trace(
                        }
                }
 
-               BT_ASSERT(stream_iter != youngest_candidate_stream_iter);
+               BT_ASSERT_DBG(stream_iter != youngest_candidate_stream_iter);
 
                if (!stream_iter_is_ended) {
                        if (G_UNLIKELY(youngest_candidate_stream_iter == NULL) ||
@@ -1039,7 +1075,7 @@ enum lttng_live_iterator_status next_stream_iterator_for_trace(
                                 * Order the messages in an arbitrary but
                                 * deterministic way.
                                 */
-                               BT_ASSERT(stream_iter != youngest_candidate_stream_iter);
+                               BT_ASSERT_DBG(stream_iter != youngest_candidate_stream_iter);
                                int ret = common_muxing_compare_messages(
                                        stream_iter->current_msg,
                                        youngest_candidate_stream_iter->current_msg);
@@ -1067,14 +1103,17 @@ enum lttng_live_iterator_status next_stream_iterator_for_trace(
                        stream_iter_idx++;
                } else {
                        /*
-                        * The live stream iterator is ENDed. We remove that
-                        * iterator from the list and we restart the iteration
-                        * at the beginning of the live stream iterator array
-                        * to because the removal will shuffle the array.
+                        * The live stream iterator has ended. That
+                        * iterator is removed from the array, but
+                        * there is no need to increment
+                        * stream_iter_idx as
+                        * g_ptr_array_remove_index_fast replaces the
+                        * removed element with the array's last
+                        * element.
                         */
-                       g_ptr_array_remove_index_fast(live_trace->stream_iterators,
+                       g_ptr_array_remove_index_fast(
+                               live_trace->stream_iterators,
                                stream_iter_idx);
-                       stream_iter_idx = 0;
                }
        }
 
@@ -1118,13 +1157,8 @@ enum lttng_live_iterator_status next_stream_iterator_for_session(
                goto end;
        }
 
-       BT_ASSERT(session->traces);
+       BT_ASSERT_DBG(session->traces);
 
-       /*
-        * Use while loops here rather then for loops so we can restart the
-        * iteration if an element is removed from the array during the
-        * looping.
-        */
        while (trace_idx < session->traces->len) {
                bool trace_is_ended = false;
                struct lttng_live_stream_iterator *stream_iter;
@@ -1144,7 +1178,7 @@ enum lttng_live_iterator_status next_stream_iterator_for_session(
                }
 
                if (!trace_is_ended) {
-                       BT_ASSERT(stream_iter);
+                       BT_ASSERT_DBG(stream_iter);
 
                        if (G_UNLIKELY(youngest_candidate_stream_iter == NULL) ||
                                        stream_iter->current_msg_ts_ns < youngest_candidate_msg_ts) {
@@ -1175,8 +1209,13 @@ enum lttng_live_iterator_status next_stream_iterator_for_session(
                        }
                        trace_idx++;
                } else {
-                       g_ptr_array_remove_index_fast(session->traces, trace_idx);
-                       trace_idx = 0;
+                       /*
+                        * trace_idx is not incremented since
+                        * g_ptr_array_remove_index_fast replaces the
+                        * element at trace_idx with the array's last element.
+                        */
+                       g_ptr_array_remove_index_fast(session->traces,
+                               trace_idx);
                }
        }
        if (youngest_candidate_stream_iter) {
@@ -1227,7 +1266,7 @@ bt_component_class_message_iterator_next_method_status lttng_live_msg_iter_next(
 
        *count = 0;
 
-       BT_ASSERT(lttng_live_msg_iter);
+       BT_ASSERT_DBG(lttng_live_msg_iter);
 
        /*
         * Clear all the invalid message reference that might be left over in
@@ -1286,18 +1325,8 @@ bt_component_class_message_iterator_next_method_status lttng_live_msg_iter_next(
                          *candidate_stream_iter = NULL;
                int64_t youngest_msg_ts_ns = INT64_MAX;
 
-               BT_ASSERT(lttng_live_msg_iter->sessions);
+               BT_ASSERT_DBG(lttng_live_msg_iter->sessions);
                session_idx = 0;
-               /*
-                * Use a while loop instead of a for loop so we can restart the
-                * iteration if we remove an element. We can safely call
-                * next_stream_iterator_for_session() multiple times on the
-                * same session as we only fetch a new message if there is no
-                * current next message for each live stream iterator.
-                * If all live stream iterator of that session already have a
-                * current next message, the function will simply exit return
-                * the same candidate live stream iterator every time.
-                */
                while (session_idx < lttng_live_msg_iter->sessions->len) {
                        struct lttng_live_session *session =
                                g_ptr_array_index(lttng_live_msg_iter->sessions,
@@ -1315,14 +1344,15 @@ bt_component_class_message_iterator_next_method_status lttng_live_msg_iter_next(
                        if (stream_iter_status == LTTNG_LIVE_ITERATOR_STATUS_END) {
                                if (session->closed && session->traces->len == 0) {
                                        /*
-                                        * Remove the session from the list and restart the
-                                        * iteration at the beginning of the array since the
-                                        * removal shuffle the elements of the array.
+                                        * Remove the session from the list.
+                                        * session_idx is not modified since
+                                        * g_ptr_array_remove_index_fast
+                                        * replaces the the removed element with
+                                        * the array's last element.
                                         */
                                        g_ptr_array_remove_index_fast(
                                                lttng_live_msg_iter->sessions,
                                                session_idx);
-                                       session_idx = 0;
                                } else {
                                        session_idx++;
                                }
@@ -1376,9 +1406,9 @@ bt_component_class_message_iterator_next_method_status lttng_live_msg_iter_next(
                        goto end;
                }
 
-               BT_ASSERT(youngest_stream_iter->current_msg);
+               BT_ASSERT_DBG(youngest_stream_iter->current_msg);
                /* Ensure monotonicity. */
-               BT_ASSERT(lttng_live_msg_iter->last_msg_ts_ns <=
+               BT_ASSERT_DBG(lttng_live_msg_iter->last_msg_ts_ns <=
                        youngest_stream_iter->current_msg_ts_ns);
 
                /*
@@ -1476,7 +1506,7 @@ bt_component_class_message_iterator_initialize_method_status lttng_live_msg_iter
 
        lttng_live_msg_iter->viewer_connection =
                live_viewer_connection_create(lttng_live->params.url->str, false,
-                       lttng_live_msg_iter, log_level);
+                       lttng_live_msg_iter, self_comp, NULL, log_level);
        if (!lttng_live_msg_iter->viewer_connection) {
                goto error;
        }
@@ -1495,7 +1525,7 @@ bt_component_class_message_iterator_initialize_method_status lttng_live_msg_iter
                                lttng_live->params.url->str);
                        break;
                case SESSION_NOT_FOUND_ACTION_FAIL:
-                       BT_COMP_LOGE("Unable to connect to the requested live viewer "
+                       BT_COMP_LOGE_APPEND_CAUSE(self_comp, "Unable to connect to the requested live viewer "
                                "session. Fail the message iterator"
                                "initialization because of %s=\"%s\" "
                                "component parameter: url =\"%s\"",
@@ -1551,7 +1581,8 @@ bt_component_class_query_method_status lttng_live_query_list_sessions(
                goto error;
        } else if (validation_status == BT_PARAM_VALIDATION_STATUS_VALIDATION_ERROR) {
                status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR;
-               BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "%s", validate_error);
+               BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class, "%s",
+                       validate_error);
                goto error;
        }
 
@@ -1559,8 +1590,10 @@ bt_component_class_query_method_status lttng_live_query_list_sessions(
        url = bt_value_string_get(url_value);
 
        viewer_connection = live_viewer_connection_create(url, true, NULL,
-               log_level);
+               NULL, self_comp_class, log_level);
        if (!viewer_connection) {
+               BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class,
+                       "Failed to create viewer connection");
                status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_ERROR;
                goto error;
        }
@@ -1568,6 +1601,8 @@ bt_component_class_query_method_status lttng_live_query_list_sessions(
        status = live_viewer_connection_list_sessions(viewer_connection,
                result);
        if (status != BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_OK) {
+               BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class,
+                       "Failed to list viewer sessions");
                goto error;
        }
 
@@ -1593,6 +1628,7 @@ end:
 static
 bt_component_class_query_method_status lttng_live_query_support_info(
                const bt_value *params, const bt_value **result,
+               bt_self_component_class *self_comp_class,
                bt_logging_level log_level)
 {
        bt_component_class_query_method_status status =
@@ -1609,12 +1645,14 @@ bt_component_class_query_method_status lttng_live_query_support_info(
        input_type_value = bt_value_map_borrow_entry_value_const(params,
                "type");
        if (!input_type_value) {
-               BT_COMP_LOGE("Missing expected `type` parameter.");
+               BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class,
+                       "Missing expected `type` parameter.");
                goto error;
        }
 
        if (!bt_value_is_string(input_type_value)) {
-               BT_COMP_LOGE("`type` parameter is not a string value.");
+               BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class,
+                       "`type` parameter is not a string value.");
                goto error;
        }
 
@@ -1625,12 +1663,14 @@ bt_component_class_query_method_status lttng_live_query_support_info(
 
        input_value = bt_value_map_borrow_entry_value_const(params, "input");
        if (!input_value) {
-               BT_COMP_LOGE("Missing expected `input` parameter.");
+               BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class,
+                       "Missing expected `input` parameter.");
                goto error;
        }
 
        if (!bt_value_is_string(input_value)) {
-               BT_COMP_LOGE("`input` parameter is not a string value.");
+               BT_COMP_CLASS_LOGE_APPEND_CAUSE(self_comp_class,
+                       "`input` parameter is not a string value.");
                goto error;
        }
 
@@ -1687,7 +1727,7 @@ bt_component_class_query_method_status lttng_live_query(
                        self_comp_class, log_level);
        } else if (strcmp(object, "babeltrace.support-info") == 0) {
                status = lttng_live_query_support_info(params, result,
-                       log_level);
+                       self_comp_class, log_level);
        } else {
                BT_COMP_LOGI("Unknown query object `%s`", object);
                status = BT_COMPONENT_CLASS_QUERY_METHOD_STATUS_UNKNOWN_OBJECT;
This page took 0.031406 seconds and 4 git commands to generate.