14 3 / 2012

For those who think functions such as printf, cout, or even fprintf(stdout,…) are sufficient for a larger scale application, you are cheating yourself out of something special. I’d like to show you the magic of a class setup, though for the less inclined, we’ll be using a function approach, which in this application, is not too bad. (A very, very simple and compact example is included at the end of this… something.)

What’s so good about a simple debug print function? Oh, There are many benefits, course you have to build it correctly. Now what kinds of options do we add exactly?

Another good question. It should at the very least, include a write to console (graphical if you have something fancy, or into a DOS or other console), and a write to file, within the same function.

An example is:

 FLog(string Text = “NULL”, bool Write = false);

When you want to write, just add true. FLog(“THE BEES!”,true); and there you have it, if everything goes and crashes, you’ll have physical evidence, written to log.

But writing to file is not really advanced, or much of an original idea; I hear you say. We can get much fancier! And why not, we all deserve something a little elegant from time to time. Why not use our favorite time header <time.h> to log the date of the error in the text file, or even console? I won’t go into detail, but this link explains a good bit of “copy-pasta” code that will work fine with file output.

Here is where we introduce our specific logging system, where as you can enable certain logs you’ve marked. Here we adapted the prototype:

FLog(String Text = “NULL”,int Type = 0, bool write = false);

Of course ‘Type’ could be a string, though by number and referencing a text file is very simple.
A simple rule to follow can include:
0 = Basic; 1 = THEBEES.header, ect…

Using a static int in the header will allow you to set the current outputs you want to show, -1 for all, and the corresponding number for a single. Static is great for sharing information between headers, making it nicely versatile, in addition to memory efficient. 

static int allowed; 
void SetAllow(int T)
{ allowed = T;} 

void FLog(…)
{
if ( allowed == -1)
{ // Allow all messages} 
if (Type == allowed)
{// Continue on to the rest of code}
}

From such a system, you can disable and enable only relevant outputs for fast debugging. Becoming ever-more fancy, you may want to use XML (and if you don’t, I will force upon you the goodlike glory of such a great storage format) to store a list of Type levels based on a text variable within the file:

<Log>

<Level Type = “Generic” Var = “0” /> 
<Level Type = “BEES.Header” Var = “1” />

</Log>

 This may sound a little excessive, and it is, but anything to get away with using XML and my favorite third party parser, TinyXML.

You don’t need to get incredibly fancy to make something that will increase production and traceback of bugs, but do take a bit of time, and well develop something that will save you hassle. Remember, we’re programmers! We automate tasks and reap the benefits.

My chicken-scratch FLog setup:

void FLog(string Text = “NULL”, bool Write = false,bool Default = true)

{

if (!Default)

cout « Text « endl; 

else

cout « “Info: ” « Text « endl; 

if (Write)

{

ofstream file;

file.open (FPath.Dir_Add_Aliased(“Root”,”FlakLog.txt”), ios::app|std::ios::out);

time_t raw;time (&raw);

file « “\n” « asctime(localtime(&raw)) « “: ” « Text « “\n”;

file.close();

}

}

  1. danielsaucen posted this