Add new Log module and use clang-tidy in test code.

This commit is contained in:
xiaojiazhu 2023-09-08 08:10:30 -07:00
parent cee11f19a7
commit 9f9abd7130
22 changed files with 8195 additions and 5 deletions

View File

@ -26,7 +26,7 @@ set(IMPL_TARGET Hal)
add_library(${ABSTRACT_TARGET} STATIC ${ABSTRACT_SRC_FILES}) add_library(${ABSTRACT_TARGET} STATIC ${ABSTRACT_SRC_FILES})
target_link_libraries(${ABSTRACT_TARGET} StatusCode Log) target_link_libraries(${ABSTRACT_TARGET} StatusCode Log)
add_library(${IMPL_TARGET} STATIC ${IMPL_SRC_FILES}) add_library(${IMPL_TARGET} STATIC ${IMPL_SRC_FILES})
target_link_libraries(${IMPL_TARGET} ${ABSTRACT_TARGET} Log) target_link_libraries(${IMPL_TARGET} ${ABSTRACT_TARGET})
if ("${CLANG_TIDY_SUPPORT}" MATCHES "true") if ("${CLANG_TIDY_SUPPORT}" MATCHES "true")

View File

@ -2,6 +2,6 @@
# cmake_minimum_required(VERSION 2.8.0) # cmake_minimum_required(VERSION 2.8.0)
#Compile gtest for test code. #Compile gtest for test code.
add_subdirectory(ReturnCode) add_subdirectory(ReturnCode)
add_subdirectory(LogC) add_subdirectory(Log)

View File

