Skip to content

Commit

Permalink
net/netdev: Add periodic log for netdev statistics
Browse files Browse the repository at this point in the history
Work for every network device using `CONFIG_NETDEV_STATISTICS`.

Log style:
<interface>:T{done}/{total},R({v4}+{v6})/{total} {Protocol}:T{tx},R{rx},D{drop}
Example:
wlan0:T10/10,R(10+20)/31 TCP:T0,R0,D0 UDP:T0,R10,D0 ICMP:T0,R0,D0 ICMP6:T0,R0,D0

Signed-off-by: Zhe Weng <[email protected]>
  • Loading branch information
wengzhe authored and xiaoxiang781216 committed Aug 22, 2024
1 parent f5fe764 commit acbddd1
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 2 deletions.
8 changes: 8 additions & 0 deletions drivers/net/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,14 @@ config NETDEV_STATISTICS
Enable to collect statistics from the network drivers (if supported
by the network driver).

config NETDEV_STATISTICS_LOG_PERIOD
int "Network device statistics log period"
default 0
depends on NETDEV_STATISTICS && DEBUG_FEATURES
---help---
Period in seconds to log network device statistics. Zero means
disable logging.

config NET_DUMPPACKET
bool "Enable packet dumping"
depends on DEBUG_FEATURES
Expand Down
51 changes: 49 additions & 2 deletions include/nuttx/net/netdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@
# include <nuttx/net/mld.h>
#endif

#ifndef CONFIG_NETDEV_STATISTICS_LOG_PERIOD
# define CONFIG_NETDEV_STATISTICS_LOG_PERIOD 0
#endif

#if CONFIG_NETDEV_STATISTICS_LOG_PERIOD > 0
# include <nuttx/wqueue.h>
#endif

/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
Expand Down Expand Up @@ -112,7 +120,26 @@
} \
while (0)

# define NETDEV_RXPACKETS(dev) _NETDEV_STATISTIC(dev,rx_packets)
# if CONFIG_NETDEV_STATISTICS_LOG_PERIOD > 0
# define NETDEV_STATISTICS_WORK LPWORK
# define _NETDEV_STATISTIC_LOG(dev,name) \
do \
{ \
_NETDEV_STATISTIC(dev,name); \
if (work_available(&(dev)->d_statistics.logwork)) \
{ \
work_queue(NETDEV_STATISTICS_WORK, \
&(dev)->d_statistics.logwork, \
netdev_statistics_log, (dev), \
SEC2TICK(CONFIG_NETDEV_STATISTICS_LOG_PERIOD)); \
} \
} \
while (0)
# else
# define _NETDEV_STATISTIC_LOG(dev,name) _NETDEV_STATISTIC(dev,name)
# endif

# define NETDEV_RXPACKETS(dev) _NETDEV_STATISTIC_LOG(dev,rx_packets)
# define NETDEV_RXFRAGMENTS(dev) _NETDEV_STATISTIC(dev,rx_fragments)
# define NETDEV_RXERRORS(dev) _NETDEV_ERROR(dev,rx_errors)
# ifdef CONFIG_NET_IPv4
Expand All @@ -132,7 +159,7 @@
# endif
# define NETDEV_RXDROPPED(dev) _NETDEV_STATISTIC(dev,rx_dropped)

# define NETDEV_TXPACKETS(dev) _NETDEV_STATISTIC(dev,tx_packets)
# define NETDEV_TXPACKETS(dev) _NETDEV_STATISTIC_LOG(dev,tx_packets)
# define NETDEV_TXDONE(dev) _NETDEV_STATISTIC(dev,tx_done)
# define NETDEV_TXERRORS(dev) _NETDEV_ERROR(dev,tx_errors)
# define NETDEV_TXTIMEOUTS(dev) _NETDEV_ERROR(dev,tx_timeouts)
Expand Down Expand Up @@ -219,6 +246,10 @@ struct netdev_statistics_s
/* Other status */

uint32_t errors; /* Total number of errors */

#if CONFIG_NETDEV_STATISTICS_LOG_PERIOD > 0
struct work_s logwork; /* For periodic log work */
#endif
};
#endif

Expand Down Expand Up @@ -1196,4 +1227,20 @@ int netdev_ipv6_foreach(FAR struct net_driver_s *dev,
devif_ipv6_callback_t callback, FAR void *arg);
#endif

/****************************************************************************
* Name: netdev_statistics_log
*
* Description:
* The actual implementation of the network statistics logging. Log
* network statistics at regular intervals.
*
* Input Parameters:
* arg - The pointer to the network device
*
****************************************************************************/

