(C++) Logger Class

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
AlexL
Posts: 184
Joined: Tue Mar 02, 2004 6:06 pm
Location: Washington State

(C++) Logger Class

Post by AlexL »

So I have been apart of this community for some time now, and have never really been able to give anything back the community; so here if my first attempt at which.

Below is a class and methods for adding to a log file. A way, small way, to debug your applications if your running without the console and for people to be able to send something back to you so you can figure out why the application is having errors on their system. The code pretty much explains itself, I hope that it can come in to use by someone and prove to be helpful :)

Code: Select all

//--------------------------------------------------------------------------
/// CLogger Class
/// Copyright 2006, Alexander M. Loren
/// Notes:	 This class is totaly library indipentant, all that is needed
///			 to use this class; is to plug it into your solution and compile.
/// Credits: nVidia example referance.
//--------------------------------------------------------------------------
#ifndef __CLOGGER_H__
#define __CLOGGER_H__

#include <fstream>
#include <vector>
#include <string>

class CLogger
{
private:
	static std::vector<std::string> hLogQueue;
	static const char* hLogPath;
public:
	static void Initialize(const char* lpstrLogFile = NULL);
	static void Process();
	static void WriteInfoLog(const std::string& lpstrInfo,bool bTab = false);
	static void WriteErrorLog(const std::string& lpstrError,bool bTab = false);
	static void WriteFatalLog(const std::string& lpstrFatal,bool bTab = false);
};

#endif

Code: Select all

//--------------------------------------------------------------------------
/// CLogger Class
/// Copyright 2006, Alexander M. Loren
/// Notes:	 This class is totaly library indipentant, all that is needed
///			 to use this class; is to plug it into your solution and compile.
/// Credits: nVidia example referance.
//--------------------------------------------------------------------------
#include "CLogger.h"

//--------------------------------------------------------------------------
/// Summary:	Pre-Definition of methods used.
//--------------------------------------------------------------------------
std::vector<std::string> CLogger::hLogQueue;
const char* CLogger::hLogPath = NULL;

//--------------------------------------------------------------------------
/// Method:		CLogger::Initialize()
/// Summary:	Initialization of logger engine.
/// Paramaters: (const char* - Log file path name)
//--------------------------------------------------------------------------
void CLogger::Initialize(const char* lpstrLogFile)
{
	hLogPath = !lpstrLogFile ? "console.log" : lpstrLogFile;
	std::ofstream hLogFile(hLogPath);
	hLogFile.close();
}

//--------------------------------------------------------------------------
/// Method:		CLogger::Process()
/// Summary:	Run through queued list and output to log file.
/// Paramaters: -NONE-
//--------------------------------------------------------------------------
void CLogger::Process()
{
	if(!hLogQueue.size())
	{
		return;
	}

	std::ofstream hLogFile(hLogPath,std::ios::app);

	for(size_t t = 0; t < hLogQueue.size(); t++)
	{
		hLogFile << hLogQueue[t];
	}

	hLogQueue.clear();
	hLogFile.close();
}

//--------------------------------------------------------------------------
/// Method:		CLogger::WriteInfoLog()
/// Summary:	Writes the information message to the log.
/// Paramaters: (std::string& - Error message)
//--------------------------------------------------------------------------
void CLogger::WriteInfoLog(const std::string& lpstrInfo,bool bTab)
{
	if(bTab)
	{
		hLogQueue.push_back(std::string("<+> \t") + lpstrInfo + "\n");
	}
	else
	{
		hLogQueue.push_back(std::string("<+> ") + lpstrInfo + "\n");
	}
	if(hLogQueue.size() >= 10)
	{
		Process();
	}
}

//--------------------------------------------------------------------------
/// Method:		CLogger::WriteErrorLog()
/// Summary:	Writes the error message to the log.
/// Paramaters: (std::string& - Error message)
//--------------------------------------------------------------------------
void CLogger::WriteErrorLog(const std::string& lpstrError,bool bTab)
{
	if(lpstrError.size())
	{
		if(bTab)
		{
			hLogQueue.push_back(std::string("<!> \t") + lpstrError + "\n");
		}
		else
		{
			hLogQueue.push_back(std::string("<!> ") + lpstrError + "\n");
		}
		Process();
	}
}

//--------------------------------------------------------------------------
/// Method:		CLogger::WriteFatalLog()
/// Summary:	Writes the fatal error message to the log.
/// Paramaters: (std::string& - Fatal error message)
//--------------------------------------------------------------------------
void CLogger::WriteFatalLog(const std::string& lpstrFatal,bool bTab)
{
	if(lpstrFatal.size())
	{
		if(bTab)
		{
			hLogQueue.push_back(std::string("<X> \t") + lpstrFatal + "\n");
		}
		else
		{
			hLogQueue.push_back(std::string("<X> ") + lpstrFatal + "\n");
		}
		Process();
	}
}
Halan
Posts: 447
Joined: Tue Oct 04, 2005 8:17 pm
Location: Germany, Freak City
Contact:

