日志打印输出

#define LOG_BUFFER_LEN (1024)
static char log_buf[LOG_BUFFER_LEN] = {0};
static OsiLockObj_t log_locker = NULL;

#define LOG_FILE_ENABLE (0)
#if LOG_FILE_ENABL
#define LOG_FILE_DIR "/tmp/log.txt"
static FILE* log_file_hd = NULL;
static volatile int log_file_reopen = 0;
static int log_file_write_len = 0;
#endif

static void log_file_open(void) {
#if LOG_FILE_ENABLE
    if (log_file_hd)
        return;
    log_file_hd = fopen(LOG_FILE_DIR, "aw");
    if (log_file_hd == NULL) {
        printf("%s %s failed: %d %s\r\n", __FUNCTION__, LOG_FILE_DIR, errno, strerror(errno));
    } else {
        printf("%s\n", __FUNCTION__);
    }
#endif
}

static void log_file_close(void) {
#if LOG_FILE_ENABLE
    osi_LockObjLock(&log_locker);
    if (log_file_hd != NULL) {
        fclose(log_file_hd);
        log_file_hd = NULL;
        printf("%s\n", __FUNCTION__);
    }
    osi_LockObjUnlock(&log_locker);
#endif
}

static void log_file_write(const char* data) {
#if LOG_FILE_ENABLE
    osi_LockObjLock(&log_locker);
    if (log_file_hd == NULL || log_file_write_len > 50 * 1024) {
        pthread_mutex_unlock(&log_locker);
        return;
    }
    if (fwrite(data, 1, strlen(data), log_file_hd) <= 0) {
        printf("%s failed\n", __FUNCTION__);
    } else {
        log_file_write_len = log_file_write_len + strlen(data);
    }
    fflush(log_file_hd);
    osi_LockObjUnlock(&log_locker);
#endif
}


void log_printf(_LOG_TYPE_E type, const char* func, const int line, const char* format, ...) {
    if (log_locker == NULL) {
        osi_LockObjCreate(&log_locker);
    }
    osi_LockObjLock(&log_locker);

    va_list ap;
    va_start(ap, format);

    switch (type) {
        case LOG_TYPE_ERROR:
            snprintf(log_buf, LOG_BUFFER_LEN, "%s", "E/");
            break;
        case LOG_TYPE_WARN:
            snprintf(log_buf, LOG_BUFFER_LEN, "%s", "W/");
            break;
        case LOG_TYPE_DEBUG:
            snprintf(log_buf, LOG_BUFFER_LEN, "%s", "D/");
            break;
        case LOG_TYPE_PRINT:
            snprintf(log_buf, LOG_BUFFER_LEN, "%s", "I/");
            break;
        default:
            break;
    }
    int idx = strlen(log_buf);

    if (type == LOG_TYPE_ERROR || type == LOG_TYPE_WARN) {
        snprintf(log_buf + idx, LOG_BUFFER_LEN - idx, "[%010d](%s:%d)", common_get_current_ms(),
                 func, line);
    } else if (type == LOG_TYPE_DEBUG) {
        snprintf(log_buf + idx, LOG_BUFFER_LEN - idx, "[%010d](%s)", common_get_current_ms(), func);
    } else {
        snprintf(log_buf + idx, LOG_BUFFER_LEN - idx, "[%010d]", common_get_current_ms());
    }
    idx = strlen(log_buf);

    vsnprintf(log_buf + idx, LOG_BUFFER_LEN - idx, format, ap);
    va_end(ap);

    if (type == LOG_TYPE_ERROR) {
        printf(B_RED("%s"), log_buf);
    } else if (type == LOG_TYPE_WARN) {
        printf(B_MAGENTA("%s"), log_buf);
    } else if (type == LOG_TYPE_DEBUG) {
        printf("%s", log_buf);
    } else if (type == LOG_TYPE_PRINT) {
        printf("%s", log_buf);
    }

    osi_LockObjUnlock(&log_locker);

    log_file_write(log_buf);
}