@ -0,0 +1,55 @@
# include(${CMAKE_SOURCE_DIR}/build/independent_source.cmake)
include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake)
set(EXECUTABLE_OUTPUT_PATH ${TEST_OUTPUT_PATH}/bin)
include_directories(
.
./src
./include
${UTILS_SOURCE_PATH}/Log/include
${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include
${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/include
)
link_directories(
${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/lib
${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/lib
${LIBS_OUTPUT_PATH}
)
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
aux_source_directory(. SRC_FILES)
aux_source_directory(./src SRC_FILES)
set(TARGET_NAME LogTest)
add_executable(${TARGET_NAME} ${SRC_FILES})
target_link_libraries(${TARGET_NAME} Log gtest gmock pthread)
if(${COVERAGE_ON} MATCHES "true")
target_link_libraries(${TARGET_NAME} gcov)
endif()
if ("${CLANG_TIDY_SUPPORT}" MATCHES "true")
add_custom_target(
LogTest_code_check
COMMAND ${CLANG_TIDY_EXE}
-checks='${CLANG_TIDY_CHECKS}'
--header-filter=.*
--system-headers=false
${SRC_FILES}
${CLANG_TIDY_CONFIG}
# --line-filter='[{\"name\":\"${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include/getest/gtest.h\"}]'
--line-filter='[{\"name\":\"${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include/getest/*.h\"}]'
-p ${CMAKE_SOURCE_DIR_IPCSDK}/cmake-shell-linux
WORKING_DIRECTORY ${TEST_SOURCE_PATH}/utils/Log
)
add_custom_command(
TARGET ${TARGET_NAME}
PRE_BUILD
COMMAND make LogTest_code_check
WORKING_DIRECTORY ${PROJECT_ROOT_PATH}/cmake-shell-linux/
)
endif()

View File

@ -0,0 +1,9 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <thread>
#include <unistd.h>
int main(int argc, char *argv[])
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -0,0 +1,19 @@
#include "ILog.h"
// #include <gmock/gmock.h>
#include <gtest/gtest.h>
namespace ILogTest
{
// ../out/test/bin/ILogTest --gtest_filter=LogCTest.Demo
TEST(ILogTest, Demo)
{
CreateLogModule();
ILogInit(LOG_INSTANCE_TYPE_END);
LogInfo("hello world.");
LogError("create ... failed.");
LogDebug("a = %d b = %s", 124, "apple");
IHalUnInit();
DestroyLogModule();
}
} // namespace ILogTest

View File

@ -3,4 +3,3 @@
add_subdirectory(ReturnCode) add_subdirectory(ReturnCode)
add_subdirectory(StatusCode) add_subdirectory(StatusCode)
add_subdirectory(Log) add_subdirectory(Log)
add_subdirectory(LogC)

52
utils/Log/CMakeLists.txt Normal file
View File

@ -0,0 +1,52 @@
include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake)
set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH})
set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH})
include_directories(
./abstract
./src
./src/easyloggingpp
./include
)
#do not rely on any other library
# link_directories(
# ${EXTERNAL_SOURCE_PATH}/curl/curl-8.1.2/build/lib
# )
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
aux_source_directory(./abstract ABSTRACT_SRC_FILES)
aux_source_directory(./src IMPL_SRC_FILES)
aux_source_directory(./src/easyloggingpp EASYLOGGING_SRC_FILES)
set(ABSTRACT_TARGET LogAbstract)
set(IMPL_TARGET Log)
add_library(${ABSTRACT_TARGET} STATIC ${ABSTRACT_SRC_FILES})
# target_link_libraries(${ABSTRACT_TARGET} Log)
add_library(${IMPL_TARGET} STATIC ${IMPL_SRC_FILES} ${EASYLOGGING_SRC_FILES})
target_link_libraries(${IMPL_TARGET} ${ABSTRACT_TARGET})
if ("${CLANG_TIDY_SUPPORT}" MATCHES "true")
add_custom_target(
Log_code_check
COMMAND ${CLANG_TIDY_EXE}
-checks='${CLANG_TIDY_CHECKS}'
--header-filter=.*
--system-headers=false
${IMPL_SRC_FILES}
${ABSTRACT_SRC_FILES}
${CLANG_TIDY_CONFIG}
-p ${CMAKE_SOURCE_DIR_IPCSDK}/cmake-shell-linux
WORKING_DIRECTORY ${UTILS_SOURCE_PATH}/Log
)
add_custom_command(
TARGET ${IMPL_TARGET}
# TARGET ${ABSTRACT_TARGET}
PRE_BUILD
COMMAND make Log_code_check
WORKING_DIRECTORY ${PROJECT_ROOT_PATH}/cmake-shell-linux/
)
endif()

View File

@ -0,0 +1,43 @@
#include "ILog.h"
#include "ILogCpp.h"
#include <string.h>
static void ILogInitCallBack(ILog *object, const LogInstance log)
{
return ILogCpp::GetInstance()->Init(log);
}
static void ILogFree(ILog *object)
{
}
static int ILogPrintf(ILog *object, const char *function, const int line, const int type, const char *format, ...)
{
return 0;
}
static void ILogUnInitCallBack(ILog *object)
{
return ILogCpp::GetInstance()->UnInit();
}
static ILog default_log = {
.init = ILogInitCallBack,
.free = ILogFree,
.printf = ILogPrintf,
.un_init = ILogUnInitCallBack,
};
static ILog *log_instance = &default_log;
ILog *GetLogIntance(void)
{
return log_instance;
}
void NewILog(ILog **object)
{
if (!object || !(*object))
{
return;
}
memcpy(*object, &default_log, sizeof(ILog));
return;
}
void ResetHalImpl(ILog *impl)
{
log_instance->free(log_instance);
log_instance = impl;
}

View File

