How to properly activate zephyr logs with network syslog backend to work over LTE-M for nrf9160 custom device?
How to properly activate zephyr logs with network syslog backend to work over LTE-M for nrf9160 custom device?
you need to set up the LTE link using the LTE Link Controller (LTE LC) library and enable the logging infrastructure.
Haven't tested this myself but you can do something like this. In your prj.conf, you need to enable the necessary logging and network configurations
CONFIG_LOG=y CONFIG_LOG_BACKEND_NET=y CONFIG_LOG_DEFAULT_LEVEL=4 CONFIG_NET_SOCKETS=y CONFIG_NET_SOCKETS_POSIX_NAMES=y CONFIG_LTE_LINK_CONTROL=y CONFIG_LOG_BACKEND_NET_SERVER="XXXXXXXX" CONFIG_LOG_BACKEND_NET_PORT=514 # Standard syslog port
Use the LTE Link Controller to connect to the network, which is essential for sending logs. The lte_lc_init_and_connect() function is recommended to initialize and connect to the LTE network. Here's a sample code snippet:
#include <modem/lte_lc.h> #include <zephyr/logging/log.h> #include <zephyr/kernel.h> LOG_MODULE_REGISTER(my_app); void lte_connect(void) { int err = lte_lc_init_and_connect(); if (err) { LOG_ERR("Failed to connect to LTE, error: %d", err); return; } LOG_INF("LTE connected successfully"); } void main(void) { LOG_INF("Starting application..."); lte_connect(); // Application logic while (1) { LOG_INF("Running main loop..."); k_sleep(K_SECONDS(10)); } }
To conserve power, you might want to enable Power Saving Mode (PSM) and Extended Discontinuous Reception (eDRX). These modes help reduce power consumption during idle periods, which is important for battery-powered devices operating over LTE-M. You can request these modes with the following LTE Link Controller APIs
lte_lc_psm_req(true);
lte_lc_edrx_req(true);
Once the LTE-M link is established, the syslog backend configured in Zephyr will automatically forward log messages to the syslog server over the LTE-M connection.
Make sure to set an appropriate log level to avoid flooding the LTE-M network with unnecessary debug messages, especially if the connection is metered.
The suggested example does not work. I slightly supplemented the configuration with new options and created a project for nRF9160-DK. The example code has also been tweaked a bit based on the official Zephyr Syslog example.
CONFIG_BUILD_WITH_TFM=n
CONFIG_HEAP_MEM_POOL_SIZE=20480
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_NEWLIB_LIBC_MIN_REQUIRED_HEAP_SIZE=4096
CONFIG_PRINTK=y
CONFIG_SHELL=y
CONFIG_INIT_STACKS=y
CONFIG_THREAD_STACK_INFO=y
CONFIG_KERNEL_SHELL=y
CONFIG_NETWORKING=y
CONFIG_NET_NATIVE=n
CONFIG_NET_OFFLOAD=y
CONFIG_NET_SOCKETS_OFFLOAD=y
CONFIG_NET_DEFAULT_IF_OFFLOAD=y
CONFIG_NET_IPV6=n
CONFIG_NET_IPV4=y
CONFIG_NET_UDP=y
CONFIG_NET_TCP=y
CONFIG_NET_LOG=y
CONFIG_NRF_MODEM_LIB=y
CONFIG_LTE_AUTO_INIT_AND_CONNECT=n
CONFIG_LTE_NETWORK_MODE_LTE_M_NBIOT_GPS=y
CONFIG_LTE_MODE_PREFERENCE_NBIOT=y
CONFIG_LOG_MODE_DEFERRED=y
CONFIG_LOG_BACKEND_NET_AUTOSTART=n
CONFIG_LOG=y
CONFIG_LOG_BACKEND_NET=y
CONFIG_LOG_DEFAULT_LEVEL=4
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_LTE_LINK_CONTROL=y
CONFIG_LOG_BACKEND_NET_SERVER="169.46.82.174:25736"
#include <zephyr.h>
#include <kernel.h>
#include <modem/lte_lc.h>
#include <logging/log.h>
#include <logging/log_backend.h>
#include <logging/log_ctrl.h>
LOG_MODULE_REGISTER(net_syslog_lte, LOG_LEVEL_DBG);
extern const struct log_backend *log_backend_net_get(void);
void begin_syslog(void)
{
LOG_INF("Begin logging to syslog...");
const struct log_backend *log_backend_net = log_backend_net_get();
if (log_backend_net->api->init != NULL) {
log_backend_net->api->init(log_backend_net);
}
log_backend_activate(log_backend_net, NULL);
}
void lte_connect(void)
{
int err = lte_lc_init_and_connect();
if (err)
{
LOG_ERR("Failed to connect to LTE, error: %d", err);
return;
}
LOG_INF("LTE connected successfully");
}
#define SLEEP_BETWEEN_LOG_PRINTS 10 // sec
#define TOTAL_LOG_TIME 30 // sec
void cycle_logs(void)
{
int i, count;
/* Allow some setup time before starting to send data */
k_sleep(K_SECONDS(SLEEP_BETWEEN_LOG_PRINTS));
count = TOTAL_LOG_TIME / SLEEP_BETWEEN_LOG_PRINTS;
i = count;
do
{
LOG_ERR("Error message (%d)", i);
LOG_WRN("Warning message (%d)", i);
LOG_INF("Info message (%d)", i);
LOG_DBG("Debug message (%d)", i);
k_sleep(K_SECONDS(SLEEP_BETWEEN_LOG_PRINTS));
} while (--i);
LOG_DBG("Stopped after %d msg", count);
}
void main(void)
{
LOG_INF("Starting application...");
lte_connect();
begin_syslog();
cycle_logs();
while (1)
{
k_sleep(K_SECONDS(10));
}
}
Unfortunately, debugging didn't clear anything up. But there is a suspicion that the network interface for Syslog through LTE does not work. I tested the official Zephyr example on a device with built-in Ethernet and everything works there.
Hi
Can you upload the syslog and debug log so we can review it here on our end as well, as I'm not able to tell from the .c or .conf files what exactly is wrong here. Can you also share some details on what exactly you have tweaked from the sample project?
Best regards,
Simon
Hi.
Here is complete project.
Build command:
west build --build-dir c:/Users/Andriy/ncs/syslog_net/build c:/Users/Andriy/ncs/syslog_net --pristine --board nrf9160dk_nrf9160_ns -- -DNCS_TOOLCHAIN_VERSION="NONE" -DCONF_FILE="prj.conf" -DCONFIG_DEBUG_OPTIMIZATIONS=y -DCONFIG_DEBUG_THREAD_INFO=y
I am using nRF Connect SDK v2.0.2 on Windows 10.
As for the project tweaking, it mainly concerns the fact that there is no network interface until the network registration takes place, so you have to start the backend manually.
Hi
So, we were able to get this up and running on our end (building for NCS 2.7.0 as v2.0.2 is rather old at this point). Here are the configs and source file used. Also I attached the log:
/* * Copyright (c) 2018 Intel Corporation. * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr/logging/log.h> LOG_MODULE_REGISTER(net_syslog_lte, LOG_LEVEL_DBG); #include <zephyr/kernel.h> #include <zephyr/logging/log_backend.h> #include <zephyr/logging/log_backend_net.h> #include <zephyr/logging/log_ctrl.h> #include <modem/lte_lc.h> #include <modem/nrf_modem_lib.h> #include <stdlib.h> BUILD_ASSERT(IS_ENABLED(CONFIG_LOG_BACKEND_NET), "syslog backend not enabled"); #define SLEEP_BETWEEN_PRINTS 3 extern const struct log_backend *log_backend_net_get(void); void begin_syslog(void) { LOG_INF("Begin logging to syslog..."); const struct log_backend *log_backend_net = log_backend_net_get(); if (log_backend_net->api->init != NULL) { log_backend_net->api->init(log_backend_net); } log_backend_activate(log_backend_net, NULL); } static int set_normal_mode(void) { int err; printk("Setting modem to normal mode...\n"); err = lte_lc_func_mode_set(LTE_LC_FUNC_MODE_NORMAL); if (err) { return err; } printk("Normal mode set.\n"); return 0; } void lte_connect(void) { // set_normal_mode(); int err = lte_lc_connect(); if (err) { LOG_ERR("Failed to connect to LTE, error: %d", err); return; } LOG_INF("LTE connected successfully"); } #define SLEEP_BETWEEN_LOG_PRINTS 10 // sec #define TOTAL_LOG_TIME 30 // sec void cycle_logs(void) { int i, count; /* Allow some setup time before starting to send data */ k_sleep(K_SECONDS(SLEEP_BETWEEN_LOG_PRINTS)); count = TOTAL_LOG_TIME / SLEEP_BETWEEN_LOG_PRINTS; i = count; do { LOG_ERR("Error message (%d)", i); LOG_WRN("Warning message (%d)", i); LOG_INF("Info message (%d)", i); LOG_DBG("Debug message (%d)", i); k_sleep(K_SECONDS(SLEEP_BETWEEN_LOG_PRINTS)); } while (--i); LOG_DBG("Stopped after %d msg", count); } void main(void) { int err; LOG_INF("Starting application..."); printk("Initializing modem library\n"); err = nrf_modem_lib_init(); if (err) { printk("Modem initialization failed, err %d\n", err); return err; } lte_connect(); begin_syslog(); cycle_logs(); while (1) { k_sleep(K_SECONDS(10)); } }
CONFIG_NCS_SAMPLES_DEFAULTS=y # Modem library CONFIG_NRF_MODEM_LIB=y # LTE link control CONFIG_LTE_LINK_CONTROL=y CONFIG_LTE_NETWORK_MODE_LTE_M=y # CONFIG_ENTROPY_GENERATOR=y # CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_INIT_STACKS=y CONFIG_NET_PKT_RX_COUNT=32 CONFIG_NET_PKT_TX_COUNT=32 CONFIG_NET_BUF_RX_COUNT=32 CONFIG_NET_BUF_TX_COUNT=32 CONFIG_NET_SOCKETS=y CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=3 CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=5 CONFIG_NET_LOG=y CONFIG_LOG=y CONFIG_NETWORKING=y CONFIG_NET_NATIVE=n CONFIG_NET_OFFLOAD=y CONFIG_NET_SOCKETS_OFFLOAD=y CONFIG_NET_DEFAULT_IF_OFFLOAD=y CONFIG_NET_IPV6=n CONFIG_NET_IPV4=y CONFIG_NET_UDP=y CONFIG_NET_TCP=y CONFIG_NET_LOG=y # Deferred mode is required, synchronous mode does not work with network syslog # as it would cause the sent packet to be malformed (contains only 1 byte data) CONFIG_LOG_MODE_DEFERRED=y CONFIG_NET_IPV6=n CONFIG_NET_IPV4=y CONFIG_NET_DHCPV4=n # CONFIG_NET_SHELL=y CONFIG_NET_CONFIG_SETTINGS=y CONFIG_NET_CONFIG_NEED_IPV6=n CONFIG_NET_CONFIG_NEED_IPV4=y # CONFIG_NET_CONFIG_MY_IPV6_ADDR="2001:db8::1" # CONFIG_NET_CONFIG_PEER_IPV6_ADDR="2001:db8::2" # CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" # CONFIG_NET_CONFIG_PEER_IPV4_ADDR="192.0.2.2" # logging net backend config CONFIG_LOG_BACKEND_NET=y CONFIG_LOG_BACKEND_NET_SERVER="169.46.82.174:25736" # Get a proper libc by default in order to get working time function support CONFIG_REQUIRES_FULL_LIBC=y
*** Booting nRF Connect SDK v2.7.0-5cb85570ca43 *** *** Using Zephyr OS v3.6.99-100befc70c74 *** [00:00:00.414,154] <wrn> net_config: No auto-started network interface - network-bound app initialization skipped. [00:00:00.414,184] <inf> net_syslog_lte: Starting application... Initializing modem library [00:00:04.194,976] <inf> net_syslog_lte: LTE connected successfully [00:00:04.195,037] <inf> net_syslog_lte: Begin logging to syslog... [00:00:14.195,159] <err> net_syslog_lte: Error message (3) [00:00:14.195,190] <wrn> net_syslog_lte: Warning message (3) [00:00:14.195,190] <inf> net_syslog_lte: Info message (3) [00:00:14.195,220] <dbg> net_syslog_lte: cycle_logs: Debug message (3) [00:00:24.195,312] <err> net_syslog_lte: Error message (2) [00:00:24.195,343] <wrn> net_syslog_lte: Warning message (2) [00:00:24.195,343] <inf> net_syslog_lte: Info message (2) [00:00:24.195,373] <dbg> net_syslog_lte: cycle_logs: Debug message (2) [00:00:34.195,465] <err> net_syslog_lte: Error message (1) [00:00:34.195,495] <wrn> net_syslog_lte: Warning message (1) [00:00:34.195,495] <inf> net_syslog_lte: Info message (1) [00:00:34.195,526] <dbg> net_syslog_lte: cycle_logs: Debug message (1) [00:00:44.195,617] <dbg> net_syslog_lte: cycle_logs: Stopped after 3 msg
Best regards,
Simon