UTrace
Log and Trace for Embedded System
UTrace is a log and trace system for embedded Linux/Unix based system.
It started initially with the idea of using postprocessing to add the strings in the messages (logs or traces) to reduce the application binary size. With time, additional features like file transfer and syslog client was integrated.
How does it work?
The system is composed of a system daemon utraced which collects all binary data via a dedicated pipe. Currently there is only one pipe in which all clients dump messages, but the concept can be extended to use multile pipes or Unix domain sockets for IPC. External applications can use client libraries and API to log and trace using this system. Currently only C based projects are supported, but this can be extended. Tools are provided to generate the decoders at build time for applications. For each application an unique application id has to be provided (resolved at system build). All tools and parts come with manual pages. The concept can be ported on non-POSIX systems including RTOS.
Highlights
Based on binary decoders with tools to generate and transform decoders
Data serialization based on memory packing (alignment) per frame, each frame splited in the same amount of packets (build time configurable)
A binary trace entry is stored in a packet and the transfer is done once the frame is filled or explicitly flashed
File transfer support to the trace output
Data serialization for data flow out from the target
A simple syslog or text file monitor
Application integration
Each application should define the message entries in an utracedefs.h file which shall be included in all units that use UTrace API for log and trace:
/* Application identification data */
#define UTRACEAPPID 0x01
#define UTRACEAPPNAME "utracetest"
/* Hash IDs go here */
enum {
THREAD_START = 1, THREAD_END, THREAD_LOOP_TID, THREAD_LOOP_DAT, UTRACEENTRYEND
};
/* Hash enties description goes into this table */
#ifdef UTRACEGEN
utentry_t utraceentries[UTRACEENTRYEND] = {
{ THREAD_START, UTRACEAPPID, "Test thread loop starts", "It markes the start of for loop for this test thread", UTRACEAPPNAME },
{ THREAD_END, UTRACEAPPID, "Test thread loop ends", "It markes the end of for loop for this test thread", UTRACEAPPNAME },
{ THREAD_LOOP_TID, UTRACEAPPID, "New loop for thread ID", " ", UTRACEAPPNAME },
{ THREAD_LOOP_DAT, UTRACEAPPID, "User data for current loop", "It is incremented with each loop", UTRACEAPPNAME },
{ UTRACEENTRYEND, UTRACEAPPID, "End message", "This message will not be used for decoding", UTRACEAPPNAME } };
#endif /* UTRACEGEN */
Application can use the trace entry IDs with the trace API:
static void *
tracemsg(void *threadid)
{
...
utrace_add_info(THREAD_START, &tid, sizeof(tid), true);
for (i = 0; i < g_cntloop; i++)
{
...
utrace_add_info(THREAD_LOOP_TID, &tid, sizeof(tid), true);
usleep(g_cntusec);
utrace_add_info(THREAD_LOOP_DAT, &dat, sizeof(dat), true);
usleep(g_cntusec);
}
utrace_add_info(THREAD_END, &tid, sizeof(tid), true);
...
}
int
main(int argc, char *argv[])
{
...
utrace_init(UTRACEAPPID, (uint32_t)getpid());
utrace_settime_cb(&mytime);
utrace_open();
utrace_print("Program start threads");
....
/* start threads */
...
utrace_print("Program end");
utrace_close();
utrace_free();
...
}
Decoders
Decoders can be generated with utracegen tool with utracedefs.h as input:
$ utracegen -f ../application/src/utracedefs.h
The service daemon
The service which collects the traces is utraced and it needs as argument at least the output directory where to save the binary file. It has the option to limit the size of the output or to split the output in multiple files:
$ utraced --output ~/Work/utrace_output
Decoder tools and monitor
A decoder, utracedec and a live monitor application utracemon are provided with the UTrace system:
$ utracemon -a localhost -l ~/Work/utrace_decoders/decoders.list
UTRACEDEC version: v0.1
[ COUNT][TIMESTAMP ][APPID:INSTANCE][PAYLOAD ] APP NAME -> HEADLINE
[00000000][ 10:45:36 2020-01-31 ][fffe:000158e6][000000000000000000000000] utraced -> External monitor connected
[00000001][ 10:46:50 2020-01-31 ][fffd:00015bf2][TEXT ] utrace -> This is a message string example
[00000002][ 10:47:42 2020-01-31 ][fffd:00015c50][TEXT ] utrace -> A binary trace message follows
[00000003][ 10:48:35 2020-01-31 ][fffd:00015cb7][00000000000000000008a992] utrace -> ID 0462
[00000004][ 10:49:31 2020-01-31 ][fffd:00015d15][TEXT ] utrace -> A file transfer to traces will start
[00000005][ 10:49:49 2020-01-31 ][fffe:000041a7][FILE_TRANSFER_START ] FILE -> decoders.list;115
[00000006][ 10:49:49 2020-01-31 ][fffe:000041a7][FILE_TRANSFER_DATA ] FILE -> 572f363538303933712f73726573552f...
[00000007][ 10:49:49 2020-01-31 ][fffe:000041a7][FILE_TRANSFER_END ] FILE -> 115;0
[00000008][ 10:54:03 2020-01-31 ][fffe:000158e6][000000000000000000000000] utraced -> Terminate