[Asterisk-code-review] cdr / cel: Use event time at event creation instead of processing. (...asterisk[17.0])

Friendly Automation asteriskteam at digium.com
Thu Aug 8 13:27:29 CDT 2019


Friendly Automation has submitted this change and it was merged. ( https://gerrit.asterisk.org/c/asterisk/+/11696 )

Change subject: cdr / cel: Use event time at event creation instead of processing.
......................................................................

cdr / cel: Use event time at event creation instead of processing.

When updating times on CDR or CEL records using the time at which
it is done can result in times being incorrect if the system is
heavily loaded and stasis message processing is delayed.

This change instead makes it so CDR and CEL use the time at which
the stasis messages that drive the systems are created. This allows
them to be backed up while still producing correct records.

ASTERISK-28498

Change-Id: I6829227e67aefa318efe5e183a94d4a1b4e8500a
---
M include/asterisk/cel.h
M main/cdr.c
M main/cel.c
3 files changed, 108 insertions(+), 48 deletions(-)

Approvals:
  George Joseph: Looks good to me, but someone else must approve
  Kevin Harwell: Looks good to me, approved
  Friendly Automation: Approved for Submit



diff --git a/include/asterisk/cel.h b/include/asterisk/cel.h
index fed2085..c0b8848 100644
--- a/include/asterisk/cel.h
+++ b/include/asterisk/cel.h
@@ -264,6 +264,28 @@
 		struct ast_json *extra, const char *peer_str);
 
 /*!
+ * \brief Allocate and populate a CEL event structure
+ *
+ * \param snapshot An ast_channel_snapshot of the primary channel associated
+ *        with this channel event.
+ * \param event_type The type of call event being reported.
+ * \param event_time The time at which the event occurred.
+ * \param userdefevname Custom name for the call event. (optional)
+ * \param extra An event-specific opaque JSON blob to be rendered and placed
+ *        in the "CEL_EXTRA" information element of the call event. (optional)
+ * \param peer_str A list of comma-separated peer channel names. (optional)
+ *
+ * \since 13.29.0
+ * \since 16.6.0
+ *
+ * \retval The created ast_event structure
+ * \retval NULL on failure
+ */
+struct ast_event *ast_cel_create_event_with_time(struct ast_channel_snapshot *snapshot,
+		enum ast_cel_event_type event_type, const struct timeval *event_time,
+		const char *userdefevname, struct ast_json *extra, const char *peer_str);
+
+/*!
  * \brief CEL backend callback
  */
 /*typedef int (*ast_cel_backend_cb)(struct ast_cel_event_record *cel);*/
diff --git a/main/cdr.c b/main/cdr.c
index f8f038c..2c3ca97 100644
--- a/main/cdr.c
+++ b/main/cdr.c
@@ -718,6 +718,7 @@
 	struct timeval start;                   /*!< When this CDR was created */
 	struct timeval answer;                  /*!< Either when the channel was answered, or when the path between channels was established */
 	struct timeval end;                     /*!< When this CDR was finalized */
