[component] Add ulog logger basic component.
This commit is contained in:
parent
7fd434e2f7
commit
12a803bcc9
|
@ -46,4 +46,184 @@ config RT_USING_RYM
|
|||
bool "Enable Ymodem"
|
||||
default n
|
||||
|
||||
config RT_USING_ULOG
|
||||
bool "Enable ulog"
|
||||
default n
|
||||
|
||||
if RT_USING_ULOG
|
||||
if !ULOG_USING_SYSLOG
|
||||
choice
|
||||
prompt "The static output log level."
|
||||
default ULOG_OUTPUT_LVL_DEBUG
|
||||
help
|
||||
When the log level is less than this option and it will stop output.
|
||||
These log will not compile into ROM when using LOG_X api.
|
||||
NOTE: It's not available on syslog mode.
|
||||
config ULOG_OUTPUT_LVL_ASSERT
|
||||
bool "Assert"
|
||||
config ULOG_OUTPUT_LVL_ERROR
|
||||
bool "Error"
|
||||
config ULOG_OUTPUT_LVL_WARNING
|
||||
bool "Warning"
|
||||
config ULOG_OUTPUT_LVL_INFO
|
||||
bool "Information"
|
||||
config ULOG_OUTPUT_LVL_DEBUG
|
||||
bool "Debug"
|
||||
endchoice
|
||||
endif
|
||||
|
||||
if ULOG_USING_SYSLOG
|
||||
choice
|
||||
prompt "The static output log level."
|
||||
default ULOG_OUTPUT_LVL_DEBUG
|
||||
help
|
||||
When the log level is less than this option and it will stop output.
|
||||
These log will not compile into ROM when using LOG_X api.
|
||||
NOTE: It's not available on syslog mode.
|
||||
config ULOG_OUTPUT_LVL_EMERG
|
||||
bool "EMERG"
|
||||
config ULOG_OUTPUT_LVL_ALERT
|
||||
bool "ALERT"
|
||||
config ULOG_OUTPUT_LVL_CRIT
|
||||
bool "CRIT"
|
||||
config ULOG_OUTPUT_LVL_ERROR
|
||||
bool "ERR"
|
||||
config ULOG_OUTPUT_LVL_WARNING
|
||||
bool "WARNING"
|
||||
config ULOG_OUTPUT_LVL_NOTICE
|
||||
bool "NOTICE"
|
||||
config ULOG_OUTPUT_LVL_INFO
|
||||
bool "INFO"
|
||||
config ULOG_OUTPUT_LVL_DEBUG
|
||||
bool "DEBUG"
|
||||
endchoice
|
||||
endif
|
||||
|
||||
config ULOG_OUTPUT_LVL
|
||||
int
|
||||
default 0 if ULOG_OUTPUT_LVL_ASSERT
|
||||
default 0 if ULOG_OUTPUT_LVL_EMERG
|
||||
default 1 if ULOG_OUTPUT_LVL_ALERT
|
||||
default 2 if ULOG_OUTPUT_LVL_CRIT
|
||||
default 3 if ULOG_OUTPUT_LVL_ERROR
|
||||
default 4 if ULOG_OUTPUT_LVL_WARNING
|
||||
default 5 if ULOG_OUTPUT_LVL_NOTICE
|
||||
default 6 if ULOG_OUTPUT_LVL_INFO
|
||||
default 7 if ULOG_OUTPUT_LVL_DEBUG
|
||||
default 7
|
||||
|
||||
config ULOG_USING_ISR_LOG
|
||||
bool "Enable ISR log."
|
||||
default n
|
||||
help
|
||||
The log output API can using in ISR (Interrupt Service Routines) also.
|
||||
|
||||
config ULOG_ASSERT_ENABLE
|
||||
bool "Enable assert check."
|
||||
default y
|
||||
|
||||
config ULOG_LINE_BUF_SIZE
|
||||
int "The log's max width."
|
||||
default 128
|
||||
help
|
||||
The buffer size for every line log.
|
||||
|
||||
config ULOG_USING_ASYNC_OUTPUT
|
||||
bool "Enable async output mode."
|
||||
default n
|
||||
help
|
||||
When enable asynchronous output mode. The log output is not immediately and the log will stored to buffer.
|
||||
The another thread (Such as idle) will read the buffer and output the log. So it will using more RAM.
|
||||
|
||||
if ULOG_USING_ASYNC_OUTPUT
|
||||
config ULOG_ASYNC_OUTPUT_BUF_SIZE
|
||||
int "The async output buffer size."
|
||||
default 2048
|
||||
|
||||
config ULOG_ASYNC_OUTPUT_BY_THREAD
|
||||
bool "Enable async output by thread."
|
||||
default y
|
||||
help
|
||||
This thread will output the asynchronous logs. The logs can output by other user thread when this option is disable.
|
||||
|
||||
if ULOG_ASYNC_OUTPUT_BY_THREAD
|
||||
|
||||
config ULOG_ASYNC_OUTPUT_THREAD_STACK
|
||||
int "The async output thread stack size."
|
||||
default 1024
|
||||
|
||||
config ULOG_ASYNC_OUTPUT_THREAD_PRIORITY
|
||||
int "The async output thread stack priority."
|
||||
range 0 RT_THREAD_PRIORITY_MAX
|
||||
default 30
|
||||
|
||||
endif
|
||||
endif
|
||||
|
||||
menu "log format"
|
||||
config ULOG_OUTPUT_FLOAT
|
||||
bool "Enable float number support."
|
||||
select RT_USING_LIBC
|
||||
default n
|
||||
help
|
||||
The default formater is using rt_vsnprint and it not supported float number.
|
||||
When enable this option then it will enable libc. The formater will change to vsnprint on libc.
|
||||
|
||||
if !ULOG_USING_SYSLOG
|
||||
config ULOG_USING_COLOR
|
||||
bool "Enable color log."
|
||||
default y
|
||||
help
|
||||
The log will has different color by level.
|
||||
endif
|
||||
|
||||
config ULOG_OUTPUT_TIME
|
||||
bool "Enable time information."
|
||||
default y
|
||||
|
||||
config ULOG_TIME_USING_TIMESTAMP
|
||||
bool "Enable timestamp format for time."
|
||||
default n
|
||||
select RT_USING_LIBC
|
||||
depends on ULOG_OUTPUT_TIME
|
||||
|
||||
config ULOG_OUTPUT_LEVEL
|
||||
bool "Enable level information."
|
||||
default y
|
||||
|
||||
config ULOG_OUTPUT_TAG
|
||||
bool "Enable tag information."
|
||||
default y
|
||||
|
||||
config ULOG_OUTPUT_THREAD_NAME
|
||||
bool "Enable thread information."
|
||||
default n
|
||||
endmenu
|
||||
|
||||
config ULOG_BACKEND_USING_CONSOLE
|
||||
bool "Enable console backend."
|
||||
default y
|
||||
help
|
||||
The low level output using rt_kprintf().
|
||||
|
||||
config ULOG_USING_FILTER
|
||||
bool "Enable runtime log filter."
|
||||
default n
|
||||
help
|
||||
It will enable the log filter.
|
||||
Such as level filter, log tag filter, log kw filter and tag's level filter.
|
||||
|
||||
config ULOG_USING_SYSLOG
|
||||
bool "Enable syslog format log and API."
|
||||
select ULOG_OUTPUT_TIME
|
||||
select ULOG_USING_FILTER
|
||||
default n
|
||||
|
||||
config ULOG_SW_VERSION_NUM
|
||||
int
|
||||
default 0x00100
|
||||
help
|
||||
sfotware module version number
|
||||
endif
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c')
|
||||
path = [cwd]
|
||||
|
||||
if GetDepend('ULOG_BACKEND_USING_CONSOLE'):
|
||||
src += ['backend/console_be.c']
|
||||
|
||||
if GetDepend('ULOG_USING_SYSLOG'):
|
||||
path += [cwd + '/syslog']
|
||||
src += Glob('syslog/*.c')
|
||||
|
||||
group = DefineGroup('Utilities', src, depend = ['RT_USING_ULOG'], CPPPATH = path)
|
||||
|
||||
Return('group')
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-09-04 armink the first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <ulog.h>
|
||||
|
||||
#ifdef ULOG_BACKEND_USING_CONSOLE
|
||||
|
||||
#if defined(ULOG_ASYNC_OUTPUT_BY_THREAD) && ULOG_ASYNC_OUTPUT_THREAD_STACK < 384
|
||||
#error "The thread stack size must more than 384 when using async output by thread (ULOG_ASYNC_OUTPUT_BY_THREAD)"
|
||||
#endif
|
||||
|
||||
static struct ulog_backend console;
|
||||
|
||||
void ulog_console_backend_output(struct ulog_backend *backend, rt_uint32_t level, const char *tag, rt_bool_t is_raw,
|
||||
const char *log, size_t len)
|
||||
{
|
||||
rt_device_t dev = rt_console_get_device();
|
||||
|
||||
#ifdef RT_USING_DEVICE
|
||||
if (dev == RT_NULL)
|
||||
{
|
||||
rt_hw_console_output(log);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_uint16_t old_flag = dev->open_flag;
|
||||
|
||||
dev->open_flag |= RT_DEVICE_FLAG_STREAM;
|
||||
rt_device_write(dev, 0, log, len);
|
||||
dev->open_flag = old_flag;
|
||||
}
|
||||
#else
|
||||
rt_hw_console_output(log);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
int ulog_console_backend_init(void)
|
||||
{
|
||||
console.output = ulog_console_backend_output;
|
||||
|
||||
ulog_backend_register(&console, "console", RT_TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_COMPONENT_EXPORT(ulog_console_backend_init);
|
||||
|
||||
#endif /* ULOG_BACKEND_USING_CONSOLE */
|
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-09-07 armink the first version
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <ulog.h>
|
||||
#include <rthw.h>
|
||||
#include "syslog.h"
|
||||
|
||||
#ifdef ULOG_OUTPUT_FLOAT
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* reference:
|
||||
* http://pubs.opengroup.org/onlinepubs/7908799/xsh/syslog.h.html
|
||||
* https://www.gnu.org/software/libc/manual/html_node/Submitting-Syslog-Messages.html
|
||||
* http://man7.org/linux/man-pages/man3/syslog.3.html
|
||||
*/
|
||||
|
||||
#ifdef ULOG_USING_SYSLOG
|
||||
|
||||
#ifndef ULOG_SYSLOG_IDENT_MAX_LEN
|
||||
#define ULOG_SYSLOG_IDENT_MAX_LEN ULOG_FILTER_TAG_MAX_LEN
|
||||
#endif
|
||||
|
||||
static char local_ident[ULOG_SYSLOG_IDENT_MAX_LEN + 1];
|
||||
static int local_facility = LOG_USER;
|
||||
static int local_option = LOG_USER;
|
||||
static rt_bool_t is_open = RT_FALSE;
|
||||
|
||||
/**
|
||||
* open connection to syslog
|
||||
*
|
||||
* @param ident is an arbitrary identification string which future syslog invocations will prefix to each message.
|
||||
* @param option is not using on ulog.
|
||||
* @param facility is the default facility code for this connection.
|
||||
*/
|
||||
void openlog(const char *ident, int option, int facility)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
ulog_init();
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
|
||||
rt_memset(local_ident, 0, sizeof(local_ident));
|
||||
if (ident)
|
||||
{
|
||||
rt_strncpy(local_ident, ident, ULOG_SYSLOG_IDENT_MAX_LEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_strncpy(local_ident, "rtt", ULOG_SYSLOG_IDENT_MAX_LEN);
|
||||
}
|
||||
|
||||
local_option = option;
|
||||
|
||||
if (facility)
|
||||
{
|
||||
local_facility = facility;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* default facility is LOG_USER */
|
||||
local_facility = LOG_USER;
|
||||
}
|
||||
/* output all level log */
|
||||
setlogmask(LOG_UPTO(LOG_DEBUG));
|
||||
|
||||
is_open = RT_TRUE;
|
||||
|
||||
rt_hw_interrupt_enable(level);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This is functionally identical to syslog.
|
||||
*
|
||||
* @param priority log priority, can be generated by the macro LOG_MAKEPRI
|
||||
* @param format log format
|
||||
* @param args log arguments
|
||||
*/
|
||||
void vsyslog(int priority, const char *format, va_list args)
|
||||
{
|
||||
if (LOG_FAC(priority) == 0)
|
||||
{
|
||||
/* using local facility */
|
||||
priority |= local_facility;
|
||||
}
|
||||
|
||||
ulog_voutput(priority, local_ident, format, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* generates a log message
|
||||
*
|
||||
* @param priority log priority, can be generated by the macro LOG_MAKEPRI
|
||||
* @param format log format, like printf()
|
||||
*/
|
||||
void syslog(int priority, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
if (!is_open)
|
||||
{
|
||||
openlog(0, 0, 0);
|
||||
}
|
||||
/* args point to the first variable parameter */
|
||||
va_start(args, format);
|
||||
|
||||
vsyslog(priority, format, args);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* close the syslog
|
||||
*/
|
||||
void closelog(void)
|
||||
{
|
||||
ulog_deinit();
|
||||
|
||||
is_open = RT_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* set log priority mask
|
||||
*
|
||||
* @param mask The log priority mask which generate by macro LOG_MASK and LOG_UPTO.
|
||||
*
|
||||
* @return This function returns the previous log priority mask.
|
||||
*/
|
||||
int setlogmask(int mask)
|
||||
{
|
||||
static int old_mask = 0;
|
||||
int return_mask = old_mask;
|
||||
|
||||
ulog_tag_lvl_filter_set(local_ident, mask);
|
||||
|
||||
old_mask = mask;
|
||||
|
||||
return return_mask;
|
||||
}
|
||||
|
||||
static const char *get_month_str(uint8_t month)
|
||||
{
|
||||
switch(month)
|
||||
{
|
||||
case 1: return "Jan";
|
||||
case 2: return "Feb";
|
||||
case 3: return "Mar";
|
||||
case 4: return "Apr";
|
||||
case 5: return "May";
|
||||
case 6: return "June";
|
||||
case 7: return "July";
|
||||
case 8: return "Aug";
|
||||
case 9: return "Sept";
|
||||
case 10: return "Oct";
|
||||
case 11: return "Nov";
|
||||
case 12: return "Dec";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
RT_WEAK rt_size_t syslog_formater(char *log_buf, int level, const char *tag, const char *format, va_list args)
|
||||
{
|
||||
extern size_t ulog_strcpy(size_t cur_len, char *dst, const char *src);
|
||||
|
||||
rt_size_t log_len = 0, newline_len = rt_strlen(ULOG_NEWLINE_SIGN);
|
||||
int fmt_result;
|
||||
|
||||
RT_ASSERT(log_buf);
|
||||
RT_ASSERT(LOG_PRI(level) <= LOG_DEBUG);
|
||||
RT_ASSERT(tag);
|
||||
RT_ASSERT(format);
|
||||
|
||||
/* add time and priority (level) info */
|
||||
{
|
||||
time_t now = time(RT_NULL);
|
||||
struct tm *tm, tm_tmp;
|
||||
|
||||
tm = gmtime_r(&now, &tm_tmp);
|
||||
|
||||
#ifdef ULOG_OUTPUT_LEVEL
|
||||
rt_snprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE - log_len, "<%d>%s%3d %02d:%02d:%02d", level,
|
||||
get_month_str(tm->tm_mon + 1), tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, rt_tick_get() % 1000);
|
||||
#else
|
||||
rt_snprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE - log_len, "%s%3d %02d:%02d:%02d",
|
||||
get_month_str(tm->tm_mon + 1), tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, rt_tick_get() % 1000);
|
||||
#endif /* ULOG_OUTPUT_LEVEL */
|
||||
|
||||
log_len += rt_strlen(log_buf + log_len);
|
||||
}
|
||||
|
||||
#ifdef ULOG_OUTPUT_TAG
|
||||
/* add identification (tag) info */
|
||||
{
|
||||
log_len += ulog_strcpy(log_len, log_buf + log_len, " ");
|
||||
log_len += ulog_strcpy(log_len, log_buf + log_len, tag);
|
||||
}
|
||||
#endif /* ULOG_OUTPUT_TAG */
|
||||
|
||||
#ifdef ULOG_OUTPUT_THREAD_NAME
|
||||
/* add thread info */
|
||||
{
|
||||
log_len += ulog_strcpy(log_len, log_buf + log_len, " ");
|
||||
/* is not in interrupt context */
|
||||
if (rt_interrupt_get_nest() == 0)
|
||||
{
|
||||
log_len += ulog_strcpy(log_len, log_buf + log_len, rt_thread_self()->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_len += ulog_strcpy(log_len, log_buf + log_len, "ISR");
|
||||
}
|
||||
}
|
||||
#endif /* ULOG_OUTPUT_THREAD_NAME */
|
||||
|
||||
log_len += ulog_strcpy(log_len, log_buf + log_len, ": ");
|
||||
|
||||
#ifdef ULOG_OUTPUT_FLOAT
|
||||
fmt_result = vsnprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE - log_len, format, args);
|
||||
#else
|
||||
fmt_result = rt_vsnprintf(log_buf + log_len, ULOG_LINE_BUF_SIZE - log_len, format, args);
|
||||
#endif /* ULOG_OUTPUT_FLOAT */
|
||||
|
||||
/* calculate log length */
|
||||
if ((log_len + fmt_result <= ULOG_LINE_BUF_SIZE) && (fmt_result > -1))
|
||||
{
|
||||
log_len += fmt_result;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* using max length */
|
||||
log_len = ULOG_LINE_BUF_SIZE;
|
||||
}
|
||||
|
||||
/* overflow check and reserve some space for newline sign */
|
||||
if (log_len + newline_len > ULOG_LINE_BUF_SIZE)
|
||||
{
|
||||
/* using max length */
|
||||
log_len = ULOG_LINE_BUF_SIZE;
|
||||
/* reserve some space for newline sign */
|
||||
log_len -= newline_len;
|
||||
}
|
||||
|
||||
/* package newline sign */
|
||||
log_len += ulog_strcpy(log_len, log_buf + log_len, ULOG_NEWLINE_SIGN);
|
||||
|
||||
return log_len;
|
||||
}
|
||||
|
||||
#endif /* ULOG_USING_SYSLOG */
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-09-07 armink the first version
|
||||
*/
|
||||
|
||||
#ifndef _SYSLOG_H_
|
||||
#define _SYSLOG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* priorities/facilities are encoded into a single 32-bit quantity, where the
|
||||
* bottom 3 bits are the priority (0-7) and the top 28 bits are the facility
|
||||
* (0-big number). Both the priorities and the facilities map roughly
|
||||
* one-to-one to strings in the syslogd(8) source code. This mapping is
|
||||
* included in this file.
|
||||
*
|
||||
* priorities (these are ordered)
|
||||
*/
|
||||
#define LOG_EMERG 0 /* system is unusable */
|
||||
#define LOG_ALERT 1 /* action must be taken immediately */
|
||||
#define LOG_CRIT 2 /* critical conditions */
|
||||
#define LOG_ERR 3 /* error conditions */
|
||||
#define LOG_WARNING 4 /* warning conditions */
|
||||
#define LOG_NOTICE 5 /* normal but significant condition */
|
||||
#define LOG_INFO 6 /* informational */
|
||||
#define LOG_DEBUG 7 /* debug-level messages */
|
||||
|
||||
#define LOG_PRIMASK 0x07
|
||||
|
||||
#define LOG_PRI(p) ((p) & LOG_PRIMASK)
|
||||
#define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri))
|
||||
|
||||
/* facility codes */
|
||||
#define LOG_KERN (0<<3) /* kernel messages */
|
||||
#define LOG_USER (1<<3) /* random user-level messages */
|
||||
#define LOG_MAIL (2<<3) /* mail system */
|
||||
#define LOG_DAEMON (3<<3) /* system daemons */
|
||||
#define LOG_AUTH (4<<3) /* security/authorization messages */
|
||||
#define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */
|
||||
#define LOG_LPR (6<<3) /* line printer subsystem */
|
||||
#define LOG_NEWS (7<<3) /* network news subsystem */
|
||||
#define LOG_UUCP (8<<3) /* UUCP subsystem */
|
||||
#define LOG_CRON (9<<3) /* clock daemon */
|
||||
#define LOG_AUTHPRIV (10<<3) /* security/authorization messages (private) */
|
||||
|
||||
/* other codes through 15 reserved for system use */
|
||||
#define LOG_LOCAL0 (16<<3) /* reserved for local use */
|
||||
#define LOG_LOCAL1 (17<<3) /* reserved for local use */
|
||||
#define LOG_LOCAL2 (18<<3) /* reserved for local use */
|
||||
#define LOG_LOCAL3 (19<<3) /* reserved for local use */
|
||||
#define LOG_LOCAL4 (20<<3) /* reserved for local use */
|
||||
#define LOG_LOCAL5 (21<<3) /* reserved for local use */
|
||||
#define LOG_LOCAL6 (22<<3) /* reserved for local use */
|
||||
#define LOG_LOCAL7 (23<<3) /* reserved for local use */
|
||||
|
||||
#define LOG_NFACILITIES 24 /* current number of facilities */
|
||||
#define LOG_FACMASK 0x03f8 /* mask to extract facility part */
|
||||
/* facility of pri */
|
||||
#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3)
|
||||
|
||||
/*
|
||||
* arguments to setlogmask.
|
||||
*/
|
||||
#define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */
|
||||
#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) /* all priorities through pri */
|
||||
|
||||
/*
|
||||
* Option flags for openlog.
|
||||
*
|
||||
* LOG_ODELAY no longer does anything.
|
||||
* LOG_NDELAY is the inverse of what it used to be.
|
||||
*/
|
||||
#define LOG_PID 0x01 /* log the pid with each message */
|
||||
#define LOG_CONS 0x02 /* log on the console if errors in sending */
|
||||
#define LOG_ODELAY 0x04 /* delay open until first syslog() (default) */
|
||||
#define LOG_NDELAY 0x08 /* don't delay open */
|
||||
#define LOG_NOWAIT 0x10 /* don't wait for console forks: DEPRECATED */
|
||||
#define LOG_PERROR 0x20 /* log to stderr as well */
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
void closelog(void);
|
||||
void openlog(const char *ident, int option, int facility);
|
||||
int setlogmask(int mask);
|
||||
void syslog(int priority, const char *format, ...);
|
||||
void vsyslog(int priority, const char *format, va_list args);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYSLOG_H_ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-08-25 armink the first version
|
||||
*/
|
||||
|
||||
#ifndef _ULOG_H_
|
||||
#define _ULOG_H_
|
||||
|
||||
#include <rtthread.h>
|
||||
#include "ulog_def.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ULOG_VERSION_STR "0.1.0"
|
||||
|
||||
/*
|
||||
* ulog init and deint
|
||||
*/
|
||||
int ulog_init(void);
|
||||
void ulog_deinit(void);
|
||||
|
||||
/*
|
||||
* output different level log by LOG_X API
|
||||
*
|
||||
* NOTE: The `LOG_TAG` and `LOG_LVL` must be defined before including the <ulog.h> when you want to use LOG_X API.
|
||||
*
|
||||
* #define LOG_TAG "example"
|
||||
* #define LOG_LVL LOG_LVL_DBG
|
||||
* #include <ulog.h>
|
||||
*
|
||||
* Then you can using LOG_X API to output log
|
||||
*
|
||||
* LOG_D("this is a debug log!");
|
||||
* LOG_E("this is a error log!");
|
||||
*/
|
||||
#define LOG_E(...) ulog_e(LOG_TAG, __VA_ARGS__)
|
||||
#define LOG_W(...) ulog_w(LOG_TAG, __VA_ARGS__)
|
||||
#define LOG_I(...) ulog_i(LOG_TAG, __VA_ARGS__)
|
||||
#define LOG_D(...) ulog_d(LOG_TAG, __VA_ARGS__)
|
||||
#define LOG_RAW(...) ulog_raw(__VA_ARGS__)
|
||||
|
||||
/*
|
||||
* backend register and unregister
|
||||
*/
|
||||
rt_err_t ulog_backend_register(ulog_backend_t backend, const char *name, rt_bool_t support_color);
|
||||
rt_err_t ulog_backend_unregister(ulog_backend_t backend);
|
||||
|
||||
#ifdef ULOG_USING_FILTER
|
||||
/*
|
||||
* log filter setting
|
||||
*/
|
||||
int ulog_tag_lvl_filter_set(const char *tag, rt_uint32_t level);
|
||||
rt_uint32_t ulog_tag_lvl_filter_get(const char *tag);
|
||||
void ulog_global_filter_lvl_set(rt_uint32_t level);
|
||||
void ulog_global_filter_tag_set(const char *tag);
|
||||
void ulog_global_filter_kw_set(const char *keyword);
|
||||
#endif /* ULOG_USING_FILTER */
|
||||
|
||||
/*
|
||||
* flush all backends's log
|
||||
*/
|
||||
void ulog_flush(void);
|
||||
|
||||
#ifdef ULOG_USING_ASYNC_OUTPUT
|
||||
/*
|
||||
* asynchronous output API
|
||||
*/
|
||||
void ulog_async_output(void);
|
||||
void ulog_async_waiting_log(rt_int32_t time);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* dump the hex format data to log
|
||||
*/
|
||||
void ulog_hexdump(const char *name, rt_size_t width, rt_uint8_t *buf, rt_size_t size);
|
||||
|
||||
/*
|
||||
* Another log output API. This API is difficult to use than LOG_X API.
|
||||
*/
|
||||
void ulog_voutput(rt_uint32_t level, const char *tag, const char *format, va_list args);
|
||||
void ulog_output(rt_uint32_t level, const char *tag, const char *format, ...);
|
||||
void ulog_raw(const char *format, ...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ULOG_H_ */
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-08-25 armink the first version
|
||||
*/
|
||||
#ifndef _ULOG_DEF_H_
|
||||
#define _ULOG_DEF_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* logger level, the number is compatible for syslog */
|
||||
#define LOG_LVL_ASSERT 0
|
||||
#define LOG_LVL_ERROR 3
|
||||
#define LOG_LVL_WARNING 4
|
||||
#define LOG_LVL_INFO 6
|
||||
#define LOG_LVL_DBG 7
|
||||
|
||||
/* the output silent level and all level for filter setting */
|
||||
#ifndef ULOG_USING_SYSLOG
|
||||
#define LOG_FILTER_LVL_SILENT 0
|
||||
#define LOG_FILTER_LVL_ALL 7
|
||||
#else
|
||||
#define LOG_FILTER_LVL_SILENT 1
|
||||
#define LOG_FILTER_LVL_ALL 255
|
||||
#endif /* ULOG_USING_SYSLOG */
|
||||
|
||||
/* compatible for rtdbg */
|
||||
#undef LOG_D
|
||||
#undef LOG_I
|
||||
#undef LOG_W
|
||||
#undef LOG_E
|
||||
#undef LOG_RAW
|
||||
#undef DBG_ERROR
|
||||
#undef DBG_WARNING
|
||||
#undef DBG_INFO
|
||||
#undef DBG_LOG
|
||||
#define DBG_ERROR LOG_LVL_ERROR
|
||||
#define DBG_WARNING LOG_LVL_WARNING
|
||||
#define DBG_INFO LOG_LVL_INFO
|
||||
#define DBG_LOG LOG_LVL_DBG
|
||||
|
||||
#if !defined(LOG_TAG)
|
||||
/* compatible for rtdbg */
|
||||
#if defined(DBG_SECTION_NAME)
|
||||
#define LOG_TAG DBG_SECTION_NAME
|
||||
#else
|
||||
#define LOG_TAG "NO_TAG"
|
||||
#endif
|
||||
#endif /* !defined(LOG_TAG) */
|
||||
|
||||
#if !defined(LOG_LVL)
|
||||
/* compatible for rtdbg */
|
||||
#if defined(DBG_LEVEL)
|
||||
#define LOG_LVL DBG_LEVEL
|
||||
#else
|
||||
#define LOG_LVL LOG_LVL_DBG
|
||||
#endif
|
||||
#endif /* !defined(LOG_LVL) */
|
||||
|
||||
#if (LOG_LVL >= LOG_LVL_DBG) && (ULOG_OUTPUT_LVL >= LOG_LVL_DBG)
|
||||
#define ulog_d(TAG, ...) ulog_output(LOG_LVL_DBG, TAG, __VA_ARGS__)
|
||||
#else
|
||||
#define ulog_d(TAG, ...)
|
||||
#endif /* (LOG_LVL >= LOG_LVL_DBG) && (ULOG_OUTPUT_LVL >= LOG_LVL_DBG) */
|
||||
|
||||
#if (LOG_LVL >= LOG_LVL_INFO) && (ULOG_OUTPUT_LVL >= LOG_LVL_INFO)
|
||||
#define ulog_i(TAG, ...) ulog_output(LOG_LVL_INFO, TAG, __VA_ARGS__)
|
||||
#else
|
||||
#define ulog_i(TAG, ...)
|
||||
#endif /* (LOG_LVL >= LOG_LVL_INFO) && (ULOG_OUTPUT_LVL >= LOG_LVL_INFO) */
|
||||
|
||||
#if (LOG_LVL >= LOG_LVL_WARNING) && (ULOG_OUTPUT_LVL >= LOG_LVL_WARNING)
|
||||
#define ulog_w(TAG, ...) ulog_output(LOG_LVL_WARNING, TAG, __VA_ARGS__)
|
||||
#else
|
||||
#define ulog_w(TAG, ...)
|
||||
#endif /* (LOG_LVL >= LOG_LVL_WARNING) && (ULOG_OUTPUT_LVL >= LOG_LVL_WARNING) */
|
||||
|
||||
#if (LOG_LVL >= LOG_LVL_ERROR) && (ULOG_OUTPUT_LVL >= LOG_LVL_ERROR)
|
||||
#define ulog_e(TAG, ...) ulog_output(LOG_LVL_ERROR, TAG, __VA_ARGS__)
|
||||
#else
|
||||
#define ulog_e(TAG, ...)
|
||||
#endif /* (LOG_LVL >= LOG_LVL_ERROR) && (ULOG_OUTPUT_LVL >= LOG_LVL_ERROR) */
|
||||
|
||||
/* assert for developer. */
|
||||
#ifdef ULOG_ASSERT_ENABLE
|
||||
#define ULOG_ASSERT(EXPR) \
|
||||
if (!(EXPR)) \
|
||||
{ \
|
||||
ulog_output(LOG_LVL_ASSERT, LOG_TAG, "(%s) has assert failed at %s:%ld.", #EXPR, __FUNCTION__, __LINE__); \
|
||||
ulog_flush(); \
|
||||
while (1); \
|
||||
}
|
||||
#else
|
||||
#define ULOG_ASSERT(EXPR)
|
||||
#endif
|
||||
|
||||
/* ASSERT API definition */
|
||||
#if !defined(ASSERT)
|
||||
#define ASSERT ULOG_ASSERT
|
||||
#endif
|
||||
|
||||
/* compatible for elog */
|
||||
#undef assert
|
||||
#undef log_e
|
||||
#undef log_w
|
||||
#undef log_i
|
||||
#undef log_d
|
||||
#undef log_v
|
||||
#undef ELOG_LVL_ASSERT
|
||||
#undef ELOG_LVL_ERROR
|
||||
#undef ELOG_LVL_WARN
|
||||
#undef ELOG_LVL_INFO
|
||||
#undef ELOG_LVL_DEBUG
|
||||
#undef ELOG_LVL_VERBOSE
|
||||
#define assert ASSERT
|
||||
#define log_e LOG_E
|
||||
#define log_w LOG_W
|
||||
#define log_i LOG_I
|
||||
#define log_d LOG_D
|
||||
#define log_v LOG_D
|
||||
#define log_raw LOG_RAW
|
||||
#define ELOG_LVL_ASSERT LOG_LVL_ASSERT
|
||||
#define ELOG_LVL_ERROR LOG_LVL_ERROR
|
||||
#define ELOG_LVL_WARN LOG_LVL_WARNING
|
||||
#define ELOG_LVL_INFO LOG_LVL_INFO
|
||||
#define ELOG_LVL_DEBUG LOG_LVL_DBG
|
||||
#define ELOG_LVL_VERBOSE LOG_LVL_DBG
|
||||
|
||||
/* setting static output log level */
|
||||
#ifndef ULOG_OUTPUT_LVL
|
||||
#define ULOG_OUTPUT_LVL LOG_LVL_DBG
|
||||
#endif
|
||||
|
||||
/* buffer size for every line's log */
|
||||
#ifndef ULOG_LINE_BUF_SIZE
|
||||
#define ULOG_LINE_BUF_SIZE 128
|
||||
#endif
|
||||
|
||||
/* output filter's tag max length */
|
||||
#ifndef ULOG_FILTER_TAG_MAX_LEN
|
||||
#define ULOG_FILTER_TAG_MAX_LEN 23
|
||||
#endif
|
||||
|
||||
/* output filter's keyword max length */
|
||||
#ifndef ULOG_FILTER_KW_MAX_LEN
|
||||
#define ULOG_FILTER_KW_MAX_LEN 15
|
||||
#endif
|
||||
|
||||
#ifndef ULOG_NEWLINE_SIGN
|
||||
#define ULOG_NEWLINE_SIGN "\r\n"
|
||||
#endif
|
||||
|
||||
#define ULOG_FRAME_MAGIC 0x10
|
||||
|
||||
struct ulog_frame
|
||||
{
|
||||
/* magic word is 0x10 ('lo') */
|
||||
rt_uint32_t magic:8;
|
||||
rt_uint32_t is_raw:1;
|
||||
rt_uint32_t log_len:23;
|
||||
rt_uint32_t level;
|
||||
const char *log;
|
||||
const char *tag;
|
||||
};
|
||||
typedef struct ulog_frame *ulog_frame_t;
|
||||
|
||||
struct ulog_backend
|
||||
{
|
||||
char name[RT_NAME_MAX];
|
||||
rt_bool_t support_color;
|
||||
void (*init) (struct ulog_backend *backend);
|
||||
void (*output)(struct ulog_backend *backend, rt_uint32_t level, const char *tag, rt_bool_t is_raw, const char *log, size_t len);
|
||||
void (*flush) (struct ulog_backend *backend);
|
||||
void (*deinit)(struct ulog_backend *backend);
|
||||
rt_slist_t list;
|
||||
};
|
||||
typedef struct ulog_backend *ulog_backend_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ULOG_DEF_H_ */
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-08-02 armink the first version
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifndef ULOG_USING_SYSLOG
|
||||
#define LOG_TAG "example"
|
||||
#define LOG_LVL LOG_LVL_DBG
|
||||
#include <ulog.h>
|
||||
#else
|
||||
#include <syslog.h>
|
||||
#endif /* ULOG_USING_SYSLOG */
|
||||
|
||||
void ulog_example(void)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
#ifdef ULOG_USING_SYSLOG
|
||||
openlog("example1", 0, 0);
|
||||
#endif
|
||||
|
||||
while (count++ < 50)
|
||||
{
|
||||
#ifndef ULOG_USING_SYSLOG
|
||||
/* output different level log by LOG_X API */
|
||||
LOG_D("LOG_D(%d): RT-Thread is an open source IoT operating system from China.", count);
|
||||
LOG_I("LOG_I(%d): RT-Thread is an open source IoT operating system from China.", count);
|
||||
LOG_W("LOG_W(%d): RT-Thread is an open source IoT operating system from China.", count);
|
||||
LOG_E("LOG_E(%d): RT-Thread is an open source IoT operating system from China.", count);
|
||||
ulog_d("test", "ulog_d(%d): RT-Thread is an open source IoT operating system from China.", count);
|
||||
ulog_i("test", "ulog_i(%d): RT-Thread is an open source IoT operating system from China.", count);
|
||||
ulog_w("test", "ulog_w(%d): RT-Thread is an open source IoT operating system from China.", count);
|
||||
ulog_e("test", "ulog_e(%d): RT-Thread is an open source IoT operating system from China.", count);
|
||||
|
||||
#ifdef ULOG_USING_FILTER
|
||||
if (count == 20)
|
||||
{
|
||||
/* Set the global filer level is INFO. All of DEBUG log will stop output */
|
||||
ulog_global_filter_lvl_set(LOG_LVL_INFO);
|
||||
/* Set the test tag's level filter's level is ERROR. The DEBUG, INFO, WARNING log will stop output. */
|
||||
ulog_tag_lvl_filter_set("test", LOG_LVL_ERROR);
|
||||
}
|
||||
else if (count == 30)
|
||||
{
|
||||
/* Set the example tag's level filter's level is LOG_FILTER_LVL_SILENT, the log enter silent mode. */
|
||||
ulog_tag_lvl_filter_set("example", LOG_FILTER_LVL_SILENT);
|
||||
/* Set the test tag's level filter's level is WARNING. The DEBUG, INFO log will stop output. */
|
||||
ulog_tag_lvl_filter_set("test", LOG_LVL_WARNING);
|
||||
}
|
||||
else if (count == 40)
|
||||
{
|
||||
/* Set the test tag's level filter's level is LOG_FILTER_LVL_ALL. All level log will resume output. */
|
||||
ulog_tag_lvl_filter_set("test", LOG_FILTER_LVL_ALL);
|
||||
/* Set the global filer level is LOG_FILTER_LVL_ALL. All level log will resume output */
|
||||
ulog_global_filter_lvl_set(LOG_FILTER_LVL_ALL);
|
||||
}
|
||||
#endif /* ULOG_USING_FILTER */
|
||||
|
||||
#else
|
||||
/* output different priority log by syslog API */
|
||||
syslog(LOG_INFO, "syslog(%d) LOG_INFO: RT-Thread is an open source IoT operating system from China.", count);
|
||||
syslog(LOG_DEBUG, "syslog(%d) LOG_DEBUG: RT-Thread is an open source IoT operating system from China.", count);
|
||||
syslog(LOG_WARNING, "syslog(%d) LOG_WARNING: RT-Thread is an open source IoT operating system from China.", count);
|
||||
syslog(LOG_ERR, "syslog(%d) LOG_ERR: RT-Thread is an open source IoT operating system from China.", count);
|
||||
syslog(LOG_INFO | LOG_MAIL, "syslog(%d) LOG_INFO | LOG_MAIL: RT-Thread is an open source IoT operating system from China.", count);
|
||||
syslog(LOG_DEBUG | LOG_DAEMON, "syslog(%d) LOG_DEBUG | LOG_DAEMON: RT-Thread is an open source IoT operating system from China.", count);
|
||||
syslog(LOG_WARNING | LOG_AUTH, "syslog(%d) LOG_WARNING | LOG_AUTH: RT-Thread is an open source IoT operating system from China.", count);
|
||||
syslog(LOG_ERR | LOG_SYSLOG, "syslog(%d) LOG_ERR | LOG_SYSLOG: RT-Thread is an open source IoT operating system from China.", count);
|
||||
|
||||
if (count == 20)
|
||||
{
|
||||
/* Set log priority mask. Only output ERR and WARNING log. */
|
||||
setlogmask(LOG_MASK(LOG_ERR) | LOG_MASK(LOG_WARNING));
|
||||
}
|
||||
else if (count == 40)
|
||||
{
|
||||
/* Set log priority mask. The log which level is less than ERROR will stop output. */
|
||||
setlogmask(LOG_UPTO(LOG_ERR));
|
||||
}
|
||||
#endif /* ULOG_USING_SYSLOG */
|
||||
|
||||
rt_thread_delay(rt_tick_from_millisecond(rand() % 1000));
|
||||
}
|
||||
}
|
||||
MSH_CMD_EXPORT(ulog_example, run ulog example)
|
Loading…
Reference in New Issue