void log_printf(_LOG_TYPE_E type, const char* func, const int line, const char* format, ...);
#define log_e(format, args...) log_printf(LOG_TYPE_ERROR, __FUNCTION__, __LINE__, format, ##args)
#define log_e_tag(tag, format, arg...) \
    log_printf(LOG_TYPE_ERROR, __FUNCTION__, __LINE__, format, ##args)
#define log_i(format, args...) log_printf(LOG_TYPE_PRINT, __FUNCTION__, __LINE__, format, ##args)
#define log_i_tag(tag, format, args...) \
    log_printf(LOG_TYPE_PRINT, __FUNCTION__, __LINE__, format, ##args)
#define log_d(format, args...) log_printf(LOG_TYPE_DEBUG, __FUNCTION__, __LINE__, format, ##args)
#define log_d_tag(tag, format, args...) \
    log_printf(LOG_TYPE_DEBUG, __FUNCTION__, __LINE__, format, ##args)
#define log_w(format, args...) log_printf(LOG_TYPE_WARN, __FUNCTION__, __LINE__, format, ##args)
#define log_w_tag(tag, format, args...) \
    log_printf(LOG_TYPE_WARN, __FUNCTION__, __LINE__, format, ##args)

AI 代码审查Review工具 是一个旨在自动化代码审查流程的工具。它通过集成版本控制系统(如 GitHub 和 GitLab)的 Webhook,利用大型语言模型(LLM)对代码变更进行分析,并将审查意见反馈到相应的 Pull Request 或 Merge Request 中。此外,它还支持将审查结果通知到企业微信等通讯工具。 一个基于 LLM 的自动化代码审查助手。通过 GitHub/GitLab Webhook 监听 PR/MR 变更,调用 AI 分析代码,并将审查意见自动评论到 PR/MR,同时支持多种通知渠道。 主要功能 多平台支持: 集成 GitHub 和 GitLab Webhook,监听 Pull Request / Merge Request 事件。 智能审查模式: 详细审查 (/github_webhook, /gitlab_webhook): AI 对每个变更文件进行分析,旨在找出具体问题。审查意见会以结构化的形式(例如,定位到特定代码行、问题分类、严重程度、分析和建议)逐条评论到 PR/MR。AI 模型会输出 JSON 格式的分析结果,系统再将其转换为多条独立的评论。 通用审查 (/github_webhook_general, /gitlab_webhook_general): AI 对每个变更文件进行整体性分析,并为每个文件生成一个 Markdown 格式的总结性评论。 自动化流程: 自动将 AI 审查意见(详细模式下为多条,通用模式下为每个文件一条)发布到 PR/MR。 在所有文件审查完毕后,自动在 PR/MR 中发布一条总结性评论。 即便 AI 未发现任何值得报告的问题,也会发布相应的友好提示和总结评论。 异步处理审查任务,快速响应 Webhook。 通过 Redis 防止对同一 Commit 的重复审查。 灵活配置: 通过环境变量设置基
参考提供的引用,未直接提及tcl电视开启调试并实现日志打印输出的方法。不过,可以从相关信息中得到一些思路。 日志等级方面,常见的日志等级有错误、警告、信息、调试和详细,对应的宏分别为ESP_LOGE(错误)、ESP_LOGW(警告)、ESP_LOGI(信息)、ESP_LOGD(调试)、ESP_LOGV(详细),若要实现日志打印输出,可根据不同需求选择合适的日志等级[^1]。 对于调试过程,以其他场景为例,会先运行.cfg中的语句,再调用tcl_port语句,若处于调试模式则不会调用后面的语句。若要查看调试信息,可单独打开一个openocd服务器。在代码层面,可使用初始化SEGGER_RTT_Init(),并在循环中调用SEGGER_RTT_printf(0, "time:%ld\r\n", xTaskGetTickCount())来进行日志输出[^2]。 在控制输出和记录日志上,可通过一些命令实现。例如隐藏派生进程的输出使用log_user 0,打开日志文件记录所有输出使用log_file -a log,恢复输出显示使用log_user 1 ,还可继续与远程主机交互,如执行命令send "ls\r",并使用expect -re ".*\r\n"等待响应[^3]。 虽然这些信息不是直接针对tcl电视的,但可以推测tcl电视开启调试和日志打印输出可能需要: 1. 在tcl电视的系统设置中找到“关于”或“系统信息”选项,查看是否有“开发者选项”,若没有则连续点击“版本号”开启开发者选项。 2. 在开发者选项中找到“USB调试”并开启,若需要实现日志打印输出,可能需要通过连接电脑,使用相关的调试工具。 3. 编写或使用合适的代码来实现日志打印,可参考上述提到的日志等级和日志输出代码示例。例如在开发应用时,在代码中使用类似SEGGER_RTT_printf的函数来输出日志。 ### 代码示例 ```c #include <stdio.h> #define LOG_LEVEL_DEBUG #ifdef LOG_LEVEL_DEBUG #define LOG_DEBUG(format, ...) printf("[DEBUG] " format, ##__VA_ARGS__) #else #define LOG_DEBUG(format, ...) #endif int main() { LOG_DEBUG("This is a debug log.\n"); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值