api,bearer: new 'start-date' field in bearer statistics

It stores the epoch timestamp of the current bearer session start.
If there is no connected bearer, it is set to 0 and not displayed
in mmcli output.

Signed-off-by: Frederic Martinsons <frederic.martinsons@sigfox.com>

Includes updates by Aleksander Morgado to fix coding style issues.
This commit is contained in:
Frederic Martinsons
2021-10-15 08:38:50 +02:00
committed by Aleksander Morgado
parent 53bcdaa8c3
commit 0510e9aef8
9 changed files with 131 additions and 8 deletions

View File

@@ -270,18 +270,21 @@ print_bearer_info (MMBearer *bearer)
/* Stats */ /* Stats */
{ {
gchar *duration = NULL; guint64 start_date = 0;
gchar *bytes_rx = NULL; gchar *duration = NULL;
gchar *bytes_tx = NULL; gchar *bytes_rx = NULL;
gchar *attempts = NULL; gchar *bytes_tx = NULL;
gchar *failed_attempts = NULL; gchar *attempts = NULL;
gchar *total_duration = NULL; gchar *failed_attempts = NULL;
gchar *total_bytes_rx = NULL; gchar *total_duration = NULL;
gchar *total_bytes_tx = NULL; gchar *total_bytes_rx = NULL;
gchar *total_bytes_tx = NULL;
if (stats) { if (stats) {
guint64 val; guint64 val;
start_date = mm_bearer_stats_get_start_date (stats);
val = mm_bearer_stats_get_duration (stats); val = mm_bearer_stats_get_duration (stats);
if (val) if (val)
duration = g_strdup_printf ("%" G_GUINT64_FORMAT, val); duration = g_strdup_printf ("%" G_GUINT64_FORMAT, val);
@@ -308,6 +311,8 @@ print_bearer_info (MMBearer *bearer)
total_bytes_tx = g_strdup_printf ("%" G_GUINT64_FORMAT, val); total_bytes_tx = g_strdup_printf ("%" G_GUINT64_FORMAT, val);
} }
if (start_date)
mmcli_output_start_date (start_date);
mmcli_output_string_take (MMC_F_BEARER_STATS_DURATION, duration); mmcli_output_string_take (MMC_F_BEARER_STATS_DURATION, duration);
mmcli_output_string_take (MMC_F_BEARER_STATS_BYTES_RX, bytes_rx); mmcli_output_string_take (MMC_F_BEARER_STATS_BYTES_RX, bytes_rx);
mmcli_output_string_take (MMC_F_BEARER_STATS_BYTES_TX, bytes_tx); mmcli_output_string_take (MMC_F_BEARER_STATS_BYTES_TX, bytes_tx);

View File

@@ -248,6 +248,7 @@ static FieldInfo field_infos[] = {
[MMC_F_BEARER_IPV6_CONFIG_GATEWAY] = { "bearer.ipv6-config.gateway", "gateway", MMC_S_BEARER_IPV6_CONFIG, }, [MMC_F_BEARER_IPV6_CONFIG_GATEWAY] = { "bearer.ipv6-config.gateway", "gateway", MMC_S_BEARER_IPV6_CONFIG, },
[MMC_F_BEARER_IPV6_CONFIG_DNS] = { "bearer.ipv6-config.dns", "dns", MMC_S_BEARER_IPV6_CONFIG, }, [MMC_F_BEARER_IPV6_CONFIG_DNS] = { "bearer.ipv6-config.dns", "dns", MMC_S_BEARER_IPV6_CONFIG, },
[MMC_F_BEARER_IPV6_CONFIG_MTU] = { "bearer.ipv6-config.mtu", "mtu", MMC_S_BEARER_IPV6_CONFIG, }, [MMC_F_BEARER_IPV6_CONFIG_MTU] = { "bearer.ipv6-config.mtu", "mtu", MMC_S_BEARER_IPV6_CONFIG, },
[MMC_F_BEARER_STATS_START_DATE] = { "bearer.stats.start-date", "start date", MMC_S_BEARER_STATS, },
[MMC_F_BEARER_STATS_DURATION] = { "bearer.stats.duration", "duration", MMC_S_BEARER_STATS, }, [MMC_F_BEARER_STATS_DURATION] = { "bearer.stats.duration", "duration", MMC_S_BEARER_STATS, },
[MMC_F_BEARER_STATS_BYTES_RX] = { "bearer.stats.bytes-rx", "bytes rx", MMC_S_BEARER_STATS, }, [MMC_F_BEARER_STATS_BYTES_RX] = { "bearer.stats.bytes-rx", "bytes rx", MMC_S_BEARER_STATS, },
[MMC_F_BEARER_STATS_BYTES_TX] = { "bearer.stats.bytes-tx", "bytes tx", MMC_S_BEARER_STATS, }, [MMC_F_BEARER_STATS_BYTES_TX] = { "bearer.stats.bytes-tx", "bytes tx", MMC_S_BEARER_STATS, },
@@ -594,6 +595,22 @@ mmcli_output_signal_quality (guint value,
g_strdup_printf ("%s", recent ? "yes" : "no")); g_strdup_printf ("%s", recent ? "yes" : "no"));
} }
/******************************************************************************/
/* (Custom) Bearer start date output */
void
mmcli_output_start_date (guint64 value)
{
/* Merge value and recent flag in a single item in human output */
if (selected_type == MMC_OUTPUT_TYPE_HUMAN) {
output_item_new_take_single (MMC_F_BEARER_STATS_START_DATE, mm_format_iso8601 (value));
return;
}
output_item_new_take_single (MMC_F_BEARER_STATS_START_DATE,
g_strdup_printf ("%" G_GUINT64_FORMAT, value));
}
/******************************************************************************/ /******************************************************************************/
/* (Custom) State output */ /* (Custom) State output */

