刘收获

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

日志类库框架

  一个错误报告日志的框架,编译成动态库,不过功能还不够完善。

  利用C++输出文件流的类ofstream 来实现日志记录功能:

  使用ios::out和ios::app的方式打开(文件以输出方式打开(内存数据输出到文件);以追加方式打开文件)

1
2
3
4
5
6
7
8
9
10
private:
    __Log()
    {
         StreamObject.open( "刘大大.log", std::ios::out | std::ios::app );
    }
    __Log(const __Log&) = delete;
    __Log& operator = (const __Log&) = delete;
 
private:
    ofstream StreamObject;

  

  效果:

  

 

  源代码:

复制代码
 1 #pragma once
 2 #include <windows.h>
 3 #include <iostream>
 4 #include <fstream>
 5 #include <ctime>
 6 #include <cstdio>
 7 using namespace std;
 8 enum _LOG_LEVEL_
 9 {
10     Fatal = 0,
11     Error,
12     Critical,
13     Warning,
14     Normal,
15     Verbose
16 };
17 
18 
19 class __Log
20 {
21 public:
22     ~__Log();
23     static __Log& Instance()
24     {
25         static __Log LogObject;
26         return LogObject;
27     }
28     
29     BOOL __Log::RecordLogEx(_LOG_LEVEL_ LogLevel, const char* Format, ...);
30     BOOL __Log::RecordLog(_LOG_LEVEL_ LogLevel, const char* Format, va_list ParameterData);
31 private:
32     __Log()
33     {    
34         //以输出方式打开(内存数据输出到文件);以追加的方式打开文件
35          StreamObject.open( "刘大大.log", std::ios::out | std::ios::app );
36     }
37     __Log(const __Log&) = delete;
38     __Log& operator = (const __Log&) = delete;
39 
40 private:
41     ofstream StreamObject;
42 };
__Log.h
复制代码
复制代码
 1 #include "Common.h"
 2 
 3 static const char* __LogLevel[] = { "*致命*", "*错误*", "*关键*", "*警告*", "*普通*", "*冗长*" };
 4 __Log::~__Log()
 5 {
 6     StreamObject << endl;
 7 }
 8 BOOL __Log::RecordLogEx(_LOG_LEVEL_ LogLevel,const char* Format, ...)
 9 {
10     //初始化指向可变参数列表的指针
11     va_list ParameterData;
12     bool IsOk = FALSE;
13     //将第一个可变参数的地址付给ap,即ap指向可变参数列表的开始
14     va_start(ParameterData, Format);
15     IsOk = RecordLog(LogLevel, Format, ParameterData);
16     //ParameterData赋值为0,没什么实际用处,主要是为程序健壮性
17     va_end(ParameterData);
18 
19     return IsOk;
20 }
21 BOOL __Log::RecordLog(_LOG_LEVEL_ LogLevel,const char* Format, va_list ParameterData)
22 {
23     char BufferData[2048] = { 0 };
24     char MessageData[0x1000] = { 0 };
25     char TimeData[256] = { 0 };
26 
27     auto TimeObject = time(NULL);
28     tm v1;
29     localtime_s(&v1, &TimeObject);
30     strftime(TimeData, _countof(TimeData), "%Y-%m-%d %H:%M:%S", &v1);
31     //将参数fmt、ap指向的可变参数一起转换成格式化字符串,放string数组中,其作用同sprintf,只是参数类型不同
32     vsprintf_s(BufferData, _countof(BufferData), Format, ParameterData);
33     sprintf_s(MessageData, _countof(MessageData), "%s %-5s %s", TimeData, 
34         __LogLevel[LogLevel], BufferData);
35 
36     StreamObject << MessageData << std::endl;  //写入到日志
37 
38     return true;
39 }
__Log.cpp
复制代码
复制代码
 1 #pragma once
 2 #include <windows.h>
 3 #include <iostream>
 4 #include <fstream>
 5 #include <ctime>
 6 #include <cstdio>
 7 using namespace std;
 8 
 9 enum _LOG_LEVEL_
10 {
11     Fatal = 0,
12     Error,
13     Critical,
14     Warning,
15     Normal,
16     Verbose  
17 };
18 
19 //用__declspec(dllexport)显式的定义dll接口给调用它的exe或dll文件,
20 class _declspec (dllexport) __Log
21 {
22 public:
23     __Log();
24     ~__Log();
25     static __Log& __Log::Instance();
26     BOOL __Log::RecordLogEx(_LOG_LEVEL_ LogLevel, const char* Format, ...);
27     BOOL __Log::RecordLog(_LOG_LEVEL_ LogLevel,const char* Format, va_list ParameterData);
28 
29 protected:
30 private:
31     std::ofstream StreamObject;
32 
33 };
Common.h
复制代码
复制代码
 1 #include "Common.h"
 2 
 3 BOOL APIENTRY DllMain( HMODULE hModule,
 4                        DWORD  ul_reason_for_call,
 5                        LPVOID lpReserved
 6                      )
 7 {
 8     switch (ul_reason_for_call)
 9     {
10     case DLL_PROCESS_ATTACH:
11     case DLL_THREAD_ATTACH:
12     case DLL_THREAD_DETACH:
13     case DLL_PROCESS_DETACH:
14         break;
15     }
16     return TRUE;
17 }
dllmain.cpp
复制代码
复制代码
 1 // Log.cpp : 定义控制台应用程序的入口点。
 2 //
 3 #include <windows.h>
 4 #include <iostream>
 5 
 6 using namespace std;
 7 #include "..\__Log\__Log.h"
 8 
 9 #ifdef _WIN64
10 #pragma comment(lib,"..\\x64\\debug\\__log.lib")
11 #else
12 #pragma comment(lib,"..\\debug\\__Log.lib")
13 #endif
14 int main()
15 {
16     /*
17     int   v1 = 10;
18     char* v2 = "函数错误";
19     __Log::Instance().RecordLogEx(Warning,"%d %s",v1,v2);
20     __Log::Instance().RecordLogEx(Fatal,"%s",v2);
21     __Log::Instance().RecordLogEx(Fatal,"%s %f %f %d %s",v2,4.1,4.4,100,"HelloWorld");
22     */
23 
24 
25     //char* v1 = NULL;
26 
27 
28     __try
29     {
30         int a = 1;
31         a = a / 0;
32         //memcpy(v1,"HelloWorld",10);
33 
34     }
35     __except(EXCEPTION_EXECUTE_HANDLER)
36     {
37         int LastError = GetLastError();
38         __Log::Instance().RecordLogEx(Fatal,"%d %s",LastError,"继续努力");
39     }
40     return 0;
41 }
Log.cpp
复制代码

 


posted on   沉疴  阅读(208)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示