@ -0,0 +1,32 @@
#include "ILogCpp.h"
#include <memory>
std::shared_ptr<ILogCpp> &ILogCpp::GetInstance(std::shared_ptr<ILogCpp> *impl)
{
static std::shared_ptr<ILogCpp> instance = std::make_shared<ILogCpp>();
static bool instanceChanging = false;
if (impl && false == instanceChanging)
{
// Don't use std::mutex for runing faster.
// Sleep for difference thread to release instance.
instanceChanging = true;
// std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Don't sleep and make sure that start fast.
if (instance.use_count() == 1) // bug?
{
// LogInfo("Instance change succeed.\n");
// instance->UnInit();
// (*impl)->Init();
instance = *impl;
}
else
{
// LogError("[ error ] instance change failed, using by some one.\n");
}
instanceChanging = false;
}
if (instanceChanging)
{
static std::shared_ptr<ILogCpp> tmporaryInstance = std::make_shared<ILogCpp>();
return tmporaryInstance;
}
return instance;
}

60
utils/Log/include/ILog.h Normal file
View File

@ -0,0 +1,60 @@
#ifndef ILOG_H
#define ILOG_H
#ifdef __cplusplus
extern "C"
{
#endif
enum LogType
{
LOG_TYPE_VERBOSE = 0,
LOG_TYPE_DEBUG,
LOG_TYPE_INFORMATION,
LOG_TYPE_WARNING,
LOG_TYPE_ERROR,
LOG_TYPE_TRACE,
LOG_TYPE_TEST_TIPS,
LOG_TYPE_END
};
typedef struct LogSetting
{
const char *fileName; // File name of saving log.
const char *maxSize; // Max size of saving log.
} LogSetting;
enum LogInstance
{
LOG_SERIAL_PRINT = 0, // for serial print.
LOG_EASYLOGGING, // for easylogging++.
LOG_CAPTURE_LOG, // capture log to other who need it
LOG_INSTANCE_TYPE_END
};
#define LogVerbose(...) GetLogIntance()->printf(GetLogIntance(), __FUNCTION__, __LINE__, LOG_TYPE_VERBOSE, __VA_ARGS__)
#define LogDebug(...) GetLogIntance()->printf(GetLogIntance(), __FUNCTION__, __LINE__, LOG_TYPE_DEBUG, __VA_ARGS__)
#define LogInfo(...) GetLogIntance()->printf(GetLogIntance(), __FUNCTION__, __LINE__, LOG_TYPE_INFORMATION, __VA_ARGS__)
#define LogWarning(...) GetLogIntance()->printf(GetLogIntance(), __FUNCTION__, __LINE__, LOG_TYPE_WARNING, __VA_ARGS__)
#define LogError(...) GetLogIntance()->printf(GetLogIntance(), __FUNCTION__, __LINE__, LOG_TYPE_ERROR, __VA_ARGS__)
#define LogTrace(...) GetLogIntance()->printf(GetLogIntance(), __FUNCTION__, __LINE__, LOG_TYPE_TRACE, __VA_ARGS__)
typedef struct i_log ILog;
typedef struct i_log
{
void (*init)(ILog *, const LogInstance);
void (*free)(ILog *);
int (*printf)(ILog *, const char *, const int, const int, const char *, ...);
void (*un_init)(ILog *);
} ILog;
ILog *GetLogIntance(void);
void NewILog(ILog **object);
void ResetHalImpl(ILog *impl);
static inline void ILogInit(const LogInstance log)
{
return GetLogIntance()->init(GetLogIntance(), log);
}
static inline void IHalUnInit(void)
{
return GetLogIntance()->un_init(GetLogIntance());
}
void CreateLogModule(void);
void DestroyLogModule(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,14 @@
#ifndef ILOGCPP_H
#define ILOGCPP_H
#include "ILog.h"
#include <memory>
class ILogCpp
{
public:
ILogCpp() = default;
virtual ~ILogCpp() = default;
static std::shared_ptr<ILogCpp> &GetInstance(std::shared_ptr<ILogCpp> *impl = nullptr);
virtual void Init(const LogInstance &log) {}
virtual void UnInit(void) {}
};
#endif

View File

@ -0,0 +1,22 @@
#include "ILogMakePtr.h"
#include "ILog.h"
#include "ILogCpp.h"
#include "LogEasylogging.h"
#include "LogImpl.h"
#include <memory>
void CreateLogModule(void)
{
}
void DestroyLogModule(void)
{
}
std::shared_ptr<ILogCpp> ILogMakePtr::MakeLogImplPtr(void)
{
std::shared_ptr<ILogCpp> logImpl = std::make_shared<LogImpl>();
return logImpl;
}
std::shared_ptr<ILogCpp> ILogMakePtr::MakeLogEasylogging(const LogSetting *setting)
{
std::shared_ptr<ILogCpp> logImpl = std::make_shared<LogEasylogging>(setting);
return logImpl;
}

View File

@ -0,0 +1,23 @@
#ifndef ILOG_MAKE_PTR_H
#define ILOG_MAKE_PTR_H
#include "ILogCpp.h"
#include <iostream>
#include <memory>
class ILogMakePtr
{
public:
static std::shared_ptr<ILogMakePtr> &GetInstance(std::shared_ptr<ILogMakePtr> *impl = nullptr)
{
static std::shared_ptr<ILogMakePtr> instance = std::make_shared<ILogMakePtr>();
if (impl)
{
instance = *impl;
}
return instance;
}
ILogMakePtr() = default;
virtual ~ILogMakePtr() = default;
virtual std::shared_ptr<ILogCpp> MakeLogImplPtr(void);
virtual std::shared_ptr<ILogCpp> MakeLogEasylogging(const LogSetting *setting);
};
#endif

View File

@ -0,0 +1,88 @@
#include "ILog.h"
#include "LogEasylogging.h"
#include "easylogging++.h"
// #include <thread>
// #define ELPP_UNICODE // Define for easylogging
INITIALIZE_EASYLOGGINGPP // Init easylogging
// static bool initFlag = false; // Only used for init easyloggingpp
bool test = false;
LogEasylogging::LogEasylogging(const LogSetting *setting)
{
if (!setting)
{
return;
}
if (setting->fileName)
{
mFileName = setting->fileName;
}
if (setting->maxSize)
{
mMaxSize = setting->maxSize;
}
}
void LogEasylogging::Init(const LogInstance &log)
{
#if 0
el::Configurations conf("/home/xiaojiazhu/project/OS/OSThings/test/out/bin/default-logger.conf");
el::Loggers::reconfigureAllLoggers(conf);
#endif
// Set the log path.
if (mFileName.size() > 0)
{
el::Loggers::reconfigureAllLoggers(el::ConfigurationType::Filename, mFileName.c_str());
}
// Set the max size of log file.
// el::Loggers::reconfigureAllLoggers(el::ConfigurationType::MaxLogFileSize, "1048576");
if (mMaxSize.size() > 0)
{
el::Loggers::reconfigureAllLoggers(el::ConfigurationType::MaxLogFileSize, mMaxSize.c_str());
}
el::Loggers::reconfigureAllLoggers(el::ConfigurationType::Enabled, "true");
el::Loggers::reconfigureAllLoggers(el::ConfigurationType::ToFile, "true");
}
void LogEasylogging::UnInit(void)
{
el::Loggers::reconfigureAllLoggers(el::ConfigurationType::ToFile, "false");
el::Loggers::reconfigureAllLoggers(el::ConfigurationType::Enabled, "false");
}
// bool LogEasylogging::IsWorking()
// {
// return true;
// }
// int LogEasylogging::Log(const char *buff)
// {
// // LOG(INFO) << buff;
// return 0;
// }
// int LogEasylogging::InFo(const char *buff)
// {
// LOG(INFO) << buff;
// return 0;
// }
// int LogEasylogging::Warning(const char *buff)
// {
// LOG(WARNING) << buff;
// return 0;
// }
// int LogEasylogging::Error(const char *buff)
// {
// LOG(ERROR) << buff;
// return 0;
// }
// int LogEasylogging::Debug(const char *buff)
// {
// LOG(DEBUG) << buff;
// return 0;
// }
// int LogEasylogging::Trace(const char *buff)
// {
// LOG(TRACE) << buff;
// return 0;
// }

View File

@ -0,0 +1,23 @@
#ifndef LOG_EASYLOGGING_H
#define LOG_EASYLOGGING_H
#include "ILogCpp.h"
class LogEasylogging : public ILogCpp
{
public:
LogEasylogging(const LogSetting *setting);
virtual ~LogEasylogging() = default;
void Init(const LogInstance &log) override;
void UnInit(void) override;
// bool IsWorking(); // override;
// int Log(const char *buff); // override;
// int InFo(const char *buff); // override;
// int Warning(const char *buff); // override;
// int Error(const char *buff); // override;
// int Trace(const char *buff); // override;
// int Debug(const char *buff); // override;
private:
std::string mFileName; // File name of saving log.
std::string mMaxSize; // Max size of saving log.
};
#endif

View File

@ -0,0 +1,5 @@
// #include "LogImpl.h"
// int LogImpl::Log(const char *buff)
// {
// return printf("%s", buff);
// }

10
utils/Log/src/LogImpl.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef LOG_IMPL_H
#define LOG_IMPL_H
#include "ILogCpp.h"
class LogImpl : public ILogCpp
{
public:
LogImpl() = default;
virtual ~LogImpl() = default;
};
#endif

View File

@ -0,0 +1,9 @@
这是一个开源库的源码。
注意:
//1. 需要定义宏
//#define ELPP_UNICODE // Define for easylogging
2. 初始化
INITIALIZE_EASYLOGGINGPP // Init easylogging
//3. 支持多线程,在源码头文件"easyloggingpp.h"定义宏
//#define ELPP_THREAD_SAFE // Working in threads. Added by xiaojiazhu
4. ELPP_NO_DEFAULT_LOG_FILE 此宏屏蔽生成默认的log文件

View File

@ -0,0 +1,25 @@
* GLOBAL:
FORMAT = "%datetime | %level | %logger | %msg"
FILENAME = "/tmp/logs/myeasylog-configuration.cpp.log"
ENABLED = true
TO_FILE = true
TO_STANDARD_OUTPUT = true
SUBSECOND_PRECISION = 3
PERFORMANCE_TRACKING = false
MAX_LOG_FILE_SIZE = 2097152 ## Throw log files away after 2MB
* DEBUG:
FILENAME = "/tmp/logs/myeasylog-configuration.cpp-debug.log"
TO_STANDARD_OUTPUT = true
ENABLED = true ## We will set it to false after development completed
* WARNING:
FILENAME = "/tmp/logs/filename-with-time-%datetime{%H:%m}"
* TRACE:
TO_FILE = true ## Unnecessary configuration cuz its already true in GLOBAL but doing it anyway!
* VERBOSE:
FORMAT = "%datetime{%d/%M/%y} | %level-%vlevel | %msg"
## Error logs
* ERROR:
ENABLED = false
FILENAME = "/tmp/logs/myeasylog-configuration.cpp-error.log"
* FATAL:
ENABLED = false

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,7 @@ static const char *_PrintStringCode_(const StatusCode this)
LogError("Status code = [ %s ]\n", StatusCodeString[STATUS_CODE_INVALID_PARAMENTER]); LogError("Status code = [ %s ]\n", StatusCodeString[STATUS_CODE_INVALID_PARAMENTER]);
return StatusCodeString[STATUS_CODE_INVALID_PARAMENTER]; return StatusCodeString[STATUS_CODE_INVALID_PARAMENTER];
} }
static bool CodeEqual(const StatusCode code, const char *value) static const bool CodeEqual(const StatusCode code, const char *value)
{ {
if (memcmp(value, StatusCodeString[code.mStatusCode], strlen(value)) == 0) if (memcmp(value, StatusCodeString[code.mStatusCode], strlen(value)) == 0)
{ {