+	struct timeval lastevent;               /*!< The time at which the last event was created regarding this CDR */
 	unsigned int sequence;                  /*!< A monotonically increasing number for each CDR */
 	struct ast_flags flags;                 /*!< Flags on the CDR */
 	AST_DECLARE_STRING_FIELDS(
@@ -1035,7 +1036,7 @@
  * This implicitly sets the state of the newly created CDR to the Single state
  * (\ref single_state_fn_table)
  */
-static struct cdr_object *cdr_object_alloc(struct ast_channel_snapshot *chan)
+static struct cdr_object *cdr_object_alloc(struct ast_channel_snapshot *chan, const struct timeval *event_time)
 {
 	struct cdr_object *cdr;
 
@@ -1055,6 +1056,7 @@
 	ast_string_field_set(cdr, linkedid, chan->peer->linkedid);
 	cdr->disposition = AST_CDR_NULL;
 	cdr->sequence = ast_atomic_fetchadd_int(&global_cdr_sequence, +1);
+	cdr->lastevent = *event_time;
 
 	cdr->party_a.snapshot = chan;
 	ao2_t_ref(cdr->party_a.snapshot, +1, "bump snapshot during CDR creation");
@@ -1070,14 +1072,14 @@
  * \brief Create a new \ref cdr_object and append it to an existing chain
  * \param cdr The \ref cdr_object to append to
  */
-static struct cdr_object *cdr_object_create_and_append(struct cdr_object *cdr)
+static struct cdr_object *cdr_object_create_and_append(struct cdr_object *cdr, const struct timeval *event_time)
 {
 	struct cdr_object *new_cdr;
 	struct cdr_object *it_cdr;
 	struct cdr_object *cdr_last;
 
 	cdr_last = cdr->last;
-	new_cdr = cdr_object_alloc(cdr_last->party_a.snapshot);
+	new_cdr = cdr_object_alloc(cdr_last->party_a.snapshot, event_time);
 	if (!new_cdr) {
 		return NULL;
 	}
@@ -1440,7 +1442,7 @@
 	if (!ast_tvzero(cdr->end)) {
 		return;
 	}
-	cdr->end = ast_tvnow();
+	cdr->end = cdr->lastevent;
 
 	if (cdr->disposition == AST_CDR_NULL) {
 		if (!ast_tvzero(cdr->answer)) {
@@ -1490,7 +1492,7 @@
 static void cdr_object_check_party_a_answer(struct cdr_object *cdr)
 {
 	if (cdr->party_a.snapshot->state == AST_STATE_UP && ast_tvzero(cdr->answer)) {
-		cdr->answer = ast_tvnow();
+		cdr->answer = cdr->lastevent;
 		/* tv_usec is suseconds_t, which could be int or long */
 		CDR_DEBUG("%p - Set answered time to %ld.%06ld\n", cdr,
 			(long)cdr->answer.tv_sec,
@@ -1634,7 +1636,7 @@
 
 static void single_state_init_function(struct cdr_object *cdr)
 {
-	cdr->start = ast_tvnow();
+	cdr->start = cdr->lastevent;
 	cdr_object_check_party_a_answer(cdr);
 }
 
@@ -2149,6 +2151,7 @@
 
 	ao2_lock(cdr);
 	for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
+		it_cdr->lastevent = *stasis_message_timestamp(message);
 		if (ast_strlen_zero(dial_status)) {
 			if (!it_cdr->fn_table->process_dial_begin) {
 				continue;
@@ -2179,7 +2182,7 @@
 	if (res && ast_strlen_zero(dial_status)) {
 		struct cdr_object *new_cdr;
 
-		new_cdr = cdr_object_create_and_append(cdr);
+		new_cdr = cdr_object_create_and_append(cdr, stasis_message_timestamp(message));
 		if (new_cdr) {
 			new_cdr->fn_table->process_dial_begin(new_cdr, caller, peer);
 		}
@@ -2281,7 +2284,7 @@
 	}
 
 	if (update->new_snapshot && !update->old_snapshot) {
-		cdr = cdr_object_alloc(update->new_snapshot);
+		cdr = cdr_object_alloc(update->new_snapshot, stasis_message_timestamp(message));
 		if (!cdr) {
 			return;
 		}
@@ -2300,6 +2303,7 @@
 
 		ao2_lock(cdr);
 		for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
+			it_cdr->lastevent = *stasis_message_timestamp(message);
 			if (!it_cdr->fn_table->process_party_a) {
 				continue;
 			}
@@ -2309,7 +2313,7 @@
 			/* We're not hung up and we have a new snapshot - we need a new CDR */
 			struct cdr_object *new_cdr;
 
-			new_cdr = cdr_object_create_and_append(cdr);
+			new_cdr = cdr_object_create_and_append(cdr, stasis_message_timestamp(message));
 			if (new_cdr) {
 				new_cdr->fn_table->process_party_a(new_cdr, update->new_snapshot);
 			}
@@ -2321,6 +2325,7 @@
 		ao2_lock(cdr);
 		CDR_DEBUG("%p - Beginning finalize/dispatch for %s\n", cdr, update->old_snapshot->base->name);
 		for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
+			it_cdr->lastevent = *stasis_message_timestamp(message);
 			cdr_object_finalize(it_cdr);
 		}
 		cdr_object_dispatch(cdr);
@@ -2429,6 +2434,7 @@
 	/* Party A */
 	ao2_lock(cdr);
 	for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
+		it_cdr->lastevent = *stasis_message_timestamp(message);
 		if (!it_cdr->fn_table->process_bridge_leave) {
 			continue;
 		}
@@ -2463,7 +2469,7 @@
 {
 	struct cdr_object *new_cdr;
 
-	new_cdr = cdr_object_create_and_append(cdr);
+	new_cdr = cdr_object_create_and_append(cdr, &cdr->lastevent);
 	if (!new_cdr) {
 		return;
 	}
@@ -2574,7 +2580,8 @@
  */
 static void handle_parking_bridge_enter_message(struct cdr_object *cdr,
 		struct ast_bridge_snapshot *bridge,
-		struct ast_channel_snapshot *channel)
+		struct ast_channel_snapshot *channel,
+		const struct timeval *event_time)
 {
 	int res = 1;
 	struct cdr_object *it_cdr;
@@ -2583,6 +2590,8 @@
 	ao2_lock(cdr);
 
 	for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
+		it_cdr->lastevent = *event_time;
+
 		if (it_cdr->fn_table->process_parking_bridge_enter) {
 			res &= it_cdr->fn_table->process_parking_bridge_enter(it_cdr, bridge, channel);
 		}
@@ -2595,7 +2604,7 @@
 
 	if (res) {
 		/* No one handled it - we need a new one! */
-		new_cdr = cdr_object_create_and_append(cdr);
+		new_cdr = cdr_object_create_and_append(cdr, event_time);
 		if (new_cdr) {
 			/* Let the single state transition us to Parked */
 			cdr_object_transition_state(new_cdr, &single_state_fn_table);
@@ -2612,7 +2621,8 @@
  */
 static void handle_standard_bridge_enter_message(struct cdr_object *cdr,
 		struct ast_bridge_snapshot *bridge,
-		struct ast_channel_snapshot *channel)
+		struct ast_channel_snapshot *channel,
+		const struct timeval *event_time)
 {
 	enum process_bridge_enter_results result;
 	struct cdr_object *it_cdr;
@@ -2623,6 +2633,8 @@
 
 try_again:
 	for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
+		it_cdr->lastevent = *event_time;
+
 		if (it_cdr->fn_table->process_party_a) {
 			CDR_DEBUG("%p - Updating Party A %s snapshot\n", it_cdr,
 				channel->base->name);
@@ -2669,7 +2681,7 @@
 		handle_bridge_pairings(handled_cdr, bridge);
 	} else {
 		/* Nothing handled it - we need a new one! */
-		new_cdr = cdr_object_create_and_append(cdr);
+		new_cdr = cdr_object_create_and_append(cdr, event_time);
 		if (new_cdr) {
 			/* This is guaranteed to succeed: the new CDR is created in the single state
 			 * and will be able to handle the bridge enter message
@@ -2717,9 +2729,9 @@
 	}
 
 	if (!strcmp(bridge->subclass, "parking")) {
-		handle_parking_bridge_enter_message(cdr, bridge, channel);
+		handle_parking_bridge_enter_message(cdr, bridge, channel, stasis_message_timestamp(message));
 	} else {
-		handle_standard_bridge_enter_message(cdr, bridge, channel);
+		handle_standard_bridge_enter_message(cdr, bridge, channel, stasis_message_timestamp(message));
 	}
 	ao2_cleanup(cdr);
 }
@@ -2769,6 +2781,7 @@
 	ao2_lock(cdr);
 
 	for (it_cdr = cdr; it_cdr; it_cdr = it_cdr->next) {
+		it_cdr->lastevent = *stasis_message_timestamp(message);
 		if (it_cdr->fn_table->process_parked_channel) {
 			unhandled &= it_cdr->fn_table->process_parked_channel(it_cdr, payload);
 		}
@@ -2778,7 +2791,7 @@
 		/* Nothing handled the messgae - we need a new one! */
 		struct cdr_object *new_cdr;
 
-		new_cdr = cdr_object_create_and_append(cdr);
+		new_cdr = cdr_object_create_and_append(cdr, stasis_message_timestamp(message));
 		if (new_cdr) {
 			/* As the new CDR is created in the single state, it is guaranteed
 			 * to have a function for the parked call message and will handle
@@ -3607,6 +3620,7 @@
 		memset(&it_cdr->end, 0, sizeof(it_cdr->end));
 		memset(&it_cdr->answer, 0, sizeof(it_cdr->answer));
 		it_cdr->start = ast_tvnow();
+		it_cdr->lastevent = it_cdr->start;
 		cdr_object_check_party_a_answer(it_cdr);
 	}
 	ao2_unlock(cdr);
@@ -3628,6 +3642,7 @@
 
 	{
 		SCOPED_AO2LOCK(lock, cdr);
+		struct timeval now = ast_tvnow();
 
 		cdr_obj = cdr->last;
 		if (cdr_obj->fn_table == &finalized_state_fn_table) {
@@ -3641,7 +3656,7 @@
 		 * copied over automatically as part of the append
 		 */
 		ast_debug(1, "Forking CDR for channel %s\n", cdr->party_a.snapshot->base->name);
-		new_cdr = cdr_object_create_and_append(cdr);
+		new_cdr = cdr_object_create_and_append(cdr, &now);
 		if (!new_cdr) {
 			return -1;
 		}
@@ -3671,6 +3686,7 @@
 		}
 		new_cdr->start = cdr_obj->start;
 		new_cdr->answer = cdr_obj->answer;
+		new_cdr->lastevent = ast_tvnow();
 
 		/* Modify the times based on the flags passed in */
 		if (ast_test_flag(options, AST_CDR_FLAG_SET_ANSWER)
diff --git a/main/cel.c b/main/cel.c
index 1e77d25..00020ea 100644
--- a/main/cel.c
+++ b/main/cel.c
@@ -519,14 +519,23 @@
 		struct ast_json *extra, const char *peer)
 {
 	struct timeval eventtime = ast_tvnow();
+
+	return ast_cel_create_event_with_time(snapshot, event_type, &eventtime,
+		userdefevname, extra, peer);
+}
+
+struct ast_event *ast_cel_create_event_with_time(struct ast_channel_snapshot *snapshot,
+		enum ast_cel_event_type event_type, const struct timeval *event_time,
+		const char *userdefevname, struct ast_json *extra, const char *peer)
+{
 	RAII_VAR(char *, extra_txt, NULL, ast_json_free);
 	if (extra) {
 		extra_txt = ast_json_dump_string(extra);
 	}
 	return ast_event_new(AST_EVENT_CEL,
 		AST_EVENT_IE_CEL_EVENT_TYPE, AST_EVENT_IE_PLTYPE_UINT, event_type,
-		AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_sec,
-		AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_PLTYPE_UINT, eventtime.tv_usec,
+		AST_EVENT_IE_CEL_EVENT_TIME, AST_EVENT_IE_PLTYPE_UINT, event_time->tv_sec,
+		AST_EVENT_IE_CEL_EVENT_TIME_USEC, AST_EVENT_IE_PLTYPE_UINT, event_time->tv_usec,
 		AST_EVENT_IE_CEL_USEREVENT_NAME, AST_EVENT_IE_PLTYPE_STR, S_OR(userdefevname, ""),
 		AST_EVENT_IE_CEL_CIDNAME, AST_EVENT_IE_PLTYPE_STR, snapshot->caller->name,
 		AST_EVENT_IE_CEL_CIDNUM, AST_EVENT_IE_PLTYPE_STR, snapshot->caller->number,
@@ -558,8 +567,9 @@
 }
 
 static int cel_report_event(struct ast_channel_snapshot *snapshot,
-		enum ast_cel_event_type event_type, const char *userdefevname,
-		struct ast_json *extra, const char *peer_str)
+		enum ast_cel_event_type event_type, const struct timeval *event_time,
+		const char *userdefevname, struct ast_json *extra,
+		const char *peer_str)
 {
 	struct ast_event *ev;
 	RAII_VAR(struct cel_config *, cfg, ao2_global_obj_ref(cel_configs), ao2_cleanup);
@@ -587,7 +597,7 @@
 		return 0;
 	}
 
-	ev = ast_cel_create_event(snapshot, event_type, userdefevname, extra, peer_str);
+	ev = ast_cel_create_event_with_time(snapshot, event_type, event_time, userdefevname, extra, peer_str);
 	if (!ev) {
 		return -1;
 	}
@@ -601,7 +611,7 @@
 
 /* called whenever a channel is destroyed or a linkedid is changed to
  * potentially emit a CEL_LINKEDID_END event */
-static void check_retire_linkedid(struct ast_channel_snapshot *snapshot)
+static void check_retire_linkedid(struct ast_channel_snapshot *snapshot, const struct timeval *event_time)
 {
 	RAII_VAR(struct ao2_container *, linkedids, ao2_global_obj_ref(cel_linkedids), ao2_cleanup);
 	struct cel_linkedid *lid;
@@ -632,7 +642,7 @@
 		ao2_unlink(linkedids, lid);
 		ao2_unlock(linkedids);
 
-		cel_report_event(snapshot, AST_CEL_LINKEDID_END, NULL, NULL, NULL);
+		cel_report_event(snapshot, AST_CEL_LINKEDID_END, event_time, NULL, NULL, NULL);
 	} else {
 		ao2_unlock(linkedids);
 	}
@@ -852,7 +862,8 @@
 /*! \brief Typedef for callbacks that get called on channel snapshot updates */
 typedef void (*cel_channel_snapshot_monitor)(
 	struct ast_channel_snapshot *old_snapshot,
-	struct ast_channel_snapshot *new_snapshot);
+	struct ast_channel_snapshot *new_snapshot,
+	const struct timeval *event_time);
 
 static struct cel_dialstatus *get_dialstatus(const char *uniqueid)
 {
@@ -884,12 +895,13 @@
 /*! \brief Handle channel state changes */
 static void cel_channel_state_change(
 	struct ast_channel_snapshot *old_snapshot,
-	struct ast_channel_snapshot *new_snapshot)
+	struct ast_channel_snapshot *new_snapshot,
+	const struct timeval *event_time)
 {
 	int is_hungup, was_hungup;
 
 	if (!old_snapshot) {
-		cel_report_event(new_snapshot, AST_CEL_CHANNEL_START, NULL, NULL, NULL);
+		cel_report_event(new_snapshot, AST_CEL_CHANNEL_START, event_time, NULL, NULL, NULL);
 		return;
 	}
 
@@ -904,26 +916,27 @@
 			"hangupcause", new_snapshot->hangup->cause,
 			"hangupsource", new_snapshot->hangup->source,
 			"dialstatus", dialstatus ? dialstatus->dialstatus : "");
-		cel_report_event(new_snapshot, AST_CEL_HANGUP, NULL, extra, NULL);
+		cel_report_event(new_snapshot, AST_CEL_HANGUP, event_time, NULL, extra, NULL);
 		ast_json_unref(extra);
 		ao2_cleanup(dialstatus);
 
-		cel_report_event(new_snapshot, AST_CEL_CHANNEL_END, NULL, NULL, NULL);
+		cel_report_event(new_snapshot, AST_CEL_CHANNEL_END, event_time, NULL, NULL, NULL);
 		if (ast_cel_track_event(AST_CEL_LINKEDID_END)) {
-			check_retire_linkedid(new_snapshot);
+			check_retire_linkedid(new_snapshot, event_time);
 		}
 		return;
 	}
 
 	if (old_snapshot->state != new_snapshot->state && new_snapshot->state == AST_STATE_UP) {
-		cel_report_event(new_snapshot, AST_CEL_ANSWER, NULL, NULL, NULL);
+		cel_report_event(new_snapshot, AST_CEL_ANSWER, event_time, NULL, NULL, NULL);
 		return;
 	}
 }
 
 static void cel_channel_linkedid_change(
 	struct ast_channel_snapshot *old_snapshot,
-	struct ast_channel_snapshot *new_snapshot)
+	struct ast_channel_snapshot *new_snapshot,
+	const struct timeval *event_time)
 {
 	if (!old_snapshot) {
 		return;
@@ -935,13 +948,14 @@
 	if (ast_cel_track_event(AST_CEL_LINKEDID_END)
 		&& strcmp(old_snapshot->peer->linkedid, new_snapshot->peer->linkedid)) {
 		cel_linkedid_ref(new_snapshot->peer->linkedid);
-		check_retire_linkedid(old_snapshot);
+		check_retire_linkedid(old_snapshot, event_time);
 	}
 }
 
 static void cel_channel_app_change(
 	struct ast_channel_snapshot *old_snapshot,
-	struct ast_channel_snapshot *new_snapshot)
+	struct ast_channel_snapshot *new_snapshot,
+	const struct timeval *event_time)
 {
 	if (old_snapshot && !strcmp(old_snapshot->dialplan->appl, new_snapshot->dialplan->appl)) {
 		return;
@@ -949,12 +963,12 @@
 
 	/* old snapshot has an application, end it */
 	if (old_snapshot && !ast_strlen_zero(old_snapshot->dialplan->appl)) {
-		cel_report_event(old_snapshot, AST_CEL_APP_END, NULL, NULL, NULL);
+		cel_report_event(old_snapshot, AST_CEL_APP_END, event_time, NULL, NULL, NULL);
 	}
 
 	/* new snapshot has an application, start it */
 	if (!ast_strlen_zero(new_snapshot->dialplan->appl)) {
-		cel_report_event(new_snapshot, AST_CEL_APP_START, NULL, NULL, NULL);
+		cel_report_event(new_snapshot, AST_CEL_APP_START, event_time, NULL, NULL, NULL);
 	}
 }
 
@@ -988,7 +1002,7 @@
 	}
 
 	for (i = 0; i < ARRAY_LEN(cel_channel_monitors); ++i) {
-		cel_channel_monitors[i](update->old_snapshot, update->new_snapshot);
+		cel_channel_monitors[i](update->old_snapshot, update->new_snapshot, stasis_message_timestamp(message));
 	}
 }
 
@@ -1056,7 +1070,8 @@
 		return;
 	}
 
-	cel_report_event(chan_snapshot, AST_CEL_BRIDGE_ENTER, NULL, extra, ast_str_buffer(peer_str));
+	cel_report_event(chan_snapshot, AST_CEL_BRIDGE_ENTER, stasis_message_timestamp(message),
+		NULL, extra, ast_str_buffer(peer_str));
 }
 
 static void cel_bridge_leave_cb(
@@ -1085,7 +1100,8 @@
 		return;
 	}
 
-	cel_report_event(chan_snapshot, AST_CEL_BRIDGE_EXIT, NULL, extra, ast_str_buffer(peer_str));
+	cel_report_event(chan_snapshot, AST_CEL_BRIDGE_EXIT, stasis_message_timestamp(message),
+		NULL, extra, ast_str_buffer(peer_str));
 }
 
 static void cel_parking_cb(
@@ -1102,7 +1118,8 @@
 			"parker_dial_string", parked_payload->parker_dial_string,
 			"parking_lot", parked_payload->parkinglot);
 		if (extra) {
-			cel_report_event(parked_payload->parkee, AST_CEL_PARK_START, NULL, extra, NULL);
+			cel_report_event(parked_payload->parkee, AST_CEL_PARK_START, stasis_message_timestamp(message),
+				NULL, extra, NULL);
 		}
 		return;
 	case PARKED_CALL_TIMEOUT:
@@ -1131,7 +1148,8 @@
 	}
 
 	if (extra) {
-		cel_report_event(parked_payload->parkee, AST_CEL_PARK_END, NULL, extra, NULL);
+		cel_report_event(parked_payload->parkee, AST_CEL_PARK_END, stasis_message_timestamp(message),
+			NULL, extra, NULL);
 	}
 }
 
@@ -1224,7 +1242,8 @@
 
 		extra = ast_json_pack("{s: s}", "forward", get_blob_variable(blob, "forward"));
 		if (extra) {
-			cel_report_event(snapshot, AST_CEL_FORWARD, NULL, extra, NULL);
+			cel_report_event(snapshot, AST_CEL_FORWARD, stasis_message_timestamp(message),
+				NULL, extra, NULL);
 			ast_json_unref(extra);
 		}
 	}
@@ -1247,7 +1266,8 @@
 		{
 			const char *event = ast_json_string_get(ast_json_object_get(event_details, "event"));
 			struct ast_json *extra = ast_json_object_get(event_details, "extra");
-			cel_report_event(obj->snapshot, event_type, event, extra, NULL);
+			cel_report_event(obj->snapshot, event_type, stasis_message_timestamp(message),
+				event, extra, NULL);
 			break;
 		}
 	default:
@@ -1276,7 +1296,8 @@
 		"transferee_channel_name", transfer_msg->transferee ? transfer_msg->transferee->base->name : "N/A",
 		"transferee_channel_uniqueid", transfer_msg->transferee ? transfer_msg->transferee->base->uniqueid  : "N/A");
 	if (extra) {
-		cel_report_event(chan_snapshot, AST_CEL_BLINDTRANSFER, NULL, extra, NULL);
+		cel_report_event(chan_snapshot, AST_CEL_BLINDTRANSFER, stasis_message_timestamp(message),
+			NULL, extra, NULL);
 		ast_json_unref(extra);
 	}
 }
@@ -1339,7 +1360,8 @@
 		}
 		break;
 	}