Post by Halan »

hi,

using your logger class the file will be created but nothing is written into it (yes i called the write functions ;) )

greets,
halan
AlexL
Posts: 184
Joined: Tue Mar 02, 2004 6:06 pm
Location: Washington State

Post by AlexL »

Hrm, just gave this a run on my machine, even creating a new project and it ran without error. I know that it was said that you called the functions, but just to double check; it was designed to look something like this.

Code: Select all

// Example, is not limited to being called within the main method.
int main()
{
   ...
   CLogger::Initialize("logFileName.log");
   ...
   // Write a standard log message.
   CLogger::WriteInfoLog("Random message of sorts.");
   ...
   // An error occurred, lets log it.
   // Method imidiately processed, no queue lines; applies for warnings as well.
   CLogger::WriteErrorLog("Error string");
   ...
   CLogger::Process(); // Should be called at end of application, to make sure if there are less then 10 lines in queue they will be processed.
   ...
}
If your code is setup like this, I'd be curious to take a look at the bit of source where this is being used if you'd allow; to attemt to find why it's not working for you. If this is the case, you can send it to me at AlexLoren 'at' gmail.com

Hope we can get this resolved :)
sio2
Competition winner
Posts: 1003
Joined: Thu Sep 21, 2006 5:33 pm
Location: UK

Post by sio2 »

This is very useful. How does it compare to the Irrlicht in-built logger?
Midnight
Posts: 1772
Joined: Fri Jul 02, 2004 2:37 pm
Location: Wonderland

Post by Midnight »

sio2 wrote:This is very useful. How does it compare to the Irrlicht in-built logger?
irrlicht logs to console this is designed as a plugin app to output a crashlog.txt or something for apps without a console window mainly.

as far as I understand haven't tried it.
AlexL
Posts: 184
Joined: Tue Mar 02, 2004 6:06 pm
Location: Washington State

Post by AlexL »

Halan,
Did you ever get the issue you were having with this class resolved?

sio2,
I can't really compare this class to Irrlicht's built in logging tool. Midnight pretty much hit the nail on the head with his statement. It was built to output everything placed in the vector to a text file of sorts :) I imagine with a little work I could also have all the log information from Irrlicht placed within the same file, so even if using a windows application with no console you'd be able to see what was outputted by Irrlicht and your application.
agi_shi
Posts: 122
Joined: Mon Feb 26, 2007 12:46 am

Post by agi_shi »

Not sure what Irrlicht uses (cout?), but if it uses an ostream:

Code: Select all

std::ofstream file("log.txt");

// if it uses cout, for example...
cout.rdbuf(file.rdbuf());
And it'll be redirected.
Midnight
Posts: 1772
Joined: Fri Jul 02, 2004 2:37 pm
Location: Wonderland

Post by Midnight »

agi_shi wrote:Not sure what Irrlicht uses (cout?), but if it uses an ostream:

Code: Select all

std::ofstream file("log.txt");

// if it uses cout, for example...
cout.rdbuf(file.rdbuf());
And it'll be redirected.

Thats just silly.. use irrlicht for console.. but if yer lazy for testing then its fine.
agi_shi
Posts: 122
Joined: Mon Feb 26, 2007 12:46 am

Post by agi_shi »

Midnight wrote:
agi_shi wrote:Not sure what Irrlicht uses (cout?), but if it uses an ostream:

Code: Select all

std::ofstream file("log.txt");

// if it uses cout, for example...
cout.rdbuf(file.rdbuf());
And it'll be redirected.

Thats just silly.. use irrlicht for console.. but if yer lazy for testing then its fine.
Huh?

No, I'm saying depending on what Irrlicht internally uses, you may or may not be able to redirect it to a file.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Irrlicht doesn't use std::cout for logging though, it uses printf. You can do the same thing for the file streams.

Code: Select all

// opens 'irrlicht.log' for writing and maps stdout to that file
FILE* log = freopen("irrlicht.log", "w", stdout);
setvbuf(log, 0, _IONBF, 0); // disable buffering

// create your irrlicht device and stuff
Unfortunately, for this to work, you need to fix the Irrlicht dll build options to link the dynamic version of the CRT. If Irrlicht links the static CRT, it gets its own copy of stdout, and the freopen call only remaps printf calls made from inside the users code. If you changed the application type from console to windows, it will not work though.

I dunno why it is not sufficient to just use the Irrlicht ILogger interface and dump the messages to file from the user event receiver.

Travis
Post Reply