c++ - Agregar marca de tiempo con std:: cout
logging iostream (4)
Quieres algo como:
ostream & addTime() {
std::cout << getTime();
return std::cout;
y úsalo así:
addTime() << "printing data" << std::endl;
Tengo el siguiente código que está redirigiendo mi salida std::cout
a un archivo de registro.
std::ofstream out("out.txt");
std::streambuf *coutbuf = std::cout.rdbuf(); //save old buf
std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt!
Ahora lo que quiero es que cada vez que se produzca una nueva línea, la marca de tiempo actual se escriba en el archivo.
Sé que puedo lograr esto con:
std::cout << getTime() << "printing data" << std::endl;
Pero lo que quiero es que std::cout
se ocupe de ello automáticamente de alguna manera. ¿Es eso posible?
intente algo como lo siguiente (es solo un resumen, no lo probé):
class logger : ostream
{
bool line = true;
public:
template<typename T> ostream& operator<< (T somedata)
{
if (line)
ostream << getTime();
ostream << somedata;
line = somedata == std::endl;
}
}
Eso es un truco desde un punto diferente.
Cuando ejecuta el programa, canalice la salida en awk y agregue allí la marca de tiempo. El comando:
<program> | awk ''{print strftime()" "$0}'' > logfile
Si está usando Windows, puede descargar gawk desde este sitio web .
Puede formatear la hora impresa por strftime
. Más información sobre eso se puede encontrar en el manual
Supongo que desea imprimir el TimeStamp, si el primer carácter de la línea siguiente aparece en el resultado. Tome una nueva clase y la herede de std :: streambuf y conéctela de la misma forma que lo hace con filebuf. Si aparece una nueva línea-charater, guarde este evento en el objeto. Aparece otro personaje que agrega la marca de tiempo a la transmisión.
Escribí un ejemplo que usa el modismo RAII para conectar el streambuf.
class AddTimeStamp : public std::streambuf
{
public:
AddTimeStamp( std::basic_ios< char >& out )
: out_( out )
, sink_()
, newline_( true )
{
sink_ = out_.rdbuf( this );
assert( sink_ );
}
~AddTimeStamp()
{
out_.rdbuf( sink_ );
}
protected:
int_type overflow( int_type m = traits_type::eof() )
{
if( traits_type::eq_int_type( m, traits_type::eof() ) )
return sink_->pubsync() == -1 ? m: traits_type::not_eof(m);
if( newline_ )
{ // -- add timestamp here
std::ostream str( sink_ );
if( !(str << getTime()) ) // add perhaps a seperator " "
return traits_type::eof(); // Error
}
newline_ = traits_type::to_char_type( m ) == ''/n'';
return sink_->sputc( m );
}
private:
AddTimeStamp( const AddTimeStamp& );
AddTimeStamp& operator=( const AddTimeStamp& ); // not copyable
// -- Members
std::basic_ios< char >& out_;
std::streambuf* sink_;
bool newline_;
};
llamar a un objeto de esta clase de la siguiente manera:
// some initialisation ..
{
AddTimeStamp ats( cout ); // timestamp is active
// every output to ''cout'' will start with a ''getTime()'' now
// ...
} // restore the old streambuf in the destructor of AddTimeStamp