// $Id: LogStream.h,v 1.8.2.3 2000/03/05 04:57:36 justin Exp $
// $Revision: 1.8.2.3 $ $Author: justin $ $Date: 2000/03/05 04:57:36 $
//
//ScryMUD Server Code
//Copyright (C) 1998 Ben Greear
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// To contact the Author, Ben Greear: greear@cyberhighway.net, (preferred)
// greearb@agcs.com
//
#include <strstream.h>
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifndef LOG_STREAM_INCLUDE
#define LOG_STREAM_INCLUDE
#define LOG_STREAM_BUF_SIZE 200000 /* 200 kilobytes storage */
enum LogLevelEnum {
DIS = 1, //disasters
ERROR = 2, //errors
WRN = 4, //warnings
INF = 8, //info
TRC = 16, //function trace
DBG = 32, //debug
LSEC = 64, // log security violations
DB = 128, // READ or WRITE from the world files
XMT = 256, // Output from MUD to characters
INP = 512, // Input from players
SCRIPT = 1024, //Scripting specific stuff
PARSE = 2048, //PARSE specific
DBG2 = 4096, //More verbose than debug even..
ALL = ~(0) // all
};//enum
class LogStream;
typedef LogStream& (*__ls_manip)(LogStream&);
class LogStream : public ostrstream {
protected:
char buf[LOG_STREAM_BUF_SIZE];
char* filename;
int log_level;
int file_action;
public:
enum actionE {
APPEND = 0,
OVERWRITE = 1
};
LogStream(const char* fname, int lvl, actionE fileAction)
: ostrstream(buf, LOG_STREAM_BUF_SIZE),
log_level(lvl), file_action(fileAction)
{ filename = strdup(fname); }
LogStream(const char* fname, int lvl)
: ostrstream(buf, LOG_STREAM_BUF_SIZE),
log_level(lvl), file_action(OVERWRITE)
{ filename = strdup(fname); }
~LogStream() {
flushToFile(filename);
free(filename);
}
const char* getFileName() const { return filename; }
int flushToFile(const char* fname) {
*((ostrstream*)this) << ends;
// Allow some outside filtering...
if (file_action == OVERWRITE) {
ofstream ofile(fname);
ofile << str();
ofile.close();
char buf[200];
sprintf(buf, "truncate_log %s", fname);
system(buf);
}
else if (file_action == APPEND) {
ofstream ofile(fname, ios::app);
ofile << str();
ofile.close();
}
seekp(0); //Reset the streambuf
return 0;
}
/** The idea is that the << (const char*) method will be called
* very often. So, I'm going to over-ride it, and do a check on
* our buffer usage. If it's more than 90%, then dump I'm going
* to flush it and reset myself to the beginning of the buffer.
*/
LogStream& operator<< (char* msg) {
return (*this) << (const char*)msg;
}
LogStream& operator<< (const char* msg) {
*((ostrstream*)this) << msg;
if (pcount() > ((float)(LOG_STREAM_BUF_SIZE) * 0.95)) {
flushToFile(filename);
}//if
return *this;
}//operator overload
LogStream& operator<< (const void* ptr) {
*((ostrstream*)this) << ptr;
return *this;
}
LogStream& operator<< (int i) {
*((ostrstream*)this) << i;
return *this;
}
int ofLevel(LogLevelEnum i) { return ((int)(i) & log_level); }
int truncate() {
return 1;
/*
char buf[200];
close();
sprintf(buf, "truncate_log %s", filename);
system(buf);
open(filename, ios::app); //open and append
return 1;
*/
}//int
int getLevel() { return log_level; }
void setLevel(int i) { log_level = i; }
void log(int lvl, const char* msg);
void dbg(const char* msg) {
log(DBG, msg);
}
void log(const char* msg) {
log(DBG, msg);
}
LogStream& operator<<(__ls_manip func) { return (*func)(*this); }
};//LogStream
inline LogStream& endl(LogStream& lstr) {
return lstr << (const char*)("\n");
}
inline LogStream& nl(LogStream& lstr) {
return lstr << (const char*)("\n");
}
inline LogStream& flush(LogStream& lstr) {
lstr.flush();
return lstr;
}
inline void LogStream::log(int lvl, const char* msg) {
if ((int)(lvl) & log_level) {
(*this) << msg;
(*this) << nl;
flush();
}
}//log
#endif