#if CONFIG_NETDEV_STATISTICS_LOG_PERIOD > 0
void netdev_statistics_log(FAR void *arg);
#endif

#endif /* __INCLUDE_NUTTX_NET_NETDEV_H */
4 changes: 4 additions & 0 deletions net/netdev/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,8 @@ if(CONFIG_NET_IPv6)
list(APPEND SRCS netdev_ipv6.c)
endif()

if(CONFIG_NETDEV_STATISTICS)
list(APPEND SRCS netdev_stats.c)
endif()

target_sources(net PRIVATE ${SRCS})
4 changes: 4 additions & 0 deletions net/netdev/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ ifeq ($(CONFIG_NET_IPv6),y)
NETDEV_CSRCS += netdev_ipv6.c
endif

ifeq ($(CONFIG_NETDEV_STATISTICS),y)
NETDEV_CSRCS += netdev_stats.c
endif

# Include netdev build support

DEPPATH += --dep-path netdev
Expand Down
99 changes: 99 additions & 0 deletions net/netdev/netdev_stats.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/****************************************************************************
* net/netdev/netdev_stats.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/

/****************************************************************************
* Included Files
****************************************************************************/

#include <nuttx/config.h>

#include <syslog.h>

#include <nuttx/net/netdev.h>
#include <nuttx/net/netstats.h>

/****************************************************************************
* Pre-processor Definitions
****************************************************************************/

#define stats_log(format, ...) syslog(LOG_NOTICE, format, ##__VA_ARGS__)

/****************************************************************************
* Public Functions
****************************************************************************/

/****************************************************************************
* Name: netdev_statistics_log
*
* Description:
* The actual implementation of the network statistics logging. Log
* network statistics at regular intervals.
*
* Input Parameters:
* arg - The pointer to the network device
*
****************************************************************************/

#if CONFIG_NETDEV_STATISTICS_LOG_PERIOD > 0
void netdev_statistics_log(FAR void *arg)
{
FAR struct net_driver_s *dev = arg;
FAR struct netdev_statistics_s *stats = &dev->d_statistics;

stats_log("%s:T%" PRIu32 "/%" PRIu32 ",R"
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
"(%" PRIu32 "+%" PRIu32 ")/"
#endif
"%" PRIu32
#ifdef CONFIG_NET_TCP
" TCP:T%" PRIu16 ",R%" PRIu16 ",D%" PRIu16
#endif
#ifdef CONFIG_NET_UDP
" UDP:T%" PRIu16 ",R%" PRIu16 ",D%" PRIu16
#endif
#ifdef CONFIG_NET_ICMP
" ICMP:T%" PRIu16 ",R%" PRIu16 ",D%" PRIu16
#endif
#ifdef CONFIG_NET_ICMPv6
" ICMP6:T%" PRIu16 ",R%" PRIu16 ",D%" PRIu16
#endif
"\n",
dev->d_ifname, stats->tx_done, stats->tx_packets
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
, stats->rx_ipv4, stats->rx_ipv6
#endif
, stats->rx_packets
#ifdef CONFIG_NET_TCP
, g_netstats.tcp.sent, g_netstats.tcp.recv, g_netstats.tcp.drop
#endif
#ifdef CONFIG_NET_UDP
, g_netstats.udp.sent, g_netstats.udp.recv, g_netstats.udp.drop
#endif
#ifdef CONFIG_NET_ICMP
, g_netstats.icmp.sent, g_netstats.icmp.recv,
g_netstats.icmp.drop
#endif
#ifdef CONFIG_NET_ICMPv6
, g_netstats.icmpv6.sent, g_netstats.icmpv6.recv,
g_netstats.icmpv6.drop
#endif
);
}
#endif
4 changes: 4 additions & 0 deletions net/netdev/netdev_unregister.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ int netdev_unregister(FAR struct net_driver_s *dev)
#endif
net_unlock();

#if CONFIG_NETDEV_STATISTICS_LOG_PERIOD > 0
work_cancel_sync(NETDEV_STATISTICS_WORK, &dev->d_statistics.logwork);
#endif

#ifdef CONFIG_NET_ETHERNET
ninfo("Unregistered MAC: %02x:%02x:%02x:%02x:%02x:%02x as dev: %s\n",
dev->d_mac.ether.ether_addr_octet[0],
Expand Down

0 comments on commit acbddd1

Please sign in to comment.