-	cel_report_event(channel1, AST_CEL_ATTENDEDTRANSFER, NULL, extra, NULL);
+	cel_report_event(channel1, AST_CEL_ATTENDEDTRANSFER, stasis_message_timestamp(message),
+		NULL, extra, NULL);
 	ast_json_unref(extra);
 }
 
@@ -1363,7 +1385,7 @@
 		return;
 	}
 
-	cel_report_event(target, AST_CEL_PICKUP, NULL, extra, NULL);
+	cel_report_event(target, AST_CEL_PICKUP, stasis_message_timestamp(message), NULL, extra, NULL);
 	ast_json_unref(extra);
 }
 
@@ -1387,7 +1409,7 @@
 		return;
 	}
 
-	cel_report_event(localone, AST_CEL_LOCAL_OPTIMIZE, NULL, extra, NULL);
+	cel_report_event(localone, AST_CEL_LOCAL_OPTIMIZE, stasis_message_timestamp(message), NULL, extra, NULL);
 	ast_json_unref(extra);
 }
 

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/11696
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: 17.0
Gerrit-Change-Id: I6829227e67aefa318efe5e183a94d4a1b4e8500a
Gerrit-Change-Number: 11696
Gerrit-PatchSet: 1
Gerrit-Owner: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Friendly Automation
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20190808/1c0562fe/attachment-0001.html>


More information about the asterisk-code-review mailing list