JZsdk_Logger.c 5.5 KB
/* 头文件 ------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>

#include "JZsdk_Logger.h"
#include <time.h>
#include "JZsdkLib.h"
#include <pthread.h>
#include <sys/time.h>

// 定义全局互斥锁
static pthread_mutex_t LogWriteMutex = PTHREAD_MUTEX_INITIALIZER;

/* 全局变量 ------------------------------------------------------------------*/
static struct timeval g_start_time;
static FILE *logFile;
static char LogFileName[JZSDK_FILENAME_SIZE];

/* 函数声明 ------------------------------------------------------------------*/

static void *MonitorTask(void *arg)
{
    while (1)
    {
        delayS(10);
        USER_LOG_DEBUG("Monitor");
    }
}



static int Log_Monitor()
{
    pthread_t work_mode_task;
	pthread_attr_t task_attribute; //线程属性
	pthread_attr_init(&task_attribute);  //初始化线程属性
	pthread_attr_setdetachstate(&task_attribute, PTHREAD_CREATE_DETACHED);      //设置线程属性
	int timer = pthread_create(&work_mode_task,&task_attribute,MonitorTask,NULL);		//线程
    if(timer != 0)
    {
        printf("创建计时线程失败!\n");
    }
}

void createJZLOGFolder() 
{
    const char *path = "/root/sdcard/JZLOG";

    // 使用系统命令检测路径是否存在
    char command[100];
    snprintf(command, sizeof(command), "if [ ! -d \"%s\" ]; then mkdir -p \"%s\"; fi", path, path);
    JZsdk_RunSystemCmd(command);
}

int ReadLogNumFromFile() 
{
    const char *path = "/root/sdcard/JZLOG/thelast";
    int logNum = 0;

    FILE *file = fopen(path, "r");
    if (file == NULL) 
    {
        // 如果文件不存在,则创建并设置LogNum为0
        file = fopen(path, "w");
        fprintf(file, "%d", logNum);
    } 
    else 
    {
        // 从文件中读取LogNum,并自增1
        fscanf(file, "%d", &logNum);
        logNum++;
        fclose(file);

        // 将新的LogNum写回文件中
        file = fopen(path, "w");
        fprintf(file, "%d", logNum);
    }
    fclose(file);

    return logNum;
}

T_JZsdkReturnCode JZsdk_LoggerInit()
{
    //1、记录启动时间
    gettimeofday(&g_start_time, 0);

    //2、检查是否存在log文件,不在则创建
    createJZLOGFolder();

    //3、获取本地log个数
    int LogNum = ReadLogNumFromFile();

    //4、获取本地时间,拼接出log文件名
    time_t current_time;
    struct tm *info;
    char timeString[80];
    time(&current_time);
    info = localtime(&current_time);
    strftime(timeString, sizeof(timeString), "%Y-%m-%d-%H-%M-%S", info);
    snprintf(LogFileName, sizeof(LogFileName), "/root/sdcard/JZLOG/%d-%s", LogNum, timeString);

    printf("LogFileName:%s\n",LogFileName);

    // 在主函数或初始化阶段初始化互斥锁
    pthread_mutex_init(&LogWriteMutex, NULL);  

    //5、打开记录文件
    logFile = fopen(LogFileName, "w");
    if (logFile == NULL) {
        // 文件打开失败,输出错误消息
        printf("Failed to open file: %s", LogFileName);
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }

    //6、写入开始时间
    char logMessage[256];
    snprintf(logMessage,256,"LOG_FILE:%s\n",LogFileName);
    fprintf(logFile, "%s", logMessage); 

    fclose(logFile); 


    //设立监控
    Log_Monitor();
}


T_JZsdkReturnCode writeToLogFile(const char *data) 
{
    // 加锁
    pthread_mutex_lock(&LogWriteMutex);

    logFile = fopen(LogFileName, "a"); // 使用"a"模式打开文件,以在末尾追加数据

    if (logFile == NULL) {
        // 文件打开失败,输出错误消息
        printf("Failed to open file: %s", LogFileName);
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }

    fprintf(logFile, "%s", data); // 写入新的数据

    fclose(logFile);

    // 解锁
    pthread_mutex_unlock(&LogWriteMutex);
}

void JZsdk_UserLogOutput(E_JZsdkConsoleLogLevel level, const char *fmt, ...)
{
    // 将日志级别转换为相应的字符串
    const char *JZSDK_LOGGER_CONSOLE_LOG_LEVEL = "";
    switch (level) {
        case JZSDK_LOGGER_CONSOLE_LOG_LEVEL_DEBUG:
            JZSDK_LOGGER_CONSOLE_LOG_LEVEL = "DEBUG";
            break;
        case JZSDK_LOGGER_CONSOLE_LOG_LEVEL_INFO:
            JZSDK_LOGGER_CONSOLE_LOG_LEVEL = "INFO";
            break;
        case JZSDK_LOGGER_CONSOLE_LOG_LEVEL_WARN:
            JZSDK_LOGGER_CONSOLE_LOG_LEVEL = "WARNING";
            break;
        case JZSDK_LOGGER_CONSOLE_LOG_LEVEL_ERROR:
            JZSDK_LOGGER_CONSOLE_LOG_LEVEL = "ERROR";
            break;
        default:
            break;
    }

    // 使用可变参数处理传入的格式化字符串和可变参数
    va_list args;
    va_start(args, fmt);

    // 格式化日志消息
    char logMessage[512];
    memset(logMessage, 0, sizeof(logMessage));
    vsprintf(logMessage, fmt, args);

    va_end(args);

    struct timeval current_time;
    gettimeofday(&current_time, 0);

    long seconds = current_time.tv_sec - g_start_time.tv_sec;
    long microseconds = current_time.tv_usec - g_start_time.tv_usec;
    double elapsed = seconds + microseconds*1e-6;

    // 执行具体的日志输出操作
    char finalLogMessage[512];
    snprintf(finalLogMessage, 512, "[%s][%.4f]%s\n", JZSDK_LOGGER_CONSOLE_LOG_LEVEL, elapsed, logMessage);

    printf("%s",finalLogMessage);


    //写入日志
    writeToLogFile(finalLogMessage);
}