Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / MFC

Weekly Logger Framework

1.71/5 (4 votes)
15 Apr 2007CPOL2 min read 1   142  
Sometimes, you may want to create a log file and you want to create a log item every week(maybe every month or every 10 days). This class can help you to make the mission easier!

Introduction

Sometimes, you want to create a log file to store some information. You may create a log every second, every day or every week.

The framework designed by me can make the work easier. You can add it in your project so that you can easily create a record in the log file every N days. (The N can be changed in the source code).

The Framework Source Code

I wrote the framework in C++ and built two classes. One is the main class of the logger which is not necessary for you to change. The other is a class of each record which should be modified when you apply it into your project.

I used template so that you can simply use your own data structure of each record.

Let's take a look at the definition of the main class:

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
};

The class WeeklyReport has a private member WeeklyLogData. It's a pointer to a data structure which is a template data structure so that you can declare a class using your own data structure.

The constructor of the class has three parameters:

  1. Log File name
  2. A callback function pointer
  3. A time span

It has a member function Write which will create/open a log file and check if the program should create a new record.

C++
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
{

If it's not necessary to create a new record, nothing will be done (no extra memory space).

When the code finds that a new record should be created, a new object of the specific type (the template parameter) will be created. After creating the Object, the callback function will be called:

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

Using the Code

It's very simple to use the class. There are three steps in building a new logger:

  1. Append the Indicator Data to WeeklyItems.h's public members:
    C++
    class WeeklyItem
    {
    // ...
    //ON ONE LINE, MUST NOT INCLUDE "endl"
    /* Step.1
    *
    * Define All The Weekly Indicators Here
    *
    * ************************************************************
    */
    int MaxApps; 
    string AppsOpened;
    string Plugins;
    /*
    * *************************************************************
    */
    };

    I have added three example data in it. Applications Opened, Max Application Number and Plugins installed. You may delete them and add some new members which you want to record.

  2. Modify the output style in WeeklyItems.h:
    C++
    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);
    }

    You should change the operation overload function and make a user-friendly output style. Remember, don't add "endl" at the end.

  3. Add a function in GatherWeeklyData to generate that indicator:
    C++
    /*
    * 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();
    }

You may change the function to sum up all the information you need. The example showed how to set the data members.

Finally, you can simply apply the class and define a new object. Then invoke the Write method for writing a new record. Just add the following line into your project:

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

Output of the Log File

After applying the logger framework into your project, a log file may look as follows:

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.....
...

This log file will be changed every week!

Points of Interest

In this framework, I found that templates and operator overloading are very useful to build a programmer-friendly library or a class. Maybe it's more complicated to apply these advanced skills into your project, but it definitely will make the customer code much simpler.

History

  • 15th April, 2007: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)