• Advertisement
Sign in to follow this  

File Logging

This topic is 2745 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I wrote a general purpose logging class and looking for feedback on it.
free to use, redistribute, modify Et cetera

Header File

#ifndef LOG_H
#define LOG_H

#include <string>
#include <fstream>
#include <ctime>

enum LogLevel {Fatal = 0, Error, Warning, Information, Debug};

class LOG {
public:
LOG(void);

void disable();
void enable();

void setloglevel(LogLevel Severity);
void setmaxloglevel(LogLevel Severity);

void out(char * Message);
void out(char * Message, LogLevel Severity);
void out(std::string Message);
void out(std::string Message, LogLevel Severity);
private:
LogLevel CurrentLogLevel;
char * filename;
bool isEnabled;
LogLevel MaxLogLevel;
};

#endif /* LOG_H */


Source Code

#include "Log.h"
LOG::LOG(void) {
CurrentLogLevel = Debug;
MaxLogLevel = Debug;
filename = "Log.txt";
isEnabled = true;
}
void LOG::disable() {
isEnabled = false;
}
void LOG::enable() {
isEnabled = true;
}
void LOG::setloglevel(LogLevel Severity){
CurrentLogLevel = Severity;
}
void LOG::setmaxloglevel(LogLevel Severity) {
MaxLogLevel = Severity;
}
/*
Summary: Writes "Message" to a file using the DefaultLogLevel
//*/
void LOG::out(char * Message) {
if( (isEnabled) && (CurrentLogLevel >= MaxLogLevel) ) {
std::fstream File;

size_t writebufferlength;

File.open(filename, std::ios::out | std::ios::app);

if ( File.is_open() ) {
switch(CurrentLogLevel)
{
case Debug:
{
File.write("Debug\n",6);
break;
}
case Information:
{
File.write("Information\n",12);
break;
}
case Warning:
{
File.write("Warning!\n",9);
break;
}
case Error:
{
File.write("!!ERROR!!\n",10);
break;
}
case Fatal:
{
File.write("!!!FATAL ERROR!!!\n",27);
File.write("This is the Line You Are Looking for LOL!\n", 42);
break;
}
}
time_t ltime;
struct tm *Tm;
ltime=time(NULL);
Tm=localtime(<ime);
char * timestamp = asctime(Tm);

writebufferlength = strlen(timestamp);
File.write(timestamp, writebufferlength);

writebufferlength = strlen(Message);
File.write(Message, writebufferlength);

File.write("\n\n",2);
}
File.flush();
File.close();
}
}
/*
Summary: Writes "Message" to a file using the specified LogLevel
//*/
void LOG::out(char * Message, LogLevel Severity) {
if( (isEnabled) && (Severity <= MaxLogLevel) ) {
std::fstream File;

size_t writebufferlength;

File.open(filename, std::ios::out | std::ios::app);

if ( File.is_open() ) {
switch(Severity)
{
case Debug:
{
File.write("Debug\n",6);
break;
}
case Information:
{
File.write("Information\n",12);
break;
}
case Warning:
{
File.write("Warning!\n",9);
break;
}
case Error:
{
File.write("!!ERROR!!\n",10);
break;
}
case Fatal:
{
File.write("!!!FATAL ERROR!!!\n",27);
File.write("This is the Line You Are Looking for LOL!\n", 42);
break;
}
}
time_t ltime;
struct tm *Tm;
ltime=time(NULL);
Tm=localtime(<ime);
char * timestamp = asctime(Tm);

writebufferlength = strlen(timestamp);
File.write(timestamp, writebufferlength);

writebufferlength = strlen(Message);
File.write(Message, writebufferlength);

File.write("\n\n",2);
}
File.flush();
File.close();
}
}
void LOG::out(std::string Message) {
char *sz;

sz = new char[Message.length() + 1];
strcpy(sz, Message.c_str());
// now work with sz, which is a copy of s
out(sz);
// clean up
delete [] sz;

}
void LOG::out(std::string Message, LogLevel Severity) {
char *sz;

sz = new char[Message.length() + 1];
strcpy(sz, Message.c_str());
// now work with sz, which is a copy of s
out(sz, Severity);
// clean up
delete [] sz;
}

Share this post


Link to post
Share on other sites
Advertisement
it would be a good idea to include categories, so you can turn on and off logging for parts in the code. (usually, you dont want to log mouse position, but sometimes it can be handy to turn that logging on)

edit:
you propably want to be able to log to stdout as well as to files.

its not thread safe, but maybe that is by design because you dont need it.

personally i would get rid of the "funny" messages. Its easy enough to search a log for "fatal error".

Also, consider that there are many log alternatives out there already that are well tested with great functionallity

Share this post


Link to post
Share on other sites
Your std::string interfaces are overcomplicated, you should be able to use std::string::c_str(). You should probably allow the client to log a const c string. You could implement "void out(char * Message)" in terms of "void out(char * Message, LogLevel Severity)" by passing the CurrentLogLevel to the latter.

You should pass std::string instances by const reference to avoid unnecessary copies.

Share this post


Link to post
Share on other sites
Quote:
Original post by _Kami_
it would be a good idea to include categories, so you can turn on and off logging for parts in the code. (usually, you don't want to log mouse position, but sometimes it can be handy to turn that logging on)

edit:
you probably want to be able to log to stdout as well as to files.

its not thread safe, but maybe that is by design because you don't need it.

personally i would get rid of the "funny" messages. Its easy enough to search a log for "fatal error".

Also, consider that there are many log alternatives out there already that are well tested with great functionality


in regards to "funny messages" in my defense i was really stoned when i added that in.

Share this post


Link to post
Share on other sites
Also if you use operator << rather than std::ofstream::write, you can avoid explicitly including the length of the various string literals (which is a very brittle approach).

If for some reason you had to do that, you should defined the string literal in advance and use the strlen() (or if you know what you are doing, the sizeof() operator) to help reduce the maintenance burden.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement