Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Easiest way to print timestamp to ostream

I'd like to add a timestamp to certain outputs to the std::cout / std::cerr ostreams, without using modified standard streams, like so:

std::cerr << timestamp << "Warning!\n";

or so:

std::cerr << timestamp() << "Warning!\n";

The output should look like this:

[2020-01-23 17:40:15 CET] Warning!

But I'm really not happy with what I've come up with:

class TimeStamp {};

std::ostream &operator<<(std::ostream &stream, const TimeStamp &ts) 
{
    std::time_t t = std::time(nullptr);
    stream << "[" << std::put_time(std::localtime(&t), "%F %T %Z") << "] ";
    return stream;
}

TimeStamp ts;

int main()
{
    std::cerr << ts << "Warning!\n";
    std::cerr << ts << "Another warning!\n";
}

So I'm basically defining an empty class, using a global declaration and overloading the '<<' operator. This feels wrong. A static function like timestamp() is probably better suited, but I'm not quite sure how to go on about this. All the examples I've found online used the overloaded '<<' operator, but it usually made more sense to do so, because some class state was output. Can I locally create an ostream and return that in the function?

like image 816
panda-byte Avatar asked Jan 01 '23 08:01

panda-byte


2 Answers

There's nothing wrong with the way you've done it. But if you're looking for alternatives, you could create an ostream wrapper:

class Logger {
  private:
    std::ostream &stream;

    void print_time() {
        std::time_t t = std::time(nullptr);
        stream << "[" << std::put_time(std::localtime(&t), "%F %T %Z") << "] ";
    }
  public:
    //Maybe also take options for how to log?
    Logger(std::ostream &stream) : stream(stream) { }

    template <typename T>
    std::ostream &operator<<(const T &thing)  {
        print_time();
        return stream << thing;
    }
};

int main()
{
    Logger log(std::cerr);
    log << "Warning!" << std::endl;
    log << "Another warning!" << std::endl;
}

See it run here: https://ideone.com/YRawuQ

like image 120
scohe001 Avatar answered Jan 05 '23 17:01

scohe001


If you're just looking for a standalone function which is what I understood from a "static function like timestamp()" you can just return the date as a string:

std::string timeStamp(){
    std::ostringstream strStream;
    std::time_t t = std::time(nullptr);
    strStream<< "[" << std::put_time(std::localtime(&t), "%F %T %Z") << "] ";
    return strStream.str();
}


int main(){
    std::cout<<timeStamp()<<" Testing!";   
    return 0;
}

Remember to include sstream

like image 36
PSgold Avatar answered Jan 05 '23 17:01

PSgold