|
/*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LogXML 1.0
------------------
LogXML is a simple and free logging class for all purposes.
You can use it freely und unlimited but give me credit
where it's due.
Source code is ready for DoxyGen (http://www.doxygen.org/).
Written by Christian Richardt (cr@whizer.net).
Release history:
Mai 12, 2003: Version 1.0. First release.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*/
/**
\file LogXML.cpp
\brief XML log class
\date 2003-05-12
\author Christian Richardt (cr@whizer.net)
**/
#ifndef LOGXML_CPP
#define LOGXML_CPP
#include <stdio.h>
#include <string.h>
#include <sys/timeb.h>
#include <time.h>
#include "LogXML.h"
/**
\brief Constructor of LogXML
\param filename File name of log file
\param appName Name of Application (optional)
Opens the log file with specified name and writes the header.
Attention: Existing files will be overwritten!
**/
LogXML::LogXML(char* filename, char* appName)
{
// copy filename
m_strFilename = new char[ strlen(filename) ];
strncpy(m_strFilename, filename, strlen(filename));
// Try to open log file
try
{ LogFile = fopen(filename, "w"); }
catch(...)
{
char buf[200];
sprintf(buf, "LogXML: Error opening file \"%s\".\n", filename);
perror(buf);
return;
}
Depth = 0; // root
// Header
LogXML::WriteData("<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n");
LogXML::WriteData("<?xml-stylesheet href=\"Log.xsl\" type=\"text/xsl\" ?>");
LogXML::WriteLine("<LogFile>");
Depth++; // one level down
LogXML::WriteLine("AppName", appName);
WriteTimestamp();
WriteDateTime();
}
/**
\brief Go one level down.
\param message Log entry
\param filename Source file name (optional)
\param funcname Function name (optional)
\return true (if successful)
**/
bool LogXML::goDown(char* message, char* filename, char* funcname)
{
bool res = true;
res &= WriteLine("<LogItem>");
Depth++;
res &= WriteDateTime();
if(filename != 0) { res &= WriteLine("Filename", filename); }
if(funcname != 0) { res &= WriteLine("Function", funcname); }
if(message != 0) { res &= WriteLine("Entry", message); }
return res;
}
/**
\brief Go one level up (if possible).
**/
void LogXML::goUp(void)
{
if(Depth > 1)
{
Depth--;
WriteLine("</LogItem>");
}
}
/**
\brief Write a log entry.
\param message entry
\param filename Source file name (optional)
\param funcname Function name (optional)
\return true (if successful)
<LogItem>
<Date>YYYY-MM-DD</Date>
<Time>HH:MM:SS.mmm</Time>
<Filename>filename</Filename>
<Function>function</Function>
<Entry>message</Entry>
</LogItem>
**/
bool LogXML::Log(char* message, char* filename, char* funcname)
{
bool res = true;
goDown();
if(filename != 0) { res &= WriteLine("Filename", filename); }
if(funcname != 0) { res &= WriteLine("Function", funcname); }
res &= WriteLine("Entry", message);
goUp();
return res;
}
/**
\brief Writes current date and time
\return true (if successful)
<Date>YYYY-MM-DD</Date>
<Time>HH:MM:SS.mmm</Time>
**/
bool LogXML::WriteDateTime(void)
{
char buf1[256]; // for strftime
char buf2[256]; // result
time_t ltime; time( <ime );
short mSec = (short)(long(1000*mtime())%1000);
// Datum
strftime( buf2, 255, "<Date>%Y-%m-%d</Date>", localtime(<ime));
bool res = LogXML::WriteLine(buf2); // write
// Uhrzeit ...
// hier wird der String <buf1> f�r strftime() gebastelt,
// denn es m�ssen die Millisekunden integriert werden
sprintf(buf1, "<Time>%%H:%%M:%%S.%03i</Time>", mSec);
strftime( buf2, 255, buf1, localtime(<ime)); // Auslesen des Ergebnisses
res &= LogXML::WriteLine(buf2); // schreiben
return res;
}
/**
\brief Writes current UNIX-Timestamp
\return true (if successful)
**/
bool LogXML::WriteTimestamp(void)
{
char buf[256];
sprintf(buf, "<Timestamp>%.3f</Timestamp>", mtime());
return LogXML::WriteLine(buf);
}
/**
\brief Writes a line (raw).
\return true (if successful)
**/
bool LogXML::WriteLine(char* data)
{
bool res = true;
res &= WriteData("\n");
for(int i=0; i<Depth; i++)
{ res &= WriteData(" "); }
res &= WriteData(data);
return res;
}
/**
\brief Writes a line: <tagname>contents</tagname>.
\return true (if successful)
**/
bool LogXML::WriteLine(char* tagname, char* contents)
{
char* buf = new char[ 2*strlen(tagname) + strlen(contents) + 10 ];
sprintf(buf, "<%s>%s</%s>", tagname, contents, tagname);
bool res = WriteLine(buf);
delete[] buf;
return res;
}
/**
\brief Write to Logfile
\param data String to write
\return true (if successful)
**/
bool LogXML::WriteData(char* data)
{
try
{ fwrite(data, strlen(data), 1, LogFile); }
catch(...)
{
char buf[200];
sprintf("LogXML: Could not write to file \"%s\".\n", m_strFilename);
perror(buf);
return false; // Error
}
return true; // Successful
}
/**
\brief Destructor; closes open tags and log file
**/
LogXML::~LogXML()
{
while(Depth > 1)
{ goUp(); }
Log("Log File closed", FileName(__FILE__));
Depth--; // up
LogXML::WriteLine("</LogFile>"); // Last Line
// Try to close log file
try
{ fclose(LogFile); }
catch(...)
{
char buf[200];
sprintf(buf, "LogXML: Error closing file \"%s\".\n", m_strFilename);
perror(buf);
}
delete[] m_strFilename;
}
/// base name of file
char* FileName(char* strFile)
{
char* x = strrchr(strFile, '\\');
if(x) { return (x+1); }
else { return "Error"; }
}
/// UNIX timestamp: seconds from 1970-01-01 00:00:00 (UTC)
double mtime(void)
{
_timeb ts;
_ftime( &ts );
return (int)ts.time + (ts.millitm/1000.0);
}
#endif // LOGXML_CPP
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.