65.9K
CodeProject 正在变化。 阅读更多。
Home

每周日志框架

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.71/5 (4投票s)

2007年4月16日

CPOL

2分钟阅读

viewsIcon

20861

downloadIcon

158

有时,您可能想要创建一个日志文件,并且希望每周(也许每月或每 10 天)创建一个日志项。 这个类可以帮助您更轻松地完成这项任务!

引言

有时,您想创建一个日志文件来存储一些信息。 您可以每秒、每天或每周创建一个日志。

我设计的框架可以使这项工作更容易。 您可以将它添加到您的项目中,以便您可以轻松地每 N 天在日志文件中创建一个记录。(N 可以在源代码中更改)。

框架源代码

我用 C++ 编写了该框架,并构建了两个类。 一个是记录器的主要类,您不必更改它。 另一个是每个记录的类,当您将其应用于您的项目时,应该修改它。

我使用了模板,因此您可以简单地使用每个记录的自己的数据结构。

让我们看一下主类的定义

template<typename T>
class WeeklyReport
{
public:
typedef void (*WeekFunction) (T&); 
WeeklyReport(string LogFileName,WeekFunction CallbackFunc,float TimeSpan):
	m_LogFileName(LogFileName),Callback(CallbackFunc),m_Timespan(TimeSpan){};

static time_t getSecondCount(int Year,int Month,int Day);
void Write(); 		//The Main Procedure
private:
bool WriteData();
time_t m_Today;
time_t m_LastWroteTime;
string m_LogFileName; 	// The Weekly Report Log file path
void ReadLastWroteTime();
T* WeeklyLogData; 		// Weekly Report Data Pointer
// IMPORTANT:
// This Template Data Structure Must Have Operator Overload "<<"
// And the Output of the structure must be printed on one line!
char * TodayTag() const;
WeekFunction Callback;
float m_Timespan; 		// How many days of each record created
};

WeeklyReport 有一个 private 成员 WeeklyLogData。 这是一个指向数据结构的指针,该数据结构是一个模板数据结构,因此您可以使用您自己的数据结构声明一个类。

该类的构造函数有三个参数

  1. 日志文件名
  2. 一个回调函数指针
  3. 一个时间跨度

它有一个成员函数 Write,它将创建/打开一个日志文件并检查程序是否应该创建一个新记录。

ReadLastWroteTime();
m_Today=time(NULL);
float timeSpan=(difftime(m_Today,m_LastWroteTime)/60/60/24); // The Time Span 
					// between today and the last written time
if(timeSpan>m_Timespan) 			// Longer than m_Timespan days
{

如果不需要创建新记录,则不会执行任何操作(没有额外的内存空间)。

当代码发现应该创建一条新记录时,将创建一个特定类型(模板参数)的新对象。 创建 Object 后,将调用回调函数

WeeklyLogData=new T;
Callback(*WeeklyLogData);
WriteData(); 		// Write Current Data
delete WeeklyLogData;

Using the Code

使用该类非常简单。 构建一个新的记录器有三个步骤

  1. 将 Indicator Data 附加到 WeeklyItems.hpublic 成员
    class WeeklyItem
    {
    // ...
    //ON ONE LINE, MUST NOT INCLUDE "endl"
    /* Step.1
    *
    * Define All The Weekly Indicators Here
    *
    * ************************************************************
    */
    int MaxApps; 
    string AppsOpened;
    string Plugins;
    /*
    * *************************************************************
    */
    };

    我在其中添加了三个示例数据。已打开的应用程序、最大应用程序数量和已安装的插件。 您可以删除它们并添加一些您想要记录的新成员。

  2. 修改 WeeklyItems.h 中的输出样式
    ostream& operator<<(ostream & ostr, const WeeklyItem & item) 
    {
    /*
    *
    * Modify the following Line, Don't Add endl at the end
    *
    */
    ostr<<"Max Opened:"<<item.MaxApps<<",
    	Apps:"<<item.AppsOpened<<",Plugins:"<<item.Plugins;
    return (ostr);
    }

    您应该更改操作符重载函数并制作一个用户友好的输出样式。 记住,不要在最后添加“endl”。

  3. GatherWeeklyData 中添加一个函数来生成该指标
    /*
    * The Following Function is a Callback Function 
    * Which Will Only Be Called When Necessary
    * 
    * Notice: You can get the final data from an external function. 
    * But don't forget to store itto the inItem reference
    */
    void GatherTheWeeklyData(WeeklyItem &inItem)
    {
    inItem.AppsOpened.append(SumUpApplications());
    inItem.Plugins.append(SumUpPlugins());
    inItem.MaxApps=SumUpMaxApplications();
    }

您可以更改该函数以总结您需要的所有信息。 示例展示了如何设置数据成员。

最后,您可以简单地应用该类并定义一个新对象。 然后调用 Write 方法来写入一条新记录。 只需在您的项目中添加以下行

WeeklyReport<WeeklyItem> WeekReporter(WEEK_REPORT_FILE_NAME,&GatherWeeklyData);
WeekReporter.Run();

日志文件的输出

将记录器框架应用于您的项目后,日志文件可能如下所示

2007-03-10,Max Opened:54,Apps:Install Shield/MSDN,Plugins:Google Hints
2007-03-17,Max Opened:40,Apps:Internet Explorer/Visual Studio,Plugins:MSN Space
2007-03-24,Max Opened:35,Apps.....
...

此日志文件将每周更改一次!

关注点

在这个框架中,我发现模板和运算符重载对于构建一个程序员友好的库或类非常有用。 也许将这些高级技能应用于您的项目会更复杂,但它肯定会使客户代码更简单。

历史

  • 2007 年 4 月 15 日:最初的帖子
© . All rights reserved.