Foros - Stratos

Programadores => Código de la Semana => Mensaje iniciado por: ethernet en 31 de Diciembre de 2002, 07:34:50 PM

Título: CLogger - Grugnorr
Publicado por: ethernet en 31 de Diciembre de 2002, 07:34:50 PM


/////////////////////////////

//

// fichero: CLogger.h

//

/////////////////////////////

#ifndef _CLOGGER_H

#define _CLOGGER_H



//-------------INCLUDES--------------------

#include <iostream>

#include <fstream>

#include <string>





class CLogger

{

public:

static CLogger& Instance(const char* FilePath="Log.txt");

std::ofstream& Log(){return m_FileStream;}



private:

void Init(const char* FilePath);



/* La creación y destrucción del singleton de forma explícita se prohibe*/

CLogger(){};

CLogger(const CLogger& Logger);

CLogger& operator=(const CLogger& Logger);

~CLogger();

/**/



/*el fichero donde escribimos el log*/

std::ofstream   m_FileStream;



static CLogger*  ms_pInstance;



};



//---------------------DEFINES----------------



//Por comodidad, podemos tratar al singleton como si fuera una variable global

#define g_Logger  CLogger::Instance()





#define LOG(TEXT) {g_Logger.Log()<<TEXT;}



#define LOGLN(TEXT) {g_Logger.Log()<<TEXT<<std::endl;}







#ifdef _DEBUG

//logs que sólo queremos en modo debug



#define LOG_DEBUG(TEXT) {g_Logger.Log()<<TEXT;}

#define LOGLN_DEBUG(TEXT) {g_Logger.Log()<<TEXT<<std::endl;}



#else

//en release no los escribimos

#define LOG_DEBUG(TEXT) {}

#define LOGLN_DEBUG(TEXT) {}



#endif



//los logs de errores añaden el fichero y la línea donde se llama



#define LOG_ERROR(TEXT) {g_Logger.Log()<<"FATAL_ERROR!: "<< TEXT

 <<" AT FILE: "<<__FILE__<<" IN LINE: "<<__LINE__;}



#define LOGLN_ERROR(TEXT) {g_Logger.Log()<<"FATAL_ERROR!: "<< TEXT

 <<" AT FILE: "<<__FILE__<<" IN LINE: "<<__LINE__<<std::endl;}



#endif //_CLOGGER_H





/////////////////////////////

//

//fichero: CLogger.cpp

//

/////////////////////////////



#include "CLogger.h"

#include <exception>





//Linkamos las variables estáticas

CLogger* CLogger::ms_pInstance=NULL;



//--------------CLOGGER()----------------

void CLogger::Init(const char* FilePath)

{

m_FileStream.open(FilePath,std::ios::out|std::ios::trunc);



if(m_FileStream==NULL)//No podemos crear un fichero de log :(

 throw std::exception("Couldn´t open file stream");

}



//-----------------~CLOGGER()---------------

CLogger::~CLogger()

{

delete ms_pInstance;

ms_pInstance=NULL;

m_FileStream.close();



}

//----------------INSTANCE()----------------

//Punto de acceso al singleton. Se creará en la primera llamada.

CLogger& CLogger::Instance(const char* FilePath)

{

if(ms_pInstance==NULL)

{  

 ms_pInstance=new CLogger();

 ms_pInstance->Init(FilePath);

}





return *ms_pInstance;

}



/////////////////////////////

//

//fichero main.cpp

//

/////////////////////////////



#include "CLogger.h"

#include <iostream>





void main()

{

/*Creamos el fichero de log*/

CLogger::Instance("LogPrueba.txt");



int i=22;





LOGLN("Hola soy Grug, tengo "<<i<<" años ,llego tarde y la novia me mata... chaops


;)");



/*llamada sin macro.*/

g_Logger.Log()<<"Hola soy Grug, tengo "<<i<<" años "<<" y  la novia me mata... chaops


;)"<<std::endl;



LOGLN_ERROR("Error!, kk de ejemplo;)");

}





Título: CLogger - Grugnorr
Publicado por: Mars Attacks en 31 de Diciembre de 2002, 07:43:32 PM
                                Jejeje, menuda prueba más rara. Menos mal que no dice a qué lo mata  :X9:
Personalmente, recomiendo complicarse un poquito más la vida para hacer logs en html. Desde la primera vez que los vi creo que me enamoré de ellos. Puedes poner los errores en rojo, cabeceras en mayor tamaño para los puntos principales de las listas, letra pequeña para las sublistas, valores en negrita... en fin, para qué contaros qué es un htm  :)
Pues eso, que modificando un poco un logger ya terminado se puede conseguir algo con mucho más estilo.                                
Título: CLogger - Grugnorr
Publicado por: ethernet en 31 de Diciembre de 2002, 07:57:23 PM
Si, para ellos puedes tener  un log con metedos virtuales e implementarlo como quieras:

CLog *log = new CHTMLLog; // por ejemplo

Por otro lado un comentario al codigo:
Aunque no se llame al destructor no quita de q se pueda poner un metodo llamado Shutdown o Release.

saludos
Título: ...
Publicado por: Grugnorr en 01 de Enero de 2003, 09:52:50 AM
                                Uff, las 10 de la mañana,Año Nuevo.Me acuesto y me voy de vacaciones a Paris una semana....

Lo del log en HTML ya lo he hecho alguna vez, simplemente escribir los TAGs en el fichero y guardarlo como HTML

Lo de destruir el singleton... Lo dejé así por ser los singletons un tema aparte, que puede dar para mucho más de lo que parece(un capítulo del libro más rallante jamás escrito, ModernC++ Design, y así intento que recordéis que el sinfleton del Design Patterns leakea ;)

Lo fundamental era la idea simple de usar streams para loggear, que no se lo he visto a nadie...


PD: Que mi rack fuera tan tímido que rehusara dejarme acceder al código antiguo de mi logger no ayuda a dar una versión muy currada, pero como digo, cada cual lo ajusta a sus necesidades. Yo tenía mis excdpciones integradas y alguna cosilla más.