armink / easylogger Goto Github PK
View Code? Open in Web Editor NEWAn ultra-lightweight(ROM<1.6K, RAM<0.3k), high-performance C/C++ log library. | 一款超轻量级(ROM<1.6K, RAM<0.3k)、高性能的 C/C++ 日志库
License: MIT License
An ultra-lightweight(ROM<1.6K, RAM<0.3k), high-performance C/C++ log library. | 一款超轻量级(ROM<1.6K, RAM<0.3k)、高性能的 C/C++ 日志库
License: MIT License
EasyLogger/easylogger/src/elog.c
Line 396 in 7914a8e
log_buf每次用时,上次的数据还残留在缓冲区中,如果本次打印信息比上次短,上次的末尾也会打印出来。需要增加数据清空。
Error: Log sector header error! Now will clean all log area.
或者
Error: There must be only one sector status is USING! Now will clean all log area.
这些问题如何处理??
版本:EasyLogger V2.0.0 is initialize success
ElogErrCode elog_init(void) {
......
#ifdef ELOG_COLOR_ENABLE
/* disable text color by default /
elog_set_text_color_enabled(false);
#endif
......
}
void elog_output(...)
{
#ifdef ELOG_COLOR_ENABLE
/ add CSI start sign and color info */
if (elog.text_color_enabled) {
log_len += elog_strcpy(log_len, log_buf + log_len, CSI_START);
log_len += elog_strcpy(log_len, log_buf + log_len, color_output_info[level]);
}
#endif
}
这里默认是disable的,但是elog_find_lvl里没有判断text_color_enable,导致获取不到正确的lvl。
int8_t elog_find_lvl(const char log) {
#ifdef ELOG_COLOR_ENABLE
uint8_t i;
size_t csi_start_len = strlen(CSI_START);
for(i = 0; i < ELOG_LVL_TOTAL_NUM; i ++) {
if (!strncmp(color_output_info[i], log + csi_start_len, strlen(color_output_info[i]))) {
return i;
}
}
/ found failed */
return -1;
#else
...
}
log_cfg.h 这个头文件能不能只包含在那几个.c 文件里面, 不要包含在elog.h 里面,这样对外看到的API 只要有elog.h 就可以
使用 elog_async.c 在ring buf 满了后会丢log,
现在的easylogger虽然支持多线程,但是只是使用了一个信号量的保护,在资源占用上还有需要优化的地方。
主要是e_log宏虽然可以扩散到不同的task中,但是最终都是指向elog_output,从调用到最后输出都会在这个函数里面完成,这个函数占用很大的堆栈资源,而且随着每个task都使用e_log输出日志,每个task都要重复的占用这样的一个堆栈的资源。
比较好的一个方案是利用宏分开OS模式和BAREMETAL模式,当OS模式的时候,使用一个queue来存储每一个要发送的log,建立一个task从queue取出log并统一处理所有的输出,可以对queue的长度限制来限定资源。
具体问题在stm32f10x_flash.c中的flash_erasepage函数失败,未找到原因。
过滤的代码逻辑是不是搞反了?比如调用:elog_set_filter_tag("main");时,用意应该是过滤掉所有的tag是main的打印,而elog_output输出时,却是用:else if (!strstr(name, elog.filter.tag)) { /* tag filter */
进行过滤判断,就达不到过滤main标签的目的,应该改为else if ((NULL != strstr(tag, elog.filter.tag))&&(strlen(elog.filter.tag)>0)),其它几处判断也是类似
一个进程中有多个文件使用elog,是每个文件里都需要初始化,还是主程序初始化一次,其他的直接调打印log的函数就可以了
动态图中可以在控制台上 输入 elog on/off 来 开启/关闭日志输出。请问在Linux下如何能使用此项功能?
elog_buf_output()函数有问题,输出不完整
`void elog_buf_output(const char *log, size_t size) {
size_t write_size = 0, write_index = 0;
if (!is_enabled) {
elog_port_output(log, size);
return;
}
//循环有什么用?每次调用此处只会被执行一次
while (true) {
if (buf_write_size + size > ELOG_BUF_OUTPUT_BUF_SIZE) {
//缓冲区满时log被拆分输出?
write_size = ELOG_BUF_OUTPUT_BUF_SIZE - buf_write_size;
memcpy(log_buf + buf_write_size, log + write_index, write_size);
//write_index不是静态局部变量,此处有意义?
write_index += write_size;
size -= write_size;
buf_write_size += write_size;
/* output log /
elog_port_output(log_buf, buf_write_size);
/ reset write index */
buf_write_size = 0;
} else {
memcpy(log_buf + buf_write_size, log + write_index, size);
buf_write_size += size;
break;
}
}
}`
修改成以下代码后测试正常:
`void elog_buf_output(const char *log, size_t size)
{
//未使能缓冲输出时直接输出
if (!is_enabled) {
elog_port_output(log, size);
return;
}
//缓冲区空间不足时先输出
if (buf_write_size + size > ELOG_BUF_OUTPUT_BUF_SIZE) {
elog_port_output(log_buf, buf_write_size);
buf_write_size = 0;
}
//日志拷贝至缓冲区
memcpy(log_buf + buf_write_size, log, size);
buf_write_size += size;
}`
MCU是STM32L4,使用ST的HAL库,FreeRTOS下移植使用信号量进行elog_port_output_lock和elog_port_output_unlock,有时候会导致STM32不能进入不能进入外部中断函数,请问该怎么解决?谢谢!
static SemaphoreHandle_t log_sem;
/**
EasyLogger port initialize
@return result
*/
ElogErrCode elog_port_init(void) {
ElogErrCode result = ELOG_NO_ERR;
/* add your code here */
log_sem = xSemaphoreCreateBinary();
if (log_sem != NULL) {
xSemaphoreGive(log_sem);
}
return result;
}
/**
output lock
*/
void elog_port_output_lock(void) {
/* add your code here */
//__disable_irq();
if (log_sem == NULL) {
return;
}
xSemaphoreTake(log_sem, portMAX_DELAY);
}
/**
output unlock
*/
void elog_port_output_unlock(void) {
/* add your code here */
//__enable_irq();
if (log_sem == NULL) {
return;
}
xSemaphoreGive(log_sem);
}
问题描述:每次读取日志的时候,开头4个字节是FF。
经过检查发现:假设日志地址:0x08033000
读日志时,读取的地址是从0x08033000开始读去的。但是写日志的时候,却是从0x08033004地址开始写的。所以,每次查看日志的适合前4个字节内容为FF;
请问我是不是哪里设置有问题?
EasyFlash设置flash地址200KB开始,开启了 环境变量、掉电保护。
EasyLogger设置基本没改动。
使用的是您项目里面的RTT演示部源码,但是看你介绍的动画图又没有这个情况。。。
修改linux demo为多线程模式,verbose里面的tid不是子线程本身的id?
I/elog [12-25 18:28:36] EasyLogger V2.0.3 is initialize success.
do multithread test...
start create thread........
start create thread........
id=0
tid =3152430848
id=1
tid =3144038144
elog_output----tid:13995
A/main [12-25 18:28:36 pid:31856 tid:13995] (main.c test_elog:86)Hello EasyLogger! 0
E/main [12-25 18:28:36] Hello EasyLogger! 0
W/main [12-25 18:28:36] Hello EasyLogger! 0
I/main [12-25 18:28:36] Hello EasyLogger! 0
elog_output----tid:13995
elog_output----tid:13995
elog_output----tid:13995
A/main [12-25 18:28:36 pid:31856 tid:13995] (main.c test_elog:86)Hello EasyLogger! 1
E/main [12-25 18:28:36] Hello EasyLogger! 1
W/main [12-25 18:28:36] Hello EasyLogger! 1
I/main [12-25 18:28:36] Hello EasyLogger! 1
elog_output----tid:13995
elog_output----tid:13995
D/main [12-25 18:28:36 pid:31856 tid:13995] (main.c:90)Hello EasyLogger! 0
V/main [12-25 18:28:36 pid:31856 tid:13995] (main.c:91)Hello EasyLogger! 0
D/main [12-25 18:28:36 pid:31856 tid:13995] (main.c:90)Hello EasyLogger! 1
V/main [12-25 18:28:36 pid:31856 tid:13995] (main.c:91)Hello EasyLogger! 1
感觉elog_hexdump函数打印的数据偏移好像有点问题:
fmt_result = snprintf(log_buf, ELOG_LINE_BUF_SIZE, "D/HEX %s: %04X-%04X: ", name, i, i + width);
是不是应该改为:
fmt_result = snprintf(log_buf, ELOG_LINE_BUF_SIZE, "D/HEX %s: %04X-%04X: ", name, i, i + width - 1);
在调试过程中,很多时候会遇到打印一个数组的每个元素。比如串口调试时,可能会打印接收或者发送数组中的每个数据。
我现在的做法是:
`
for(uint16_t i = 0; i < len; i++){
elog_raw("%02X ",pbuff[i]);
}
elog_raw("\r\n");
但这样会造成打印繁琐问题,而且在关闭打印之后,for循环会空跑一圈,造成时间浪费。 我现在的想法是:
void elog_buff(char *type,char *pbuff,uint8_t len)
{
//在这儿添加相关屏蔽操作
for(uint16_t i = 0; i < len; i++){
elog_raw(type,pbuff[i]);
}
elog_raw("\r\n");
}
`
不知道大伙感觉这个方法怎么样?
一定要包含 rtthread.h 吗?
介绍里不是说支持多种操作系统(RT-Thread、UCOS、Linux、Windows...),也支持裸机平台
所以呢??Linux、Windows 该如何编译呢?
Hello.
demo/os/windows/easylogger/port/elog_port.c:
[32] #include <pthread.h>
pthread.h: No such file or directory
Thanks.
continue_ff<4 时,其log_end_addr返回sector_start + EF_ERASE_MIN_SIZE写数据会返回出错情况。
EasyLogger/src/elog_async.c:
开启ELOG_ASYNC_OUTPUT_USING_PTHREAD情况下,主线程创建线程完成后,才将init_ok设置为true.如:
#ifdef ELOG_ASYNC_OUTPUT_USING_PTHREAD
pthread_attr_t thread_attr;
struct sched_param thread_sched_param;
sem_init(&output_notice, 0, 0);
......
**pthread_create(&async_output_thread, &thread_attr, async_output, NULL);**
......
#endif
//此时,子线程极有可能已经开始执行async_output,而在async_out一开始就断言init_ok为false,
如: ELOG_ASSERT(init_ok); 子程序就有可能再也没有机会执行后边的sem_wait了。
init_ok = true;
最后,只会输出 level < OUTPUT_LVL内容了。
arm linux环境
(gdb) bt
#0 0x0000007f90ea9064 in __lll_lock_wait () from target:/lib64/libpthread.so.0
#1 0x0000007f90ea1a4c in pthread_mutex_lock ()
from target:/lib64/libpthread.so.0
#2 0x00000000004cad80 in elog_port_output_lock ()
at ./3rd_lib/easylogger/port/elog_port.c:76
#3 0x00000000004cbf78 in elog_get_filter_tag_lvl (tag=0x651c40 "TASK")
at ./3rd_lib/easylogger/src/elog.c:435
#4 0x00000000004cc2e8 in elog_output (level=2 '\002', tag=0x651c40 "TASK",
file=0x651968 "./devices/devices.c",
func=0x651f68 <__FUNCTION__.12424> "timer1_handle", line=217,
format=0x651c18 "timming update_devices_status %d")
at ./3rd_lib/easylogger/src/elog.c:528
#5 0x00000000004e9314 in timer1_handle (sig=10) at ./devices/devices.c:217
#6 <signal handler called>
#7 0x0000007f90d0f6d8 in nanosleep () from target:/lib64/libc.so.6
#8 0x0000007f90d0f568 in sleep () from target:/lib64/libc.so.6
#9 0x00000000004e75ec in main (argc=1, argv=0x7fea78d518) at ./main.c:98
(gdb) thread 2
[Switching to thread 2 (Thread 3106.3107)]
#0 0x0000007f90ea9034 in __lll_lock_wait () from target:/lib64/libpthread.so.0
(gdb) bt
#0 0x0000007f90ea9034 in __lll_lock_wait () from target:/lib64/libpthread.so.0
#1 0x0000007f90ea1a4c in pthread_mutex_lock ()
from target:/lib64/libpthread.so.0
#2 0x00000000004cad80 in elog_port_output_lock ()
at ./3rd_lib/easylogger/port/elog_port.c:76
#3 0x00000000004cbf78 in elog_get_filter_tag_lvl (tag=0x651c40 "TASK")
at ./3rd_lib/easylogger/src/elog.c:435
#4 0x00000000004cc2e8 in elog_output (level=2 '\002', tag=0x651c40 "TASK",
file=0x651968 "./devices/devices.c",
func=0x651f68 <__FUNCTION__.12424> "timer1_handle", line=226,
format=0x651c48 "timming check_devices_status %d")
at ./3rd_lib/easylogger/src/elog.c:528
#5 0x00000000004e93b4 in timer1_handle (sig=10) at ./devices/devices.c:226
#6 <signal handler called>
#7 0x0000007f90d2e6e8 in write () from target:/lib64/libc.so.6
#8 0x0000007f90cddeb0 in _IO_file_write () from target:/lib64/libc.so.6
#9 0x0000007f90cdd2f8 in ?? () from target:/lib64/libc.so.6
#10 0x0000007f90cde648 in _IO_file_xsputn () from target:/lib64/libc.so.6
#11 0x0000007f90cb8e90 in ?? () from target:/lib64/libc.so.6
#12 0x0000007f90cb6824 in vfprintf () from target:/lib64/libc.so.6
#13 0x0000007f90cbd948 in printf () from target:/lib64/libc.so.6
#14 0x00000000004cad54 in elog_port_output (
log=0x7065b8 <poll_get_buf> "D/HEX JP_PLC: 0000-0017: 55 ...***... 0A"..., size=127)
at ./3rd_lib/easylogger/port/elog_port.c:65
#15 0x00000000004cde18 in async_output (arg=0x0)
at ./3rd_lib/easylogger/src/elog_async.c:299
#16 0x0000007f90e9f0e8 in start_thread () from target:/lib64/libpthread.so.0
#17 0x0000007f90d3af4c in ?? () from target:/lib64/libc.so.6
(gdb) thread 3
[Switching to thread 3 (Thread 3106.3108)]
#0 0x0000007f90ea9064 in __lll_lock_wait () from target:/lib64/libpthread.so.0
(gdb) bt
#0 0x0000007f90ea9064 in __lll_lock_wait () from target:/lib64/libpthread.so.0
#1 0x0000007f90ea1a4c in pthread_mutex_lock () from target:/lib64/libpthread.so.0
#2 0x00000000004cad80 in elog_port_output_lock ()
at ./3rd_lib/easylogger/port/elog_port.c:76
#3 0x00000000004cbf78 in elog_get_filter_tag_lvl (tag=0x651c40 "TASK")
at ./3rd_lib/easylogger/src/elog.c:435
#4 0x00000000004cc2e8 in elog_output (level=2 '\002', tag=0x651c40 "TASK",
file=0x651968 "./devices/devices.c",
func=0x651f68 <__FUNCTION__.12424> "timer1_handle", line=226,
format=0x651c48 "timming check_devices_status %d")
at ./3rd_lib/easylogger/src/elog.c:528
#5 0x00000000004e93b4 in timer1_handle (sig=10) at ./devices/devices.c:226
#6 <signal handler called>
#7 0x0000007f90d0f6d8 in nanosleep () from target:/lib64/libc.so.6
#8 0x0000007f90d34d08 in usleep () from target:/lib64/libc.so.6
#9 0x00000000004e6bf4 in http_deal (arg=0x0) at ./service/http.c:415
#10 0x0000007f90e9f0e8 in start_thread () from target:/lib64/libpthread.so.0
#11 0x0000007f90d3af4c in ?? () from target:/lib64/libc.so.6
1、我们需要使用hex_dump功能,我参考ulog_hex_demp实现了,我可以提交一个pr吗?
2、elog_async_init中init_ok = true;建议提前到ifdef ELOG_ASYNC_OUTPUT_USING_PTHREAD宏定义前,我修改异步输出任务调度方式为SCHED_FIFO时发现,在任务还没有返回时async_output回调就被调用,会在该函数中ELOG_ASSERT(init_ok);导致无法输出。
我还没有能力贡献代码,就贡献测试出的bug吧。
使用linux demo的代码,以so库的方式调用,设定文件大小为100k, rotate为2,同时启动四个程序,是为了测试多进程下log是否完整。
预期结果:
在elog_file.log中出现如下有序或无序,但自增数字连续的日志记录:
A: 000 Hello EasyLogger!
B: 000 Hello EasyLogger!
C: 000 Hello EasyLogger!
D: 000 Hello EasyLogger!
测试结果:
当第一个elog_file.log.0产生前,log是预期的的结果;
当第一个elog_file.log.0产生后,log记录出现错乱,log只出现其中一个程序的所有log,比如:
...
B: 199 Hello EasyLogger!
B: 200 Hello EasyLogger!
B: 201 Hello EasyLogger!
B: 202 Hello EasyLogger!
...
其他三个程序的log全部没有记录。shell显示程序还在正常产生log。
备注:
单进程无此问题。
我还没有能力直接分析解决,所以只能提issue。:-(
程序如下:
int main()
{
/* close printf buffer */
setbuf(stdout, NULL);
/* initialize EasyLogger */
elog_init();
/* set EasyLogger log format */
elog_set_fmt(ELOG_LVL_ASSERT, ELOG_FMT_ALL);
elog_set_fmt(ELOG_LVL_ERROR, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_WARN, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_INFO, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_DEBUG, ELOG_FMT_ALL & ~ELOG_FMT_FUNC);
elog_set_fmt(ELOG_LVL_VERBOSE, ELOG_FMT_ALL & ~ELOG_FMT_FUNC);
#ifdef ELOG_COLOR_ENABLE
elog_set_text_color_enabled(true);
#endif
/* start EasyLogger */
elog_start();
log_e("This is test message");
char *a = NULL;//制造崩溃
*a = 0;
}
此时This is test message
这条信息是无法输出的,造成了调试和信息记录上面的误解以为是log_e("This is test message");
之前就已经崩溃了。
linux系统下,有几率初始化不成功什么原因,10次有两三次。不成功导致日志完全不能输出。
初始化不是同步执行吗?
不好意思 我还是新手。
我这单片机有点怪 可以装个SD卡 可以使用FILE * 把数据存到SD卡上
用的是arm-none-eabi编译的
有几个疑问:
1 他似乎每个级别的记录都保存,怎么设置某些低级别的记录不保存?这样我就不需要普通的COUT了
直接全部LOG_D就可以了
2 单片机上他会不会自动清除log记录?因为log文件不能无限大啊..
3 elog_file_port.cpp 这个我的单片机是arm-none-eabi 没操作系统.再这个咋办?都空着?如果不写这个他不会保存文件
#ifdef ELOG_COLOR_ENABLE
/* add CSI end sign */
if (elog.text_color_enabled) {
log_len += elog_strcpy(log_len, log_buf + log_len + fmt_result, CSI_END);
}
#endif
log_buf + log_len + fmt_result可能超过ELOG_LINE_BUF_SIZE,导致数组越界
elog_flash_set_filter在elog_flash.h头文件中给出定义,却没有在任何.c中实现,且源码中也不具备对从flash中抓出的日志进行过滤的功能,请问日后准备实现该功能吗?
thanks and respect
找了半天才闹明白,原来每个输出“目标”都是通过port定义的。为什么会没有file port呢?
1.3.1 输出基本日志
#define elog_assert(tag, ...)
#define elog_a(tag, ...) //简化方式1,每次需填写 LOG_TAG
#define log_a(...) //简化方式2,LOG_TAG 已经在文件顶部定义,使用前无需填写 LOG_TAG
#define elog_error(tag, ...)
#define elog_e(tag, ...)
#define log_a(...)
...
后面几项的log_a(...)似乎应该是log_e, log_w ...
packages\EasyLogger-v2.0.0\inc\elog.h(209): warning: #47-D: incompatible redefinition of macro "log_e" (declared at line 98 of "packages\fal-latest\inc\fal_def.h")
fal_def.h:
/* info level log */
#ifdef log_i
#undef log_i
#endif
#define log_i(...) FAL_PRINTF("\033[32;22m[I/FAL] ");
在easylogger中是使用log_x的宏,但是fal中也是使用log_x,虽然是不同的东西,但是看到作者都是你,所以提一下。
EasyLogger/easylogger/src/elog.c
Line 513 in 7914a8e
用gcc -O2 编译,在这一行报
warning: call to __builtin___memcpy_chk will always overflow destination buffer
分析:
与elog_strcpy不同,strcpy函数会拷贝ELOG_NEWLINE_SIGN结束的'\0'字符,因此仅仅从log_buf的结尾退回newline_len = strlen(ELOG_NEWLINE_SIGN)个字节是不够的,得多退一个字节,修改成:
strcpy(log_buf + ELOG_LINE_BUF_SIZE - newline_len - 1, ELOG_NEWLINE_SIGN);
没有细看前后文,上文的log_len是否也应该减1?
我有两个进程client和server,我想把两个进程的日志写到一起,而且保持时序,方便debug,就是android的日志系统一样,这个工具是否可行?
配置如下:
/*
* This file is part of the EasyLogger Library.
*
* Copyright (c) 2015, Armink, <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: It is the configure head file for this library.
* Created on: 2015-07-30
*/
#ifndef _ELOG_CFG_H_
#define _ELOG_CFG_H_
/* enable log output. default open this macro */
#define ELOG_OUTPUT_ENABLE
/* setting static output log level */
#define ELOG_OUTPUT_LVL ELOG_LVL_VERBOSE
/* enable assert check */
#define ELOG_ASSERT_ENABLE
/* buffer size for every line's log */
#define ELOG_LINE_BUF_SIZE 1024000
/* output line number max length */
#define ELOG_LINE_NUM_MAX_LEN 5
/* output filter's tag max length */
#define ELOG_FILTER_TAG_MAX_LEN 16
/* output filter's keyword max length */
#define ELOG_FILTER_KW_MAX_LEN 16
/* output newline sign */
#define ELOG_NEWLINE_SIGN "\n"
/* enable log color */
#define ELOG_COLOR_ENABLE
/* enable asynchronous output mode */
// #define ELOG_ASYNC_OUTPUT_ENABLE
/* the highest output level for async mode, other level will sync output */
#define ELOG_ASYNC_OUTPUT_LVL ELOG_LVL_DEBUG
/* buffer size for asynchronous output mode */
#define ELOG_ASYNC_OUTPUT_BUF_SIZE (ELOG_LINE_BUF_SIZE * 100)
/* each asynchronous output's log which must end with newline sign */
//#define ELOG_ASYNC_LINE_OUTPUT
/* asynchronous output mode using POSIX pthread implementation */
#define ELOG_ASYNC_OUTPUT_USING_PTHREAD
//ELOG_BUF_OUTPUT_ENABLE 缓冲输出模式下日志缓冲区满了才会输出,或者手动调用 elog_flush 方法时输出
#endif /* _ELOG_CFG_H_ */
初始化代码如下:
void log_init(void)
{/* close printf buffer */
setbuf(stdout, NULL);
/* initialize EasyLogger */
elog_init();
/* set EasyLogger log format */
elog_set_fmt(ELOG_LVL_ASSERT, ELOG_FMT_ALL);
elog_set_fmt(ELOG_LVL_ERROR, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_WARN, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_INFO, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_DEBUG, ELOG_FMT_ALL & ~ELOG_FMT_FUNC);
elog_set_fmt(ELOG_LVL_VERBOSE, ELOG_FMT_ALL & ~ELOG_FMT_FUNC);
#ifdef ELOG_COLOR_ENABLE
elog_set_text_color_enabled(true);
#endif
/* start EasyLogger */
elog_start();
}
gdb信息如下:
[~]# ./gdb -p 8793
GNU gdb (GDB) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "arm-buildroot-linux-gnueabihf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
Attaching to process 8793
[New LWP 8794]
[New LWP 8795]
[New LWP 8796]
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
0x76e47ba4 in __libc_do_syscall () from /lib/libpthread.so.0
(gdb) bt
#0 0x76e47ba4 in __libc_do_syscall () from /lib/libpthread.so.0
#1 0x76e4568c in __lll_lock_wait () from /lib/libpthread.so.0
#2 0x76e415ba in pthread_mutex_lock () from /lib/libpthread.so.0
#3 0x00017184 in elog_port_output_lock () at ../../easylogger/port/elog_port.c:128
#4 0x00016080 in elog_output_lock () at ../../easylogger/src/elog.c:306
#5 0x00016254 in elog_output (level=3 '\003', tag=0x192bc "NO_TAG", file=0x192b4 "db.c",
func=0x197e0 <__FUNCTION__.7622> "db_get_retained_count", line=239,
format=0x19538 "db get retained message count %d") at ../../easylogger/src/elog.c:413
#6 0x0001253c in db_get_retained_count () at db.c:239
#7 0x0001363e in sync_publishRetainedMsg (clientPt=0x2c0d4 <_client>) at sync.c:258
#8 0x0001588a in main (argc=2, argv=0x7e983e44) at transceiver.c:809
(gdb) where
#0 0x76e47ba4 in __libc_do_syscall () from /lib/libpthread.so.0
#1 0x76e4568c in __lll_lock_wait () from /lib/libpthread.so.0
#2 0x76e415ba in pthread_mutex_lock () from /lib/libpthread.so.0
#3 0x00017184 in elog_port_output_lock () at ../../easylogger/port/elog_port.c:128
#4 0x00016080 in elog_output_lock () at ../../easylogger/src/elog.c:306
#5 0x00016254 in elog_output (level=3 '\003', tag=0x192bc "NO_TAG", file=0x192b4 "db.c",
func=0x197e0 <__FUNCTION__.7622> "db_get_retained_count", line=239,
format=0x19538 "db get retained message count %d") at ../../easylogger/src/elog.c:413
#6 0x0001253c in db_get_retained_count () at db.c:239
#7 0x0001363e in sync_publishRetainedMsg (clientPt=0x2c0d4 <_client>) at sync.c:258
#8 0x0001588a in main (argc=2, argv=0x7e983e44) at transceiver.c:809
(gdb)
看了别的 issue 断言的时候要把几个锁关掉,但是整个程序中没有使用到断言。
仔细查看了下代码,发现日志初始化代码运行了两次,也就是log_init()
调用了两次,是否和这个有关系?
如题
elog_set_filter_tag 这个API是LOG中TAG符合才会输出,我想要个API,符合不输出,应该,好弄把
else if (!strstr(tag, elog.filter.tag)) /* tag filter */
{
//TODO 可以考虑采用KMP及朴素模式匹配字符串,提升性能
return;
}
这块 改成?
else if (strstr(tag, elog.filter.tag)) /* tag filter */
{
//TODO 可以考虑采用KMP及朴素模式匹配字符串,提升性能
return;
}
或者为了保持原来的 elog_set_filter_tag 接口,增加个 elog_set_unfilter_tag 接口
//伪代码演示
else if (!strstr(tag, elog.filter.tag) && filter_mode == true) /* tag filter */
{
}
else if (!strstr(tag, elog.filter.tag)&& filter_mode == false) ) /* tag filter */
{
//TODO 可以考虑采用KMP及朴素模式匹配字符串,提升性能
return;
}
在elog.h中elog_a~elog_v的宏定义默认给出了有效定义(187-192行),导致未定义ELOG_OUTPUT_ENABLE时不能将宏有效置空。
配置文件:
/*
* This file is part of the EasyLogger Library.
*
* Copyright (c) 2015, Armink, <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* 'Software'), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Function: It is the configure head file for this library.
* Created on: 2015-07-30
*/
#ifndef _ELOG_CFG_H_
#define _ELOG_CFG_H_
/* enable log output. default open this macro */
#define ELOG_OUTPUT_ENABLE
/* setting static output log level */
#define ELOG_OUTPUT_LVL ELOG_LVL_VERBOSE
/* enable assert check */
#define ELOG_ASSERT_ENABLE
/* buffer size for every line's log */
#define ELOG_LINE_BUF_SIZE 5120
/* output line number max length */
#define ELOG_LINE_NUM_MAX_LEN 5
/* output filter's tag max length */
#define ELOG_FILTER_TAG_MAX_LEN 16
/* output filter's keyword max length */
#define ELOG_FILTER_KW_MAX_LEN 16
/* output newline sign */
#define ELOG_NEWLINE_SIGN "\n"
/* enable log color */
#define ELOG_COLOR_ENABLE
/* enable asynchronous output mode */
// #define ELOG_ASYNC_OUTPUT_ENABLE
/* the highest output level for async mode, other level will sync output */
#define ELOG_ASYNC_OUTPUT_LVL ELOG_LVL_DEBUG
/* buffer size for asynchronous output mode */
#define ELOG_ASYNC_OUTPUT_BUF_SIZE (ELOG_LINE_BUF_SIZE * 100)
/* each asynchronous output's log which must end with newline sign */
//#define ELOG_ASYNC_LINE_OUTPUT
/* asynchronous output mode using POSIX pthread implementation */
#define ELOG_ASYNC_OUTPUT_USING_PTHREAD
//ELOG_BUF_OUTPUT_ENABLE 缓冲输出模式下日志缓冲区满了才会输出,或者手动调用 elog_flush 方法时输出
#endif /* _ELOG_CFG_H_ */
测试程序:
void test_elog(void) {
while(true) {
/* test log output for all level */
errno = 5;
log_a("Hello EasyLogger! %d", errno);
log_e("Hello EasyLogger! %d", errno);
log_w("Hello EasyLogger! %d", errno);
log_i("Hello EasyLogger! %d", errno);
log_d("Hello EasyLogger! %d", errno);
log_v("Hello EasyLogger! %d", errno);
// elog_raw("Hello EasyLogger!");
sleep(5);
}
}
void log_init(void)
{
/* close printf buffer */
setbuf(stdout, NULL);
/* initialize EasyLogger */
elog_init();
/* set EasyLogger log format */
elog_set_fmt(ELOG_LVL_ASSERT, ELOG_FMT_ALL);
elog_set_fmt(ELOG_LVL_ERROR, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_WARN, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_INFO, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_DEBUG, ELOG_FMT_ALL & ~ELOG_FMT_FUNC);
elog_set_fmt(ELOG_LVL_VERBOSE, ELOG_FMT_ALL & ~ELOG_FMT_FUNC);
#ifdef ELOG_COLOR_ENABLE
elog_set_text_color_enabled(true);
#endif
/* start EasyLogger */
elog_start();
// elog_async_enabled(false);//失能异步输出,否则会出现程序崩溃的时候没有输出的问题
}
int main(int argc, char** argv)
{
log_init();
test_elog();
}
程序输出
I/elog [05-29 18:13:46] EasyLogger V2.0.1 is initialize success.
A/Alfred [05-29 18:13:46 pid:0704 tid:19956] (alfred.c test_elog:526)Hello EasyLogger! 5
E/Alfred [05-29 18:13:46] Hello EasyLogger! 2
W/Alfred [05-29 18:13:46] Hello EasyLogger! 2
I/Alfred [05-29 18:13:46] Hello EasyLogger! 2
D/Alfred [05-29 18:13:46 pid:0704 tid:19956] (alfred.c:530)Hello EasyLogger! 2
V/Alfred [05-29 18:13:46 pid:0704 tid:19956] (alfred.c:531)Hello EasyLogger! 2
使用打印函数之后errno被改变了,应该是elogger内部调用出现了错误,目前还没查出来。
#define ELOG_FILE_MAX_SIZE (10 * 1024) 这句话表示日志文件大小是10KB吗?
如果log_i("...\n"), 这样log里面已经有了换行符,使用的时候会打印两个换行符,应该去掉一个啊
没看到 elog_async_output有用lock/unlock保护下.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.