Una clase para Loggearlos a todos

Una buena forma de sacar información de lo que está pasando en nuestras simulaciones SystemC es generar un archivo de log con la distinta información que necesitemos (nombre del módulo, tiempo de simulación, qué se está enviado o recibiendo, etc.).

Para ello la forma más elegante y sencilla de hacerlo es crearse una clase especial para la tarea, que los demás módulos puedan usar para enviar sus información y ésta los grabe en un fichero. Esto se consigue diseñando una clase de tipo singleton. Este patrón de diseño restringe la creación de un solo objecto de una clase dada. En nuestro caso, hará que todos los módulos usen el mismo objecto.

Para diseñar una clase singleton, hemos de tener en cuenta lo siguiente:

  • La propia clase crea la única instancia
  • Declarar el constructor como privado para que la clase no se pueda instanciar directamente
  • Permitir el acceso al objecto único a través de un método de la clase

Eso se resume en crear una clase con el constructor privado y un método que cree el objecto si no está creado ya y devuelta la referencia al objecto creado:

fichero Log.h

class Log
{
public:
static Log* Instance();

private:
Log(const char*);
static Log* m_pInstance;
std::ofstream m_stream;
...
}

fichero Log.cpp

Log* Log::m_pInstance = NULL;

Log*
Log::Instance()
{
if (!m_pInstance)
m_pInstance = new Log("Log.txt");
return m_pInstance;
}

Log::Log(const char* filename)
{
m_stream.open(filename);
}

 

Para usar esta clase, hay que instanciarla en cada módulo que quiera usarla de la siguiente forma

 

Log *my_log = Log::Instance();

 

Para acabar, le añadimos a la clase Log algunos métodos para bajar a fichero la información que queramos y listo:

 

// Método para ser llamado: my_log->SC_log("Mi mensaje de log");
void Log::SC_log(std::ostringstream msg)
{
m_stream << "time " << sc_core::sc_time_stamp() << ": "
<< msg << std::endl; } // Método para usarlo dentro de streams de C++ // es posible hacer my_log->SC_log() << name() << ". Mi mensaje de log" << std::endl;
std::ofstream& Log::SC_log()
{
m_stream << "time " << sc_core::sc_time_stamp() << ": ";
return m_stream;
}

 

En el segundo caso, el fichero resultante será de texto plano con el tiempo actual de simulación, el nombre del módulo que genera la linea y el texto deseado. Podríamos usar alguna librería para generar un fichero XML, o algo más estructurado, pero eso es otra historia 😉

Y eso es todo, espero que os sirva para tener un log común de todo vuestro sistema de una manera fácil y rápida.

Leave a Reply