Sfoglia il codice sorgente

Merge pull request #1 from Lawlieta/main

【添加】logmgr 软件包初始版本
朱天龙 (Armink) 5 anni fa
parent
commit
2ac22196aa
5 ha cambiato i file con 564 aggiunte e 2 eliminazioni
  1. 81 2
      README.md
  2. 11 0
      SConscript
  3. 20 0
      inc/logmgr.h
  4. 63 0
      src/logmgr.c
  5. 389 0
      src/logmgr_abort.c

+ 81 - 2
README.md

@@ -1,2 +1,81 @@
-# logmgr
-log system manager
+# 日志管理软件包介绍
+
+## 1、介绍
+
+该软件包主要用于配置和管理系统中日志相关功能,实现功能如下
+
+- 支持 ulog 文件后端功能启动;
+- 重定向异常日志打印接口,支持异常时多种调试日志输出;
+- 支持异常时日志保存并输出到指定文件中;
+
+### 1.1 许可证
+
+本软件包遵循 Apache-2.0 许可,详见 `LICENSE` 文件。 
+
+### 1.2 依赖
+
+- [ulog_file 软件包](https://github.com/RT-Thread-packages/ulog_file.git)
+- [flashdb 软件包](https://github.com/armink-rtt-pkgs/FlashDB.git)
+- [cmbacktrace 软件包](https://github.com/armink-rtt-pkgs/CmBacktrace.git)(可配置)
+- [kdb 软件包](http://packages.rt-thread.org/detail.html?package=kdb)(可配置)
+- [sys_load_monitor 软件包](https://github.com/armink-rtt-pkgs/sys_load_monitor)(可配置)
+
+## 2、如何打开
+
+使用本软件包需要在 RT-Thread 的包管理器中选择它,具体路径如下:
+
+```
+RT-Thread online packages
+    tools packages --->
+        [*] logmgr: A log management system for rt-thread.
+        [ ]   Enable automatic initialization
+        [ ]   Enable log file backend feature
+        [*]   Enable log abort feature
+        (/abort.log) abort file path
+        (logmgr) flashdb fal part name
+        (65536) falshdb data max size
+        [*]     cmbacktrace log support
+        [*]     system ipc log support
+        [*]     kernel running log support
+        [*]     system load monitor log support
+        [*]     system memory log support
+            Version (latest)  --->
+```
+
+- **Enable automatic initialization**:自动初始化功能支持
+- **Enable log file backend feature** :开启日志文件后端功能支持
+- **Enable log abort feature**:开启异常日志打印功能支持
+  - **abort file path**:定义异常日志存储文件位置
+  - **flashdb fal part name**:定义异常日志保存使用 flashdb 分区名称
+  - **falshdb data max size**:定义异常日志保存使用 flashdb 数据最大值
+  - **cmbacktrace log support**:开启系统异常后 cmbacktrace 日志打印
+  - **system ipc log support**:开启系统异常后 IPC 信息打印
+  - **kernel running log support**:开启系统异常后系统运行日志打印
+  - **system load monitor log support**:开启系统异常系统负荷监视器打印
+  - **system memory log support**:开启系统异常后系统内存相关信息日志打印
+
+## 3、使用说明
+
+### 3.1 日志管理初始化
+
+```
+int logmgr_init(void);
+```
+
+上述功能配置完成之后,需要在应用层调用 `logmgr_init()` 初始化函数,或者开启自动初始化,即可完成日志管理系统初始化。实现文件后端和异常日志输出功能支持。
+
+### 3.1 日志管理取消初始化
+
+```
+int logmgr_deinit(void);
+```
+
+需要在应用层调用 `logmgr_deinit()` 函数,可以注销日志管理初始化。
+
+## 4、联系方式
+
+- 维护:ChenYong
+- 主页:<https://github.com/RT-Thread-packages/logmgr.git>
+
+
+

+ 11 - 0
SConscript

@@ -0,0 +1,11 @@
+# RT-Thread building script for component
+
+from building import *
+
+cwd = GetCurrentDir()
+src = Glob('src/*.c')
+CPPPATH = [cwd + '/inc']
+
+group = DefineGroup('logmgr', src, depend = ['PKG_USING_LOGMGR'], CPPPATH = CPPPATH)
+
+Return('group')

+ 20 - 0
inc/logmgr.h

@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-01-13     ChenYong     first version
+ */
+
+#ifndef _LOGMGR_H_
+#define _LOGMGR_H_
+
+#define ULOGMGR_SW_VERSION      "0.0.1"
+#define ULOGMGR_SW_VERSION_NUM  0x000001
+
+int logmgr_init(void);
+int logmgr_deinit(void);
+
+#endif /* _LOGMGR_H_ */

+ 63 - 0
src/logmgr.c

@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-01-13     ChenYong     first version
+ */
+
+#include <rtthread.h>
+#include <logmgr.h>
+
+#ifdef PKG_USING_ULOG_FILE
+#include <ulog_file.h>
+#endif
+
+#define DBG_TAG "logmgr"
+#define DBG_LVL DBG_LOG
+#include <ulog.h>
+
+static rt_bool_t is_init = RT_FALSE;
+
+extern int logmgr_abort_init(void);
+
+/* logmgr initialize */
+int logmgr_init(void)
+{
+    if (is_init)
+    {
+        LOG_E("logmgr is already initialized");
+        return -1;
+    }
+
+#ifdef PKG_USING_ULOG_FILE
+    ulog_file_backend_init();
+#endif
+#ifdef LOGMGR_USING_ABORT
+    logmgr_abort_init();
+#endif
+
+    is_init = RT_TRUE;
+    LOG_I("logmgr (v%s) initialized success.", ULOGMGR_SW_VERSION);
+    return 0;
+}
+#ifdef LOGMGR_AUTO_INIT
+INIT_APP_EXPORT(logmgr_init);
+#endif
+
+/* logmgr deinitialize */
+int logmgr_deinit(void)
+{
+    if (is_init == RT_FALSE)
+    {
+        return -1;
+    }
+
+#ifdef PKG_USING_ULOG_FILE
+    ulog_file_backend_deinit();
+#endif
+
+    return 0;
+}

+ 389 - 0
src/logmgr_abort.c

@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-01-13     ChenYong     first version
+ */
+
+#include <stdbool.h>
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <sys/time.h>
+
+#include <dfs.h>
+#include <dfs_posix.h>
+
+#include <logmgr.h>
+
+#define DBG_TAG "logmgr.abort"
+#define DBG_LVL DBG_LOG
+#include <ulog.h>
+
+#ifdef LOGMGR_USING_CMBACKTRACE
+#include <cm_backtrace.h>
+#endif
+#ifdef LOGMGR_USING_KDB
+#include <kdb_sys.h>
+#endif
+#ifdef LOGMGR_USING_SYS_LOAD_MONITOR
+#include <sys_load_monitor.h>
+#endif
+#define LOGMGR_CONSOLE_NAME            "logmgr"
+#ifdef PKG_USING_FLASHDB
+#include <flashdb.h>
+#ifndef LOGMGR_FLASHDB_PART_NAME
+#define LOGMGR_FLASHDB_PART_NAME       "logmgr"
+#endif
+#ifndef LOGMGR_FLASHDB_MAX_LEN
+#define LOGMGR_FLASHDB_MAX_LEN         512
+#endif
+#define LOGMGR_FLASHDB_SECTOR_SIZE     4096
+#ifndef LOGMGR_FLASHDB_MAX_SIZE
+#define LOGMGR_FLASHDB_MAX_SIZE        65536
+#endif
+#endif /* PKG_USING_FLASHDB */
+#ifndef LOGMGR_ABORT_FILE_PATH
+#define LOGMGR_ABORT_FILE_PATH         "/abort.log"
+#endif
+
+#ifdef PKG_USING_FLASHDB
+static struct fdb_tsdb g_tsdb;
+#endif
+static rt_bool_t is_init = RT_FALSE;
+static struct rt_device g_console_dev;
+static rt_device_t g_def_device = RT_NULL;
+
+static void _logmgr_ipc_log(void);
+static void _logmgr_memory_log(void);
+static void _logmgr_console_switch(rt_device_t device);
+void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context));
+
+static void printf_time_log(void)
+{
+    rt_kprintf("Logmgr Abort Start %s %s\n", __DATE__, __TIME__);
+}
+
+static void printf_second_header_log(const char *second_name)
+{
+    rt_kprintf("\n/******  %.*s  ******/\n", rt_strlen(second_name), second_name);
+}
+
+static void print_header_log(const char *log_name)
+{
+    rt_kprintf("\n");
+    rt_kprintf("/**********************************************************/\n");
+    rt_kprintf("/**************     %20s     **************/\n", log_name);
+    rt_kprintf("/**********************************************************/\n");
+    rt_kprintf("\n");
+}
+
+RT_WEAK rt_err_t logmgr_exception_hook(void *context)
+{
+    volatile uint8_t _continue = 1;
+
+    /* set console device to new customize device */
+    _logmgr_console_switch(&g_console_dev);
+
+    /* show abort start time */
+    printf_time_log();
+
+#ifdef LOGMGR_USING_CMBACKTRACE
+    print_header_log("CmBacktrace Log");
+    /* cmbacktrace exception hook */
+    extern rt_err_t exception_hook(void *context);
+    exception_hook(context);
+#endif
+#ifdef LOGMGR_USING_IPC_LOG
+    print_header_log("System IPC Log");
+    _logmgr_ipc_log();
+#endif
+#ifdef LOGMGR_USING_KDB
+    print_header_log("Kernel Running Log");
+    kdb_sys_stop_dump();
+#endif
+#ifdef LOGMGR_USING_SYS_LOAD_MONITOR
+    print_header_log("System Load Log");
+    sys_load_monitor_dump();
+#endif
+#ifdef LOGMGR_USING_MEMORY_LOG
+    print_header_log("System Memory Log");
+    _logmgr_memory_log();
+#endif
+
+    while (_continue == 1);
+
+    return RT_EOK;
+}
+
+RT_WEAK void logmgr_assert_hook(const char *ex, const char *func, rt_size_t line)
+{
+    volatile uint8_t _continue = 1;
+
+    /* set console device to new customize device */
+    _logmgr_console_switch(&g_console_dev);
+
+    /* show abort start time */
+    printf_time_log();
+
+#ifdef PKG_USING_CMBACKTRACE
+    print_header_log("CmBacktrace Log");
+    /* cmbacktrace assert hook */
+    extern void assert_hook(const char* ex, const char* func, rt_size_t line);
+    assert_hook(ex, func, line);
+#endif
+
+    while (_continue == 1);
+}
+
+#ifdef LOGMGR_USING_MEMORY_LOG
+static void _logmgr_memory_log(void)
+{
+#ifdef RT_USING_HEAP
+    printf_second_header_log("sys memory log");
+#ifdef RT_USING_MEMHEAP_AS_HEAP
+    extern void list_memheap(void);
+    list_memheap();
+#else
+    extern void list_mem(void);
+    list_mem();
+#endif
+#endif /* RT_USING_HEAP */
+
+#ifdef PKG_JMEM_STATS
+    printf_second_header_log("js heap log");
+    extern void jmem_heap(void);
+    jmem_heap();
+#endif
+}
+#endif /* LOGMGR_USING_MEMORY_LOG */
+
+#ifdef LOGMGR_USING_IPC_LOG
+/* system ipc log print */
+static void _logmgr_ipc_log(void)
+{
+#ifdef RT_USING_SEMAPHORE
+    printf_second_header_log("semaphore log");
+    extern long list_sem(void);
+    list_sem();
+#endif
+#ifdef RT_USING_EVENT
+    printf_second_header_log("event log");
+    extern long list_event(void);
+    list_event();
+#endif
+#ifdef RT_USING_MUTEX
+    printf_second_header_log("mutex log");
+    extern long list_mutex(void);
+    list_mutex();
+#endif
+#ifdef RT_USING_MAILBOX
+    printf_second_header_log("mailbox log");
+    extern long list_mailbox(void);
+    list_mailbox();
+#endif
+#ifdef RT_USING_MESSAGEQUEUE
+    printf_second_header_log("messagqueue log");
+    long list_msgqueue(void);
+    list_msgqueue();
+#endif
+}
+#endif /* LOGMGR_USING_IPC_LOG */
+
+#ifdef PKG_USING_FLASHDB
+/* flashdb get time function */
+static fdb_time_t _logmgr_get_time(void)
+{
+    static fdb_time_t count = 0;
+    return count++;
+}
+#endif /* PKG_USING_FLASHDB */
+
+/* flashdb iterator callback function */
+static bool _logmgr_tsl_cb(fdb_tsl_t tsl, void *arg)
+{
+    int fd = *((int *) arg);
+    struct fdb_blob blob;
+    size_t data_len = 0;
+    char data[LOGMGR_FLASHDB_MAX_LEN] = { 0 };
+
+    /* get blob data by tsl data */
+    fdb_blob_make(&blob, data, tsl->log_len);
+    data_len = fdb_blob_read((fdb_db_t )&g_tsdb, fdb_tsl_to_blob(tsl, &blob));
+
+    /* write falshdb historical data to file */
+    write(fd, data, data_len);
+    return false;
+}
+/* logmgr support packages initialized */
+static int _logmgr_pkgs_init(void)
+{
+#ifdef PKG_USING_FLASHDB
+    uint32_t sec_size = LOGMGR_FLASHDB_SECTOR_SIZE;
+    uint32_t db_size  = LOGMGR_FLASHDB_MAX_SIZE;
+    fdb_tsdb_t tsdb = &g_tsdb;
+
+     /* initialize flashdb tsdb information */
+    fdb_tsdb_control(tsdb, FDB_TSDB_CTRL_SET_SEC_SIZE, &sec_size);
+    fdb_tsdb_control(tsdb, FDB_TSDB_CTRL_SET_MAX_SIZE,  &db_size);
+
+    if (fdb_tsdb_init(tsdb, "logmgr",
+            LOGMGR_FLASHDB_PART_NAME, _logmgr_get_time, LOGMGR_FLASHDB_MAX_LEN, RT_NULL) != FDB_NO_ERR)
+    {
+        LOG_E("logmgr flashdb tsdb initialized failed.");
+        return -1;
+    }
+
+    /* write falsh tsdb data to file */
+    if (fdb_tsl_query_count(tsdb, 0, 0x7FFFFFFF, FDB_TSL_WRITE) > 0)
+    {
+        int fd = -1;
+
+        /* open the storge log file */
+        fd = open(LOGMGR_ABORT_FILE_PATH, O_RDWR | O_CREAT | O_TRUNC);
+        if (fd < 0)
+        {
+            LOG_E("open logmgr abort file failed.");
+            return -1;
+        }
+        lseek(fd, 0, SEEK_END);
+
+        /* set tsdb iterator callback */
+        fdb_tsl_iter(tsdb, _logmgr_tsl_cb, (void *)&fd);
+        fdb_tsl_clean(tsdb);
+        close(fd);
+    }
+#endif /* PKG_USING_FLASHDB */
+#ifdef LOGMGR_USING_CMBACKTRACE
+    extern int rt_cm_backtrace_init(void);
+    rt_cm_backtrace_init();
+#endif
+#ifdef PKG_USING_KDB
+    kdb_sys_init();
+    kdb_sys_start();
+#endif
+#ifdef PKG_USING_SYS_LOAD_MONITOR
+    sys_load_monitor_init();
+#endif
+    return 0;
+}
+
+/* logmgr customize console write operation */
+static rt_size_t _console_write(rt_device_t dev, rt_off_t pos, const void *buffer,
+                        rt_size_t size)
+{
+#ifdef PKG_USING_FLASHDB
+    struct fdb_blob blob;
+
+    if (!is_init)
+        return 0;
+
+    RT_ASSERT(buffer);
+
+    /* make log buffer blob */
+    if (fdb_tsl_append(&g_tsdb, fdb_blob_make(&blob, buffer, size)) != FDB_NO_ERR)
+    {
+        return 0;
+    }
+#endif /* PKG_USING_FLASHDB */
+
+    if (g_def_device)
+    {
+        rt_uint16_t old_flag = g_def_device->open_flag;
+
+        /* write log data to original console device */
+        g_def_device->open_flag |= RT_DEVICE_FLAG_STREAM;
+        rt_device_write(g_def_device, 0, buffer, size);
+        g_def_device->open_flag = old_flag;
+    }
+
+    return size;
+}
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops _console_ops =
+{
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    _console_write,
+    RT_NULL
+};
+#endif
+
+/* logmgr customize console initialized */
+static int _logmgr_console_init(void)
+{
+    rt_err_t ret = 0;
+    rt_device_t device = &g_console_dev;
+
+    device->type = RT_Device_Class_Char;
+#ifdef RT_USING_DEVICE_OPS
+    device->ops = &_console_ops;
+#else
+    device->init = RT_NULL;
+    device->open = RT_NULL;
+    device->close = RT_NULL;
+    device->read = RT_NULL;
+    device->write = _console_write;
+    device->control = RT_NULL;
+#endif
+    device->user_data = RT_NULL;
+
+    /* register virtual console device */
+    ret = rt_device_register(device, LOGMGR_CONSOLE_NAME,
+                             RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
+    if (ret != RT_EOK)
+    {
+        return -1;
+    }
+
+    if (g_def_device == RT_NULL)
+    {
+        g_def_device = rt_device_find(RT_CONSOLE_DEVICE_NAME);
+    }
+
+    return 0;
+}
+
+/* logmgr customize console switch for log storage */
+static void _logmgr_console_switch(rt_device_t device)
+{
+    rt_console_set_device(device->parent.name);
+}
+
+/* logmgr abort log print and storage initialize */
+int logmgr_abort_init(void)
+{
+    if (is_init == RT_TRUE)
+    {
+        LOG_W("logmgr abort is already initialized.");
+        return 0;
+    }
+
+    if (_logmgr_pkgs_init() < 0)
+    {
+        LOG_E("logmgr packages initialize failed.");
+        return -1;
+    }
+
+    if (_logmgr_console_init() < 0)
+    {
+        LOG_E("logmgr console initialized failed.");
+        return -1;
+    }
+
+    /* set system hardfault hook */
+    rt_hw_exception_install(logmgr_exception_hook);
+    /* set system assert hook */
+    rt_assert_set_hook(logmgr_assert_hook);
+
+    is_init = RT_TRUE;
+    LOG_I("logmgr abort initialized success.");
+
+    return 0;
+}