View File

@@ -266,6 +266,7 @@ typedef enum {
MMC_F_BEARER_IPV6_CONFIG_GATEWAY, MMC_F_BEARER_IPV6_CONFIG_GATEWAY,
MMC_F_BEARER_IPV6_CONFIG_DNS, MMC_F_BEARER_IPV6_CONFIG_DNS,
MMC_F_BEARER_IPV6_CONFIG_MTU, MMC_F_BEARER_IPV6_CONFIG_MTU,
MMC_F_BEARER_STATS_START_DATE,
MMC_F_BEARER_STATS_DURATION, MMC_F_BEARER_STATS_DURATION,
MMC_F_BEARER_STATS_BYTES_RX, MMC_F_BEARER_STATS_BYTES_RX,
MMC_F_BEARER_STATS_BYTES_TX, MMC_F_BEARER_STATS_BYTES_TX,
@@ -367,6 +368,7 @@ void mmcli_output_listitem (MmcF field,
void mmcli_output_signal_quality (guint value, void mmcli_output_signal_quality (guint value,
gboolean recent); gboolean recent);
void mmcli_output_start_date (guint64 value);
void mmcli_output_state (MMModemState state, void mmcli_output_state (MMModemState state,
MMModemStateFailedReason reason); MMModemStateFailedReason reason);
void mmcli_output_sim_slots (gchar **sim_slot_paths, void mmcli_output_sim_slots (gchar **sim_slot_paths,

View File

@@ -309,6 +309,14 @@
<literal>"t"</literal>). <literal>"t"</literal>).
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry><term><literal>"start-date"</literal></term>
<listitem>
Timestamp indicating when the ongoing connection started, given
as an unsigned 64-bit integer value representing seconds
since the epoch (signature <literal>"t"</literal>).
Since 1.20.
</listitem>
</varlistentry>
<varlistentry><term><literal>"duration"</literal></term> <varlistentry><term><literal>"duration"</literal></term>
<listitem> <listitem>
Duration of the ongoing connection, in seconds, given as an Duration of the ongoing connection, in seconds, given as an

View File

@@ -36,6 +36,7 @@ G_DEFINE_TYPE (MMBearerStats, mm_bearer_stats, G_TYPE_OBJECT)
#define PROPERTY_DURATION "duration" #define PROPERTY_DURATION "duration"
#define PROPERTY_RX_BYTES "rx-bytes" #define PROPERTY_RX_BYTES "rx-bytes"
#define PROPERTY_TX_BYTES "tx-bytes" #define PROPERTY_TX_BYTES "tx-bytes"
#define PROPERTY_START_DATE "start-date"
#define PROPERTY_ATTEMPTS "attempts" #define PROPERTY_ATTEMPTS "attempts"
#define PROPERTY_FAILED_ATTEMPTS "failed-attempts" #define PROPERTY_FAILED_ATTEMPTS "failed-attempts"
#define PROPERTY_TOTAL_DURATION "total-duration" #define PROPERTY_TOTAL_DURATION "total-duration"
@@ -46,6 +47,7 @@ struct _MMBearerStatsPrivate {
guint duration; guint duration;
guint64 rx_bytes; guint64 rx_bytes;
guint64 tx_bytes; guint64 tx_bytes;
guint64 start_date;
guint attempts; guint attempts;
guint failed_attempts; guint failed_attempts;
guint total_duration; guint total_duration;
@@ -151,6 +153,39 @@ mm_bearer_stats_set_tx_bytes (MMBearerStats *self,
/*****************************************************************************/ /*****************************************************************************/
/**
* mm_bearer_stats_get_start_date:
* @self: a #MMBearerStats.
*
* Gets the start date of the current connection as a timestamp in seconds
* since the epoch.
*
* Returns: a #guint64.
*
* Since: 1.20
*/
guint64
mm_bearer_stats_get_start_date (MMBearerStats *self)
{
g_return_val_if_fail (MM_IS_BEARER_STATS (self), 0);
return self->priv->start_date;
}
/**
* mm_bearer_stats_set_start_date: (skip)
*/
void
mm_bearer_stats_set_start_date (MMBearerStats *self,
guint64 start_date)
{
g_return_if_fail (MM_IS_BEARER_STATS (self));
self->priv->start_date = start_date;
}
/*****************************************************************************/
/** /**
* mm_bearer_stats_get_attempts: * mm_bearer_stats_get_attempts:
* @self: a #MMBearerStats. * @self: a #MMBearerStats.
@@ -338,6 +373,10 @@ mm_bearer_stats_get_dictionary (MMBearerStats *self)
"{sv}", "{sv}",
PROPERTY_TX_BYTES, PROPERTY_TX_BYTES,
g_variant_new_uint64 (self->priv->tx_bytes)); g_variant_new_uint64 (self->priv->tx_bytes));
g_variant_builder_add (&builder,
"{sv}",
PROPERTY_START_DATE,
g_variant_new_uint64 (self->priv->start_date));
g_variant_builder_add (&builder, g_variant_builder_add (&builder,
"{sv}", "{sv}",
PROPERTY_ATTEMPTS, PROPERTY_ATTEMPTS,
@@ -403,6 +442,10 @@ mm_bearer_stats_new_from_dictionary (GVariant *dictionary,
mm_bearer_stats_set_tx_bytes ( mm_bearer_stats_set_tx_bytes (
self, self,
g_variant_get_uint64 (value)); g_variant_get_uint64 (value));
} else if (g_str_equal (key, PROPERTY_START_DATE)) {
mm_bearer_stats_set_start_date (
self,
g_variant_get_uint64 (value));
} else if (g_str_equal (key, PROPERTY_ATTEMPTS)) { } else if (g_str_equal (key, PROPERTY_ATTEMPTS)) {
mm_bearer_stats_set_attempts ( mm_bearer_stats_set_attempts (
self, self,

View File

@@ -61,6 +61,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMBearerStats, g_object_unref)
guint mm_bearer_stats_get_duration (MMBearerStats *self); guint mm_bearer_stats_get_duration (MMBearerStats *self);
guint64 mm_bearer_stats_get_rx_bytes (MMBearerStats *self); guint64 mm_bearer_stats_get_rx_bytes (MMBearerStats *self);
guint64 mm_bearer_stats_get_tx_bytes (MMBearerStats *self); guint64 mm_bearer_stats_get_tx_bytes (MMBearerStats *self);
guint64 mm_bearer_stats_get_start_date (MMBearerStats *self);
guint mm_bearer_stats_get_attempts (MMBearerStats *self); guint mm_bearer_stats_get_attempts (MMBearerStats *self);
guint mm_bearer_stats_get_failed_attempts (MMBearerStats *self); guint mm_bearer_stats_get_failed_attempts (MMBearerStats *self);
guint mm_bearer_stats_get_total_duration (MMBearerStats *self); guint mm_bearer_stats_get_total_duration (MMBearerStats *self);
@@ -81,6 +82,7 @@ MMBearerStats *mm_bearer_stats_new_from_dictionary (GVariant *dictionary,
void mm_bearer_stats_set_duration (MMBearerStats *self, guint duration); void mm_bearer_stats_set_duration (MMBearerStats *self, guint duration);
void mm_bearer_stats_set_rx_bytes (MMBearerStats *self, guint64 rx_bytes); void mm_bearer_stats_set_rx_bytes (MMBearerStats *self, guint64 rx_bytes);
void mm_bearer_stats_set_tx_bytes (MMBearerStats *self, guint64 tx_bytes); void mm_bearer_stats_set_tx_bytes (MMBearerStats *self, guint64 tx_bytes);
void mm_bearer_stats_set_start_date (MMBearerStats *self, guint64 stats);
void mm_bearer_stats_set_attempts (MMBearerStats *self, guint attempts); void mm_bearer_stats_set_attempts (MMBearerStats *self, guint attempts);
void mm_bearer_stats_set_failed_attempts (MMBearerStats *self, guint failed_attempts); void mm_bearer_stats_set_failed_attempts (MMBearerStats *self, guint failed_attempts);
void mm_bearer_stats_set_total_duration (MMBearerStats *self, guint duration); void mm_bearer_stats_set_total_duration (MMBearerStats *self, guint duration);

View File

@@ -1661,6 +1661,47 @@ mm_get_string_unquoted_from_match_info (GMatchInfo *match_info,
return str; return str;
} }
gchar *
mm_format_iso8601 (guint64 timestamp)
{
gchar *format_date = NULL;
GDateTime *datetime = NULL;
datetime = g_date_time_new_from_unix_utc ((gint64)timestamp);
#if GLIB_CHECK_VERSION (2, 62, 0)
format_date = g_date_time_format_iso8601 (datetime);
#else
{
GString *outstr = NULL;
gchar *main_date = NULL;
gint64 offset = 0;
main_date = g_date_time_format (datetime, "%Y-%m-%dT%H:%M:%S");
outstr = g_string_new (main_date);
g_free (main_date);
/* Timezone. Format it as `%:::z` unless the offset is zero, in which case
* we can simply use `Z`. */
offset = g_date_time_get_utc_offset (datetime);
if (offset == 0) {
g_string_append_c (outstr, 'Z');
} else {
gchar *time_zone;
time_zone = g_date_time_format (datetime, "%:::z");
g_string_append (outstr, time_zone);
g_free (time_zone);
}
format_date = g_string_free (outstr, FALSE);
}
#endif
g_date_time_unref (datetime);
return format_date;
}
/*****************************************************************************/ /*****************************************************************************/
/* From hostap, Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> */ /* From hostap, Copyright (c) 2002-2005, Jouni Malinen <jkmaline@cc.hut.fi> */

View File

@@ -190,6 +190,7 @@ gboolean mm_get_double_from_match_info (GMatchInfo *match_info,
gdouble *out); gdouble *out);
gchar *mm_get_string_unquoted_from_match_info (GMatchInfo *match_info, gchar *mm_get_string_unquoted_from_match_info (GMatchInfo *match_info,
guint32 match_index); guint32 match_index);
gchar *mm_format_iso8601 (guint64 timestamp);
/******************************************************************************/ /******************************************************************************/
/* Type checkers and conversion utilities */ /* Type checkers and conversion utilities */

View File

@@ -314,6 +314,7 @@ bearer_reset_ongoing_interface_stats (MMBaseBearer *self)
mm_bearer_stats_set_duration (self->priv->stats, 0); mm_bearer_stats_set_duration (self->priv->stats, 0);
mm_bearer_stats_set_tx_bytes (self->priv->stats, 0); mm_bearer_stats_set_tx_bytes (self->priv->stats, 0);
mm_bearer_stats_set_rx_bytes (self->priv->stats, 0); mm_bearer_stats_set_rx_bytes (self->priv->stats, 0);
mm_bearer_stats_set_start_date (self->priv->stats, 0);
bearer_update_interface_stats (self); bearer_update_interface_stats (self);
} }
@@ -456,6 +457,9 @@ bearer_stats_start (MMBaseBearer *self)
self->priv->stats_update_id = g_timeout_add_seconds (BEARER_STATS_UPDATE_TIMEOUT, self->priv->stats_update_id = g_timeout_add_seconds (BEARER_STATS_UPDATE_TIMEOUT,
(GSourceFunc) stats_update_cb, (GSourceFunc) stats_update_cb,
self); self);
mm_bearer_stats_set_start_date (self->priv->stats, (guint64)(g_get_real_time() / G_USEC_PER_SEC));
/* Load initial values */ /* Load initial values */
stats_update_cb (self); stats_update_cb (self);
} }