[Embedded project from 0 to 1] Implementation of log system

For the log output of embedded development, one is directly output to the standard output, which can be seen through the serial port, and the other is to store the log in the memory file. In general embedded development, the two coexist.

Standard output is output to standard output via the printf() function, or via vfprintf(stdout, format, args).

For the log placed in the file, due to the frequency of the log, a separate thread or process is required to read and write the file, and at the same time, the log file is managed such as size limit and loop coverage.

An implementation is documented below:

Create a log server process that is responsible for collecting the log output sent by other modules.

Message structure:

{ unsigned int Pid;//Module process ID

char logMsg[1020];//The log itself}


sockfd = socket() creates a socket;

bind(sockfd, "/tmp/socket_log"), bind this socket to /tmp/socket_log;

open("/tmp/log.log" "w+"), open the file to which we want to write the log;

while(1)

    recvfrom(sockfd), always listening to sockfd. According to the Pid, ​​execute "ps | grep -w PID | grep -v grep | awk '{print $5}'" to get the process name. In order to reduce the need to obtain the process name in this way every time, create an array, put the PID and PNAME of the process name that have been obtained, and use the PID to find it from the array next time. For the case that the PID of the process changes, in Find in the array whether the PNAME obtained through the command already exists, if so, update the PID value, if not, write it into the array. Record the current number of array elements.

    At this time, we have PNAME, and then obtain the time information through the interface, organize the format, write log.log, then write logMSG, then write "\n", call flush, after the writing is completed, judge totalsize=writensize+ If the size written this time is larger than the limit value we set, such as 1MB, call seek_set 0 to point the file write pointer to the beginning of the file.

In this way, the implementation of the log server process is completed. In general, the msg of each module is received from the socket, the format is encapsulated, and then written to the file, and the size of the current file is recorded. If it is too large, seek to the beginning of the file.

    Look at the log client side again:

The client unified function format_log(_F_, _FU_, _L_, "HELLO %s", "world"); file, function name, line number, message body and format parameters.

The function prototype format_log(char* file, char* func,int line, char* format, ...) is a function of variable length parameters;

va_list args;

va_start(args, format); Through this function, you can get the parameter list after format;

vsprintf(logMsg, format, args);

va_end(args); In this way, all the log information will be sent to the logMsg buff, get the PID of the current process through getpid(), then you can use sendto(client_socket, MSG_DONTWAIT) to send the log information to the log server.

Note that the function format_log function is multiplexed by multiple processes, the memory is not shared, and each process needs to have its own client_socket.

After the message is sent successfully, the standard output is still called, and the log information is sent to the standard output.

va_start(args);

vfprintf(stdout, format, args);

va_end(args);

printf("\n");

In this way, the log written in log.log will also be output to the serial port at the same time.


For the log classification of each module, set a log level for each module, such as ERROR, and judge whether the level parameter is higher than the set log level when printing.

How to print color in serial port:

RED "\033[0;32;31m"    NONE "\033[m" 

#define log_red(format, args...)  printf(RED"%s,%d "fmt NONE"\N", __func__, __LINE__, ##args)

It can be output as a red log in the serial port.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325797229&siteId=291194637