From e6670a19bd27a0751064ab3b5e688e629076fff4 Mon Sep 17 00:00:00 2001 From: lucius Date: Mon, 4 Aug 2025 17:04:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=EF=BC=9AREADME?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 28 ++++ program/Makefile | 39 +++++ program/include/printlog.h | 178 +++++++++++++++++++++++ program/jni/Android.mk | 17 +++ program/jni/Application.mk | 1 + program/main.c | 82 +++++++++++ program/printlog.c | 245 ++++++++++++++++++++++++++++++++ project/PrintLOG.code-workspace | 8 ++ 8 files changed, 598 insertions(+) create mode 100644 README.md create mode 100644 program/Makefile create mode 100644 program/include/printlog.h create mode 100644 program/jni/Android.mk create mode 100644 program/jni/Application.mk create mode 100644 program/main.c create mode 100644 program/printlog.c create mode 100644 project/PrintLOG.code-workspace diff --git a/README.md b/README.md new file mode 100644 index 0000000..f3ad73d --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +## V1.1.0 + +### 新增: + +1、调试信息输出可选(EWID) + +2、调试信息着色(E:Red、W:Yellow、I:Green、D:Blue) + +## V1.2.0 + +### 新增: + + 不同文件调试信息可过滤 + +## V1.2.1 + +### 优化: + + README + +## 附言 + +PrintLOG + +1. 不同等级(EWID)调试信息可过滤 +2. 不同等级调试信息着色(E:Red、W:Yellow、I:Green、D:Blue) +3. 不同文件调试信息可过滤 +4. 编译:gcc main.c printlog.c -o main -I./include -lpthread diff --git a/program/Makefile b/program/Makefile new file mode 100644 index 0000000..7f0dfe5 --- /dev/null +++ b/program/Makefile @@ -0,0 +1,39 @@ +# include ../../Rules.make + +CFLAGS += -I./include -fPIC +TARGET_LIB_DIR := libprintlog + +SOURCES = $(wildcard *.c) +DEP = $(wildcard *.h) +OBJS = $(patsubst %.c, %.o,$(SOURCES)) +CROSS_DEF = $(subst -,_,$(CROSS_COMPILE)) + +TARGET_SO:=libprintlog.so +TARGET_A:=libprintlog.a + +all: $(TARGET_SO) $(TARGET_A) + +$(TARGET_SO): $(OBJS) + if [ ! -d $(TARGET_LIB_DIR) ]; then mkdir -p $(TARGET_LIB_DIR); fi; + $(CC) $(CFLAGS) -shared -o $(TARGET_LIB_DIR)/$@ $(OBJS) + + +$(TARGET_A): $(OBJS) + if [ ! -d $(TARGET_LIB_DIR) ]; then mkdir -p $(TARGET_LIB_DIR); fi; + $(AR) -rcs $(TARGET_LIB_DIR)/$@ $(OBJS) + + +$(OBJS): %.o: %.c $(DEP) + $(CC) $(CFLAGS) -c $< -o $@ + +clean: + rm -f *~ *.swp $(OBJS) a.out *.gc* + +cleanall: + rm -rf $(OBJS) + rm -rf *.gc* + rm -rf $(TARGET_LIB_DIR)/$(TARGET_SO) + rm -rf $(TARGET_LIB_DIR)/$(TARGET_A) + rm *.h~ -rf + rm *.c~ -rf + rm *.d -rf diff --git a/program/include/printlog.h b/program/include/printlog.h new file mode 100644 index 0000000..2decde8 --- /dev/null +++ b/program/include/printlog.h @@ -0,0 +1,178 @@ +/* + * @Author: Lucius + * @Date: 2023-03-25 14:05:20 + * @LastEditTime: 2023-03-27 17:11:09 + * @LastEditors: Lucius + * @Description: + * @FilePath: /23Mar25_PrintLOG/program/include/printlog.h + */ +#ifndef PRINT_LOG_H_ +#define PRINT_LOG_H_ + +#define ERROR_LOG_OK 0 /**< 错误日记ok标识*/ +#define ERROR_LOG_SET_TYPE -1 /**< 错误日记设置类型*/ + +#define PRINT_RUN_MODE 1 /**< 打印运行的模式*/ +#define PRINT_PROCESS_MODE 0 /**< 打印进程模式*/ +#define PRINT_THREAD_MODE 1 /**< 打印线程模式*/ + +/** 打印日记的类型*/ +enum __PRINT_LOG_TYPE +{ + LOG_TYPE_NULL = 0x0, /**< 不打印调试信息 */ + LOG_TYPE_ERROR = (1 << 0), /**< 打印错误调试信息 */ + LOG_TYPE_WARNING = (1 << 1), /**< 打印警告调试信息 */ + LOG_TYPE_INFO = (1 << 2), /**< 打印提示调试信息 */ + LOG_TYPE_DEBUG = (1 << 3), /**< 打印调试信息 */ +}; + +enum __PRINT_LOG_DEBUGFLAG +{ + dDebugFlag_main = 0, + dDebugFlag_Max +}; + +void SetDebugFlag(unsigned int tInputDebugFlag); + +int HaveDebugFlag(unsigned int tInputDebugFlag); + +/** + * \fn int SetLogType(char logType, int enable) + * \brief 设置打印类型 + * \param logType [in] 打印信息的类型 + * \code + enum __PRINT_LOG_TYPE + { + LOG_TYPE_NULL = 0x0, // 不打印调试信息 + LOG_TYPE_ERROR = (1 << 0), // 打印错误调试信息 + LOG_TYPE_WARNING = (1 << 1), // 打印警告调试信息 + LOG_TYPE_INFO = (1 << 2), // 打印提示调试信息 + LOG_TYPE_DEBUG = (1 << 3), // 打印调试信息 + }; + * \endcode + * \param enable [in] 设置相应类型是否生效 \n + * 1:开启 \n + * 0:关闭 + * \return + * 1 : 设置成功 \n + * 0 : 设置失败 + * \sa __PRINT_LOG_TYPE + */ +int SetLogType(char logType, int enable); + +/** + * \fn void SetLogTypesByParams(char *pParams) + * \brief 通过参数设置打印类型,功能类型SetLogType函数。 + * \param pParams [in] 打印类型描述参数 \n + * 字符串中包含如下字母 \n + * E:打印错误调试信息 \n + * W:打印警告调试信息 \n + * I:打印提示调试信息 \n + * D:打印调试信息 \n + * \return 无 + */ +void SetLogTypesByParams(char *pParams); + +/** + * \fn int SetprocessName(const char *pFileName) + * \brief 设置进程打印的文件名。 + * \param pFileName [in] 文件名描述 + * \return + * < 0:设置失败 \n + * 0: 设置成功 + */ +int SetprocessName(const char *pFileName); + +/** + * \fn int SetPrintParameter(int parameterCode, char *parameterValue, int maxValueLen) + * \brief 设置打印库参数。 + * \param parameterCode [in] 参数编码 + * \code + * #define PRINT_PROCESS_MODE 0 //进程模式 + * #define PRINT_THREAD_MODE 1 //线程模式 + * \endcode + * \param parameterValue [out] 参数值 + * \param maxValueLen [in] 参数最大长度 + * + * \return + * < 0:设置失败 \n + * 0:设置成功 + */ +int SetPrintParameter(int parameterCode, int *parameterValue, int maxValueLen); + +/** + * \fn int GetLogType(void) + * \brief 获得打印类型 + * \param 无 + * \return 返回打印类型 + */ +int GetLogType(void); + +/** + * \fn void PrintLog(enum __PRINT_LOG_DEBUGFLAG debugflag, enum __PRINT_LOG_TYPE logType, const char *pFile, const char *pFunction, + int line, const char *pFormat, ...) + * \brief 打印格式化信息。 + * \param logType [in] 打印信息的类型:error、warning、info + * \param pFile [in] 打印函数所在的文件名 + * \param pFunction [in] 打印代码所在的函数名 + * \param line [in] 打印代码所在的文件的行数 + * \param pFormat [in] 打印格式化信息 + * + * \return 无 + */ +void PrintLog(enum __PRINT_LOG_DEBUGFLAG debugflag, enum __PRINT_LOG_TYPE logType, const char *pFile, const char *pFunction, + int line, const char *pFormat, ...); + +/** + * \def _PrintLog_(type, fmt...) + * \brief 打印日记 + * \param type [in] 类型 + * \code + enum __PRINT_LOG_TYPE + { + LOG_TYPE_NULL = 0x0, // 不打印调试信息 + LOG_TYPE_ERROR = (1 << 0), // 打印错误调试信息 + LOG_TYPE_WARNING = (1 << 1), // 打印警告调试信息 + LOG_TYPE_INFO = (1 << 2), // 打印提示调试信息 + LOG_TYPE_DEBUG = (1 << 3), // 打印调试信息 + }; + * \endcode + * \param fmt [in] 格式 + */ +#define _PrintLog_(debugflag, type, fmt...) \ + PrintLog(debugflag, type, __FILE__, __FUNCTION__, __LINE__, fmt) + +/* 打印不同类型信息 */ +/** + * \def PrintErr(fmt...) + * \brief 打印错误信息 + * \param fmt [in] 格式 + * \sa _PrintLog_ + */ +#define PrintErr(debugflag, fmt...) _PrintLog_(debugflag, LOG_TYPE_ERROR, fmt) + +/** + * \def PrintWarn(fmt...) + * \brief 打印警告信息 + * \param fmt [in] 格式 + * \sa _PrintLog_ + */ +#define PrintWarn(debugflag, fmt...) _PrintLog_(debugflag, LOG_TYPE_WARNING, fmt) + +/** + * \def PrintInfo(fmt...) + * \brief 打印信息 + * \param fmt [in] 格式 + * \sa _PrintLog_ + */ +#define PrintInfo(debugflag, fmt...) _PrintLog_(debugflag, LOG_TYPE_INFO, fmt) + +/** + * \def PrintDebug(fmt...) + * \brief 打印调试信息 + * \param fmt [in] 格式 + * \sa _PrintLog_ + */ +#define PrintDebug(debugflag, fmt...) _PrintLog_(debugflag, LOG_TYPE_DEBUG, fmt) + +#endif /* DEBUGLOG_H_ */ diff --git a/program/jni/Android.mk b/program/jni/Android.mk new file mode 100644 index 0000000..4499392 --- /dev/null +++ b/program/jni/Android.mk @@ -0,0 +1,17 @@ +LOCAL_PATH := $(call my-dir) + +COMPILE = static + +ifeq ($(COMPILE), static) +include $(CLEAR_VARS) + +LOCAL_MODULE := printlog +include $(BUILD_STATIC_LIBRARY) +else +include $(CLEAR_VARS) +LOCAL_MODULE := printlog + +LOCAL_LDLIBS += -llog +include $(BUILD_SHARED_LIBRARY) + +endif \ No newline at end of file diff --git a/program/jni/Application.mk b/program/jni/Application.mk new file mode 100644 index 0000000..515fda4 --- /dev/null +++ b/program/jni/Application.mk @@ -0,0 +1 @@ +include ../../ApplicationRules.mk diff --git a/program/main.c b/program/main.c new file mode 100644 index 0000000..adbb13f --- /dev/null +++ b/program/main.c @@ -0,0 +1,82 @@ +/* + * @Author: Lucius + * @Date: 2023-03-25 14:05:20 + * @LastEditTime: 2023-03-27 17:18:47 + * @LastEditors: Lucius + * @Description: + * @FilePath: /23Mar25_PrintLOG/program/main.c + */ +#include +#include +#include +#include +#include "printlog.h" + +void thread_func(void *arg) +{ + char *str = (char *)arg; + PrintDebug(dDebugFlag_main, "Child thread: I'm child thread, arg = %s", str); + + // 子线程do something... + while (1) + { + PrintErr(dDebugFlag_main, "线程循环中。。。"); + sleep(2); + PrintWarn(dDebugFlag_main, "线程循环中。。。"); + sleep(2); + PrintInfo(dDebugFlag_main, "线程循环中。。。"); + sleep(2); + PrintDebug(dDebugFlag_main, "线程循环中。。。"); + sleep(2); + } + + // 退出子线程 + PrintDebug(dDebugFlag_main, "Child thread: I'll execute pthread_exit()"); + pthread_exit(NULL); + + /*此处不会再执行了*/ + PrintDebug(dDebugFlag_main, "xxxxxxxxxxxxxxxxxxxxxxxxxx"); + return; +} + +int main(int argc, char **argv) +{ +#if 1 + SetDebugFlag(dDebugFlag_main); +#endif + if (argc > 1) + { + int value = 0; + SetLogTypesByParams((char *)argv[1]); + value = PRINT_PROCESS_MODE; + SetPrintParameter(PRINT_RUN_MODE, &value, sizeof(value)); + SetprocessName("main"); + } + + pthread_t tid; + + // 这个本身是一个进程,我是在同一进程中创建多个线程, + // 同时我们一般把主流程叫主线程 + // PrintInfo("Main thread: I'll create some child threads."); + + char *str = "Farsight thread demo"; + pthread_create(&tid, NULL, (void *)thread_func, (void *)str); + + // PrintInfo("Main thread: After created thread!"); + + while (1) + { + PrintErr(dDebugFlag_main, "进程循环中。。。"); + sleep(1); + PrintWarn(dDebugFlag_main, "进程循环中。。。"); + sleep(1); + PrintInfo(dDebugFlag_main, "进程循环中。。。"); + sleep(1); + PrintDebug(dDebugFlag_main, "进程循环中。。。"); + sleep(1); + } + + PrintInfo(dDebugFlag_main, "Main thread: Before pthread_join()!"); + pthread_join(tid, NULL); // 阻塞等待子线程退出,回收子线程所占用内核中8KB物理内存,避免子线程成为僵尸 + PrintInfo(dDebugFlag_main, "Main thread: After pthread_join()!"); +} \ No newline at end of file diff --git a/program/printlog.c b/program/printlog.c new file mode 100644 index 0000000..ce084ed --- /dev/null +++ b/program/printlog.c @@ -0,0 +1,245 @@ +/* + * @Author: Lucius + * @Date: 2023-03-25 14:05:20 + * @LastEditTime: 2023-03-27 17:00:03 + * @LastEditors: Lucius + * @Description: + * @FilePath: /23Mar25_PrintLOG/program/printlog.c + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "printlog.h" + +typedef struct _threadLogInfo +{ + pthread_t owner; + char threadName[24]; +} TThreadLogInfo, *PThreadLogInfo; + +static char gLogType = 0 /*LOG_TYPE_ERROR | LOG_TYPE_WARNING | LOG_TYPE_INFO | LOG_TYPE_DEBUG*/; +static char gFileName[24] = {0}; + +static int gRunMode = PRINT_PROCESS_MODE; +static int gMaxThreadNumber = 0; +static TThreadLogInfo *gpThreadLogInfo = ((void *)0); +static int gThreadCount = 0; +static pthread_mutex_t gThreadLock; +static int gThreadFlag = 0; +static int gErrLogSaveSize = 1020 * 1024; +static unsigned int gErrLogDelSize = 4 * 1024; +static unsigned int gFileLogLevel = 0x00; + +#define PRINT_LOG_TAG +#define PRINT_LOGUNKNOW(...) printf(__VA_ARGS__) +#define PRINT_LOGD(...) printf(__VA_ARGS__) +#define PRINT_LOGI(...) printf(__VA_ARGS__) +#define PRINT_LOGW(...) printf(__VA_ARGS__) +#define PRINT_LOGE(...) printf(__VA_ARGS__) +#define VPRINT_LOGD(fmt, args) + +unsigned int pDebugFlag[(dDebugFlag_Max + 7) / 8] = {0}; + +void SetDebugFlag(unsigned int tInputDebugFlag) +{ + pDebugFlag[tInputDebugFlag / 8] |= (1 << (tInputDebugFlag % 8)); +} + +int HaveDebugFlag(unsigned int tInputDebugFlag) +{ + if (pDebugFlag[tInputDebugFlag / 8] & (1 << (tInputDebugFlag % 8))) + { + return 1; + } + return 0; +} + +int SetLogType(char logType, int enable) +{ + if (1 == enable) + { + gLogType = gLogType | logType; + } + else if (0 == enable) + { + gLogType = gLogType & (~logType); + } + else + { + return ERROR_LOG_SET_TYPE; + } + + return ERROR_LOG_OK; +} + +void SetLogTypesByParams(char *pParams) +{ + if (((void *)0) != strchr(pParams, 'E')) + { + SetLogType(LOG_TYPE_ERROR, 1); + } + if (((void *)0) != strchr(pParams, 'W')) + { + SetLogType(LOG_TYPE_WARNING, 1); + } + if (((void *)0) != strchr(pParams, 'I')) + { + SetLogType(LOG_TYPE_INFO, 1); + } + if (((void *)0) != strchr(pParams, 'D')) + { + SetLogType(LOG_TYPE_DEBUG, 1); + } +} + +int SetprocessName(const char *pFileName) +{ + int ret = 0; + + snprintf(gFileName, sizeof(gFileName), "%s", pFileName); + + return ret; +} + +int SetPrintParameter(int parameterCode, int *parameterValue, int maxValueLen) +{ + int ret = 0; + switch (parameterCode) + { + case PRINT_RUN_MODE: + { + int runMode = *parameterValue; + if ((runMode != PRINT_PROCESS_MODE) && (runMode != PRINT_THREAD_MODE)) + { + break; + } + gRunMode = *parameterValue; + break; + } + default: + { + break; + } + } + return ret; +} + +static int GetCurPrintDateTime(char *pOutBuf, int maxOutBufLen) +{ + + char tmpYear[5]; + + struct timeval tv; + struct timezone tz; + struct tm *pCurLocalDateTime = ((void *)0); + + if (((void *)0) == pOutBuf) + { + return -1; + } + + memset(tmpYear, 0, sizeof(tmpYear)); + memset(pOutBuf, 0, maxOutBufLen); + + gettimeofday(&tv, &tz); + pCurLocalDateTime = localtime(&tv.tv_sec); + + snprintf(tmpYear, sizeof(tmpYear), "%04d", pCurLocalDateTime->tm_year + 1900); + + snprintf(pOutBuf, maxOutBufLen, "%s-%02d-%02dT%02d:%02d:%02d.%03ld", + tmpYear, pCurLocalDateTime->tm_mon + 1, pCurLocalDateTime->tm_mday, + pCurLocalDateTime->tm_hour, pCurLocalDateTime->tm_min, pCurLocalDateTime->tm_sec, tv.tv_usec / 1000); + + return 0; +} + +int GetLogType(void) +{ + return gLogType; +} + +void PrintLog(enum __PRINT_LOG_DEBUGFLAG debugflag, enum __PRINT_LOG_TYPE logType, const char *pFile, const char *pFunction, + int line, const char *pFormat, ...) +{ + if (!HaveDebugFlag(debugflag)) + { + return; + } + va_list args; + char filebuf[1024] = {0}; + int cnt = 0; + + const char *pPreFix = ((void *)0); + + if (0 == (logType & gLogType) && 0 == (logType & gFileLogLevel)) + return; + + switch (logType) + { + case LOG_TYPE_INFO: + { + pPreFix = "\033[1;32;40mInfo\033[0m"; + break; + } + case LOG_TYPE_WARNING: + { + pPreFix = "\033[1;33;40mWarning\033[0m"; + break; + } + case LOG_TYPE_ERROR: + { + pPreFix = "\033[1;31;40mError\033[0m"; + break; + } + case LOG_TYPE_DEBUG: + { + + pPreFix = "\033[1;34;40mDebug\033[0m"; + break; + } + default: + { + + pPreFix = "Unknown"; + break; + } + } + + char curTime[1024]; + GetCurPrintDateTime(curTime, sizeof(curTime)); + + cnt = sprintf(filebuf, "[%s:%s] %s [%s %s %d]: ", + gFileName, curTime, pPreFix, pFile, pFunction, line); + + if (0 != (logType & gLogType)) + { + + printf("%s", filebuf); + + va_start(args, pFormat); + + vprintf(pFormat, args); + + va_end(args); + + printf("\n"); + } + + va_start(args, pFormat); + if (cnt < 512) + { + vsnprintf(filebuf + cnt, 512, pFormat, args); + } + va_end(args); + + fflush(stdout); + + return; +} diff --git a/project/PrintLOG.code-workspace b/project/PrintLOG.code-workspace new file mode 100644 index 0000000..bab1b7f --- /dev/null +++ b/project/PrintLOG.code-workspace @@ -0,0 +1,8 @@ +{ + "folders": [ + { + "path": ".." + } + ], + "settings": {} +} \ No newline at end of file