Commit 4d84c454 authored by oscar's avatar oscar

提交代码

parent d033974e
......@@ -7,6 +7,7 @@
#include "Track2D.h"
#include "BaseTracker.h"
#include "Iou.h"
#include "jfx_log.h"
//using namespace jfx_vision;
......@@ -14,6 +15,13 @@
int main(int argc, char*argv[]) {
//ROS_INFO("START JFX_VISION_NODE");
InitLog();
SDK_LOG(SDK_INFO, "main function");
ros::init(argc, argv, "jfx_vision");
ros::NodeHandle nh("~");
......
/*
Copyright (C) oscar All rights reserved.
File Name: LogBase.h
description: 通用c&c++日志头文件,可以跨的平台包括:windows,android,linux
Change History:
Date Version Changed By Changes
2021/06/09 1.0.0.1 oscar Create
*/
#ifndef _SDK_LOG_BASE_H_
#define _SDK_LOG_BASE_H_
/*
日志功能说明:
使用举例:
在你的代码里加入如下的日志信息:
int a = 1;
float b = 2.0f;
char* c = "hello";
SDK_LOG(SDK_INFO,"这个是日志信息,其中a = %d, b = %f,c = %s",a,b,c);
这样打印的日志信息为:
[2021-06-09 16:28:10.890][14036][Info][USERSDK][..\src\main.cpp:42]: 这个是日志信息,其中a = 1, b = 2.000000,c = hello
具体信息说明如下:
[2021-06-09 16:28:10.890] 这个是日志生成的时间,精确到毫秒
[14036] 这个是线程id,线程号为14036
[Info] 这个是日志级别,当前用的是Info,还有Debug,Error
[USERSDK] 这个是自己定义的模块名称,在代码中需要声明,具体看使用说明.
[..\src\main.cpp:42] 这个是日志所在文件的名称和所在行数,方便查找位置
: 这个是日志信息,其中a = 1, b = 2.000000,c = hello 剩下的冒号后面的就是日志信息了,日志信息格式与printf格式是一样的,没有任何限制。
SDK日志使用说明:
使用步骤:
1.拷贝LogBase.h头文件到自己的代码目录并在工程中#include,注意不得擅自修改LogBase.h里的内容,请把需求提交给相关维护人员,统一进行修改。
2.在接口的init函数实现的cpp文件中需要做以下步骤,举例如下:
#include "LogBase.h"
INIT_SDK_LOG("Interface");//Interface是模块名
int Interface::Init(void* logHandle)//定义好的初始化函数,参数可能有所不同,但其中必须有void* logHandle参数
{
INIT_SYS_LOG_HANDLE(logHandle);//这个宏意思是使用默认SDK的日志文件,如果需要定义自己的日志文件,需要使用INIT_DEF_LOG_HANDLE(logHandle, "1.log"); 其中1.log就是自己的日志文件名
//自己的初始化实现
return 0;
}
第一步是调用宏 INIT_SDK_LOG("自己所封装的模块名称"); 声明自己的模块名称
第二部是在init函数里拿到logHandle调用INIT_SYS_LOG_HANDLE(logHandle)初始化日志系统,也可以指定自己的日志文件名使用宏INIT_DEF_LOG_HANDLE(logHandle, "1.log");其中1.log是自己的日志文件名
3.在需要打印日志的地方直接调用宏SDK_LOG开始写日志了,举例如下:
int ret = -1;
SDK_LOG(SDK_ERRROR, "DealImage ret = %d", ret);
其中日志必须指定写出日志级别,现在分别包括:SDK_DEBUG,SDK_INFO,SDK_ERRROR,不可以掠过,之后的打印信息可以参照printf的格式。
*/
/**
* @brief 日志类型枚举,在写日志时必须指定枚举类型
*/
enum LOG_LEVEL
{
SDK_DEBUG = 0,
SDK_INFO = 1,
SDK_ERROR = 2,
SDK_LOG_NUM
};
/**
* @brief 日志枚举类型对应的字符信息,一个枚举对应一个信息说明
*/
const static char* logType[SDK_LOG_NUM] = {
"Debug",
"Info",
"Error"
};
/**
* @brief 日志系统统一的接口类声明
*/
struct SDKLogBase
{
public:
/**
* @brief 添加日志文件名到日志系统,如果使用默认的日志文件,参数file为空。
*
* @param file 输入数据,日志文件名,如果使用系统默认日志文件,请传入NULL,否则为文件名
*
* @param fileIdx 输出数据,返回文件名的索引id,对应file参数的文件名的索引id
*
* @return 0成功,1成功(但文件已经存在请知晓),-1失败
*/
int (*AddLogFile)(const char* file, int& fileIdx);
/**
* @brief 获取系统时间的接口,返回日期和时间字符串。
*
* @param 无参数
*
* @return 0成功,-1失败
*/
char* (*GetTime)();
/**
* @brief 写具体的日志信息接口
*
* @param fileIdx 输入数据,AddLogFile接口返回的fileIdx索引id
*
* @param logLevel 输入数据,日志级别请参照LOG_LEVEL枚举
*
* @param format 输入数据,格式化字符串,请参照printf的输入
*
* @return 0成功,-1失败
*/
int (*Print)(int fileIdx, int logLevel, const char* format, ...);
};
const int IDX_NUM = 10;//默认预留10个日志文件位置
extern SDKLogBase* g_logHandle;
extern int g_logFileIdx[IDX_NUM];
extern char* g_moduleName;
/**
* @brief 初始化日志系统宏,需要传入模块名,这个宏只能调用一次
*/
#define INIT_SDK_LOG(NAME) \
SDKLogBase* g_logHandle = nullptr; \
int g_logFileIdx[IDX_NUM] = {}; \
char* g_moduleName = NAME;
/**
* @brief 在init函数里,拿到void* logHandle之后调用的宏,没有指定日志文件名,使用默认的日志文件,这个宏只能调用一次
*/
#define INIT_SYS_LOG_HANDLE(handle) \
if (handle) \
{\
g_logHandle = (SDKLogBase*)handle; \
if(g_logHandle->AddLogFile) g_logHandle->AddLogFile(nullptr, g_logFileIdx[0]); \
if(g_logHandle->Print) g_logHandle->Print(g_logFileIdx[0], SDK_INFO, "[COMPILE][%s %s][%s]", __DATE__, __TIME__, g_moduleName); \
}
/**
* @brief 在init函数里,拿到void* logHandle之后调用的宏,指定日志文件名,这个宏与INIT_SYS_LOG_HANDLE宏选择其中一个并且只能调用一次
*/
#define INIT_DEF_LOG_HANDLE(handle,name) \
if (handle) \
{\
g_logHandle = (SDKLogBase*)handle; \
if(g_logHandle->AddLogFile) g_logHandle->AddLogFile(name, g_logFileIdx[0]); \
if(g_logHandle->Print) g_logHandle->Print(g_logFileIdx[0], SDK_INFO, "[COMPILE][%s %s][%s]", __DATE__, __TIME__, g_moduleName); \
}
#define ADD_DEF_LOG(idx,name) \
if (g_logHandle) \
{\
if ( idx > 0 && idx < IDX_NUM)\
{\
if(g_logHandle->AddLogFile) g_logHandle->AddLogFile(name, g_logFileIdx[idx]); \
}\
}
#ifndef __linux__
#include "windows.h"
#define THREADID GetCurrentThreadId()
#else
#if defined (__aarch64__)
#include <unistd.h>
#include <sys/syscall.h>
#define THREADID syscall(SYS_gettid)
#else
#include "unistd.h"
#include <sys/syscall.h>
//#define THREADID gettid()
#define THREADID syscall(__NR_gettid)
#endif
#endif
/**
* @brief 写日志的宏,其中需要传入日志级别和格式化字符串,具体参照printf的参数
*/
#define SDK_LOG(logLevel,FMT, ...) { if(g_logHandle) if(g_logHandle->Print && g_logHandle->GetTime) g_logHandle->Print(g_logFileIdx[0],logLevel,"[%s][%d][%s][%s][%s:%d]: " FMT,g_logHandle->GetTime(),THREADID,logType[logLevel],g_moduleName, __FILE__, __LINE__, ##__VA_ARGS__);}
#define SDK_IDX_LOG(idx,logLevel,FMT, ...) { if(g_logHandle && idx > 0 && idx < IDX_NUM) if(g_logHandle->Print) g_logHandle->Print(g_logFileIdx[idx],logLevel,FMT, ##__VA_ARGS__);}
#endif
\ No newline at end of file
#include <glog/logging.h>
#include<sys/time.h>
#include <signal.h>
#include "jfx_log.h"
#include "LogBase.h"
#include <string>
#include <vector>
#define LOG_BUFF_LEN 102400
#ifdef _WIN32
__declspec(thread) char g_timeStr[1024] = {};
__declspec(thread) char g_logStr[LOG_BUFF_LEN] = {};
#else
thread_local char g_timeStr[1024] = {};
thread_local char g_logStr[LOG_BUFF_LEN] = {};
#endif
FILE* g_file = nullptr;
const std::string& GetRootDir()
{
static std::string rootDir;
if (rootDir.empty()) {
char curDir[512] = { 0 };
getcwd(curDir, 500);
//fs::path rootPath(curDir);
//rootDir = rootPath.parent_path();
rootDir = curDir;
}
return rootDir;
}
int AddLogFileSys(const char* file, int& fileIdx)
{
if (file)
{
std::string name = file;
if (name == "jlog")//系统日志
{
fileIdx = 0;
return 0;
}
if (name.empty())
return -1;
fileIdx = 1;
std::string path = GetRootDir();
std::string dir = path + "/" + file;
LOG(INFO) << "AddLogFileSys save file = " << dir;
#ifdef _WIN32
if (fopen_s(&g_file, dir.c_str(), "wt") != 0)
#else
if (nullptr == (g_file = fopen(dir.c_str(), "wt")))
#endif
{
g_file = nullptr;
return -2;
}
}
return 0;
}
char* GetTimeSys()
{
#if defined(__ANDROID__) || defined(__linux__)
time_t tt = time(NULL);
struct tm* ptr;
ptr = localtime(&tt);
// printf("time: %d \n", tt);
char str[80];
strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S", ptr);
//2018-09-19 16:01:37.517
struct timeval tmv;
gettimeofday(&tmv, NULL);
// char buf[128] = {0};
sprintf(g_timeStr, "%s.%03d", str, (int)(tmv.tv_usec / 1000));
return (char*)g_timeStr;
#elif _WIN32
char date[64] = { 0 };
struct timeb tb;
ftime(&tb);
std::tm now = { 0 };
//gmtime_s(&now, &tb.time);
localtime_s(&now, &tb.time);
sprintf_s(g_timeStr, sizeof(g_timeStr), "%04d-%02d-%02d %02d:%02d:%02d.%03d",
now.tm_year + 1900, now.tm_mon + 1, now.tm_mday,
now.tm_hour, now.tm_min, now.tm_sec,
tb.millitm);
return g_timeStr;
#endif
}
int PrintSys(int fileIdx, int logLevel, const char* format, ...)
{
memset(g_logStr, 0, sizeof(g_logStr));
va_list argList;
va_start(argList, format);
#ifdef _WIN32
vsprintf_s(g_logStr, format, argList);
#else
int ret = vsprintf(g_logStr, format, argList);
if (ret < 0)
{
exit(0);
}
#endif
va_end(argList);
//return LogSystem::GetInstance()->Print(fileIdx, logLevel, g_logStr);
if (fileIdx == 1)
{
if (g_file)
{
fprintf(g_file, "%s", g_logStr);
fprintf(g_file, "\n");
fflush(g_file);
}
return 0;
}
if (logLevel == SDK_INFO)
LOG(INFO) << g_logStr;
else if (logLevel == SDK_DEBUG)
LOG(WARNING) << g_logStr;
else if (logLevel == SDK_ERROR)
LOG(ERROR) << g_logStr;
else
LOG(FATAL) << g_logStr;
return 0;
}
void LimitOpenFile() {
struct rlimit limit = { 0 };
if (getrlimit(RLIMIT_FSIZE, &limit) != 0) {
return;
}
limit.rlim_cur = 1024000000;
if (0 != setrlimit(RLIMIT_FSIZE, &limit)) {
}
if (getrlimit(RLIMIT_FSIZE, &limit) != 0) {
return;
}
}
void signalHandler(int signum) {
//ROS_INFO("Interrupt signal %d received", signum);
// 清理并关闭
// 终止程序
// g_Run = false;
exit(signum);
}
INIT_SDK_LOG("jfx_event")
SDKLogBase g_log;
void InitLog()
{
// 注册信号 SIGINT 和信号处理程序
signal(SIGINT, signalHandler);
LimitOpenFile();
google::InitGoogleLogging(argv[0]);
FLAGS_stderrthreshold = google::INFO; //输出到stderr的限值,默认为2(ERROR),默认ERORR以下的信息(INFO、WARNING)不打印到终端。
FLAGS_max_log_size = 500; //设置最大日志文件大小(以MB为单位)。
FLAGS_logbufsecs = 0; //设置可以缓冲日志的最大秒数,0指实时输出。
FLAGS_alsologtostderr = true; //是否将日志输出到文件和stderr,如果:true,忽略FLAGS_stderrthreshold的限制,所有信息打印到终端。
FLAGS_log_prefix = true; //设置日志前缀是否应该添加到每行输出。
FLAGS_log_dir = "log";
g_log.AddLogFile = AddLogFileSys;
g_log.GetTime = GetTimeSys;
g_log.Print = PrintSys;
INIT_DEF_LOG_HANDLE(&g_log, "jlog");
}
#pragma once
void InitLog();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment