C++日志记录类以及日志记录程序
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++日志记录类以及日志记录程序相关的知识,希望对你有一定的参考价值。
参考技术A 使用C++语言编写写日志类,支持写日志级别设置、支持多线程、支持可变形参表写日志。主要提供以下接口:
1、设置写日志的级别 2、写关键日志信息 3、写错误日志信息 4、写警告日志信息 5、写一般日志信息
#ifndef COMMAND_DEFINE_H#define COMMAND_DEFINE_H//日志级别的提示信息static const char * KEYINFOPREFIX = " Key: n";static const char * ERRORPREFIX = " Error: n";static const char * WARNINGPREFIX = " Warning: n";static const char * INFOPREFIX = " Info: n"; static const int MAX_STR_LEN = 1024;//日志级别枚举typedef enum EnumLogLevel LogLevelAll = 0, //所有信息都写日志 LogLevelMid, //写错误、警告信息 LogLevelNormal, //只写错误信息 LogLevelStop //不写日志; #endif
#ifndef LOGGER_H_#define LOGGER_H_#include#include#include "CommandDefine.h"/* * 类名:Logger * 作用:提供写日志功能,支持多线程,支持可变形参数操作,支持写日志级别的设置 * 接口:SetLogLevel:设置写日志级别 TraceKeyInfo:忽略日志级别,写关键信息 TraceError:写错误信息 TraceWarning:写警告信息 TraceInfo:写一般信息*/class Loggerpublic: //默认构造函数 Logger(); //构造函数 Logger(const char * strLogPath, EnumLogLevel nLogLevel = EnumLogLevel::LogLevelNormal); //析构函数 virtual ~Logger();public: //写关键信息 void TraceKeyInfo(const char * strInfo, ...); //写错误信息 void TraceError(const char* strInfo, ...); //写警告信息 void TraceWarning(const char * strInfo, ...); //写一般信息 void TraceInfo(const char * strInfo, ...); //设置写日志级别 void SetLogLevel(EnumLogLevel nLevel);private: //写文件操作 void Trace(const char * strInfo); //获取当前系统时间 char * GetCurrentTime(); //创建日志文件名称 void GenerateLogName(); //创建日志路径 void CreateLogPath();private: //写日志文件流 FILE * m_pFileStream; //写日志级别 EnumLogLevel m_nLogLevel; //日志的路径 char m_strLogPath[MAX_STR_LEN]; //日志的名称 char m_strCurLogName[MAX_STR_LEN]; //线程同步的临界区变量 CRITICAL_SECTION m_cs;; #endif
#include "Logger.h"#include#include#include#include#pragma comment(lib, "DbgHelp.lib") //默认构造函数Logger::Logger() //初始化 memset(m_strLogPath, 0, MAX_STR_LEN); memset(m_strCurLogName, 0, MAX_STR_LEN); m_pFileStream = NULL; //设置默认的写日志级别 m_nLogLevel = EnumLogLevel::LogLevelNormal; //初始化临界区变量 InitializeCriticalSection(&m_cs); //创建日志文件名 GenerateLogName(); //构造函数Logger::Logger(const char * strLogPath, EnumLogLevel nLogLevel):m_nLogLevel(nLogLevel) //初始化 m_pFileStream = NULL; strcpy(m_strLogPath, strLogPath); InitializeCriticalSection(&m_cs); CreateLogPath(); GenerateLogName(); //析构函数Logger::~Logger() //释放临界区 DeleteCriticalSection(&m_cs); //关闭文件流 if(m_pFileStream) fclose(m_pFileStream); //写关键信息接口void Logger::TraceKeyInfo(const char * strInfo, ...) if(!strInfo) return; char pTemp[MAX_STR_LEN] = 0; strcpy(pTemp, GetCurrentTime()); strcat(pTemp, KEYINFOPREFIX); //获取可变形参 va_list arg_ptr = NULL; va_start(arg_ptr, strInfo); vsprintf(pTemp + strlen(pTemp), strInfo, arg_ptr); va_end(arg_ptr); //写日志文件 Trace(pTemp); arg_ptr = NULL; //写错误信息void Logger::TraceError(const char* strInfo, ...) //判断当前的写日志级别,若设置为不写日志则函数返回 if(m_nLogLevel >= EnumLogLevel::LogLevelStop) return; if(!strInfo) return; char pTemp[MAX_STR_LEN] = 0; strcpy(pTemp, GetCurrentTime()); strcat(pTemp, ERRORPREFIX); va_list arg_ptr = NULL; va_start(arg_ptr, strInfo); vsprintf(pTemp + strlen(pTemp), strInfo, arg_ptr); va_end(arg_ptr); Trace(pTemp); arg_ptr = NULL; //写警告信息void Logger::TraceWarning(const char * strInfo, ...) //判断当前的'写日志级别,若设置为只写错误信息则函数返回 if(m_nLogLevel >= EnumLogLevel::LogLevelNormal) return; if(!strInfo) return; char pTemp[MAX_STR_LEN] = 0; strcpy(pTemp, GetCurrentTime()); strcat(pTemp, WARNINGPREFIX); va_list arg_ptr = NULL; va_start(arg_ptr, strInfo); vsprintf(pTemp + strlen(pTemp), strInfo, arg_ptr); va_end(arg_ptr); Trace(pTemp); arg_ptr = NULL; //写一般信息void Logger::TraceInfo(const char * strInfo, ...) //判断当前的写日志级别,若设置只写错误和警告信息则函数返回 if(m_nLogLevel >= EnumLogLevel::LogLevelMid) return; if(!strInfo) return; char pTemp[MAX_STR_LEN] = 0; strcpy(pTemp, GetCurrentTime()); strcat(pTemp,INFOPREFIX); va_list arg_ptr = NULL; va_start(arg_ptr, strInfo); vsprintf(pTemp + strlen(pTemp), strInfo, arg_ptr); va_end(arg_ptr); Trace(pTemp); arg_ptr = NULL; //获取系统当前时间char * Logger::GetCurrentTime() time_t curTime; struct tm * pTimeInfo = NULL; time(&curTime); pTimeInfo = localtime(&curTime); char temp[MAX_STR_LEN] = 0; sprintf(temp, "%02d:%02d:%02d", pTimeInfo->tm_hour, pTimeInfo->tm_min, pTimeInfo->tm_sec); char * pTemp = temp; return pTemp; //设置写日志级别void Logger::SetLogLevel(EnumLogLevel nLevel) m_nLogLevel = nLevel; //写文件操作void Logger::Trace(const char * strInfo) if(!strInfo) return; try //进入临界区 EnterCriticalSection(&m_cs); //若文件流没有打开,则重新打开 if(!m_pFileStream) char temp[1024] = 0; strcat(temp, m_strLogPath); strcat(temp, m_strCurLogName); m_pFileStream = fopen(temp, "a+"); if(!m_pFileStream) return; //写日志信息到文件流 fprintf(m_pFileStream, "%sn", strInfo); fflush(m_pFileStream); //离开临界区 LeaveCriticalSection(&m_cs); //若发生异常,则先离开临界区,防止死锁 catch(...) LeaveCriticalSection(&m_cs); //创建日志文件的名称void Logger::GenerateLogName() time_t curTime; struct tm * pTimeInfo = NULL; time(&curTime); pTimeInfo = localtime(&curTime); char temp[1024] = 0; //日志的名称如:2013-01-01.log sprintf(temp, "%04d-%02d-%02d.log", pTimeInfo->tm_year+1900, pTimeInfo->tm_mon + 1, pTimeInfo->tm_mday); if(0 != strcmp(m_strCurLogName, temp)) strcpy(m_strCurLogName,temp); if(m_pFileStream) fclose(m_pFileStream); char temp[1024] = 0; strcat(temp, m_strLogPath); strcat(temp, m_strCurLogName); //以追加的方式打开文件流 m_pFileStream = fopen(temp, "a+"); //创建日志文件的路径void Logger::CreateLogPath() if(0 != strlen(m_strLogPath)) strcat(m_strLogPath, ""); MakeSureDirectoryPathExists(m_strLogPath);
以上就是本文的全部内容,希望对大家的学习C++有所帮助。
如何在 C++ 中完全省略 CBC 日志记录?
【中文标题】如何在 C++ 中完全省略 CBC 日志记录?【英文标题】:How to completely omit CBC loggings in C++? 【发布时间】:2022-01-16 19:50:21 【问题描述】:我正在使用 CBC 求解器来求解程序,并且方法 model.branchAndBound 被多次调用(相当多次)。因为必须将日志消息写入文件,所以它实际上会减慢程序的速度。我想知道是否可以完全省略日志消息?这是在 c++ 中,我现在认为许多建议的答案纸浆只适用于 python。此外,如果纸浆是解决这个问题的方法,我不太确定如何使用纸浆。有没有什么好的文档可以帮助理解纸浆和CBC之间的关系,以及如何使用它们?如果有人能帮我解决这个问题,我将不胜感激!
例如(这是来自 github 的示例):
// Copyright (C) 2009, International Business Machines
// Corporation and others. All Rights Reserved.
// This code is licensed under the terms of the Eclipse Public License (EPL).
// For Branch and bound
#include "OsiSolverInterface.hpp"
#include "CbcModel.hpp"
// Methods of building
#include "CoinBuild.hpp"
#include "CoinModel.hpp"
int main(int argc, const char *argv[])
OsiClpSolverInterface model;
double objValue[] = 1.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, -1.0 ;
// Lower bounds for columns
double columnLower[] = 2.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0 ;
// Upper bounds for columns
double columnUpper[] = COIN_DBL_MAX, 4.1, 1.0, 1.0, 4.0,
COIN_DBL_MAX, COIN_DBL_MAX, 4.3 ;
// Lower bounds for row activities
double rowLower[] = 2.5, -COIN_DBL_MAX, 4.0, 1.8, 3.0 ;
// Upper bounds for row activities
double rowUpper[] = COIN_DBL_MAX, 2.1, 4.0, 5.0, 15.0 ;
// Matrix stored packed
int column[] = 0, 1, 3, 4, 7,
1, 2,
2, 5,
3, 6,
0, 4, 7 ;
double element[] = 3.0, 1.0, -2.0, -1.0, -1.0,
2.0, 1.1,
1.0, 1.0,
2.8, -1.2,
5.6, 1.0, 1.9 ;
int starts[] = 0, 5, 7, 9, 11, 14 ;
// Integer variables (note upper bound already 1.0)
int whichInt[] = 2, 3 ;
int numberRows = (int)(sizeof(rowLower) / sizeof(double));
int numberColumns = (int)(sizeof(columnLower) / sizeof(double));
CoinModel build;
// First do columns (objective and bounds)
int i;
for (i = 0; i < numberColumns; i++)
build.setColumnBounds(i, columnLower[i], columnUpper[i]);
build.setObjective(i, objValue[i]);
// mark as integer
for (i = 0; i < (int)(sizeof(whichInt) / sizeof(int)); i++)
build.setInteger(whichInt[i]);
// Now build rows
for (i = 0; i < numberRows; i++)
int startRow = starts[i];
int numberInRow = starts[i + 1] - starts[i];
build.addRow(numberInRow, column + startRow, element + startRow,
rowLower[i], rowUpper[i]);
// add rows into solver
model.loadFromCoinModel(build);
CbcModel model2(model);
model2.branchAndBound();
return 0;
日志输出为:
Clp0000I Optimal - objective value 3.2368421
Clp0000I Optimal - objective value 3.2368421
Node 0 depth 0 unsatisfied 0 sum 0 obj 3.23684 guess 3.23684 branching on -1
Clp0000I Optimal - objective value 3.2368421
Cbc0004I Integer solution of 3.2368421 found after 0 iterations and 0 nodes (0.13 seconds)
Cbc0001I Search completed - best objective 3.236842105263158, took 0 iterations and 0 nodes (0.14 seconds)
Cbc0035I Maximum depth 0, 0 variables fixed on reduced cost
Clp0000I Optimal - objective value 3.2368421
Clp0000I Optimal - objective value 3.2368421
【问题讨论】:
"有几个日志级别。将日志级别设置为 i 会生成级别 i 和所有低于 i 的级别的日志消息。日志级别 0:关闭所有 CBC 消息,但只有一个。" - 把它关掉? 哦,是的!我试图找到这个但没有。就像添加“model.setLogLevel(0)”一样简单。非常感谢! 【参考方案1】:将这个添加到代码中可以解决所有问题:
model.setLogLevel(0);
【讨论】:
正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。以上是关于C++日志记录类以及日志记录程序的主要内容,如果未能解决你的问题,请参考以下文章
什么是 debezium 解决方案来显示谁以及何时删除记录日志?