Skip to content

Instantly share code, notes, and snippets.

@bqv
Last active March 17, 2016 23:20
Show Gist options
  • Select an option

  • Save bqv/84c8ac50d4df001a89e8 to your computer and use it in GitHub Desktop.

Select an option

Save bqv/84c8ac50d4df001a89e8 to your computer and use it in GitHub Desktop.

Revisions

  1. Tony O revised this gist Mar 17, 2016. 1 changed file with 9 additions and 0 deletions.
    9 changes: 9 additions & 0 deletions error.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,9 @@
    Program received signal SIGSEGV, Segmentation fault.
    0x00007ffff7b68fb9 in std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6

    #0 0x00007ffff7b68fb9 in std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
    #1 0x000000000040170a in log::operator<< (log=..., f=@0x400d00: {std::ostream &(std::ostream &)} 0x400d00 <std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)@plt>) at logger.cpp:47
    #2 0x0000000000401846 in log::endl (log=...) at logger.cpp:71
    #3 0x0000000000401819 in log::done (log=...) at logger.cpp:64
    #4 0x00000000004016e1 in log::operator<< (log=..., f=@0x401801: {log::Logger &(log::Logger &)} 0x401801 <log::done(log::Logger&)>) at logger.cpp:42
    #5 0x0000000000400ee6 in main (argc=1, argv=0x7fffffffe5a8) at main.cpp:16
  2. Tony O created this gist Mar 17, 2016.
    73 changes: 73 additions & 0 deletions logger.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,73 @@
    #include "logger.hpp"

    namespace log
    {
    Log fatal = Log(std::cerr, 00, "FATAL");
    Log error = Log(std::cerr, 10, "ERROR");
    Log warn = Log(std::cerr, 20, "WARN");
    Log info = Log(std::cout, 30, "INFO");
    Log debug = Log(std::cerr, 40, "DEBUG");

    std::vector<std::shared_ptr<std::ostream>> Logger::os;
    std::mutex Logger::mutex;

    Logger::Logger(std::ostream& console)
    : console(console)
    {
    }

    Logger::~Logger()
    {
    }

    void Logger::tee(std::vector<std::shared_ptr<std::ostream>> targets)
    {
    for (auto os : targets)
    Logger::os.push_back(os);
    }

    Log::Log(std::ostream& console, short int num, const char* str)
    : Logger(console)
    , str(str)
    , num(num)
    {
    }

    Log::~Log()
    {
    }

    Logger& operator<< (Logger& log, Logger& (&f)(Logger&))
    {
    return f(log);
    }

    Logger& operator<< (Logger& log, std::ostream& (&f)(std::ostream&))
    {
    log.console << f;
    for (const std::shared_ptr<std::ostream>& out : log.os)
    *out << f;
    return log;
    }

    Logger& operator<< (Log& loglvl, Logger& (&f)(Logger&))
    {
    Log::mutex.lock();

    Logger log = loglvl;

    return log << f;
    }

    Logger& done(Logger& log)
    {
    endl(log);
    Logger::mutex.unlock();
    return log;
    }

    Logger& endl(Logger& log)
    {
    return log << std::endl;
    }
    };
    58 changes: 58 additions & 0 deletions logger.hpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,58 @@
    #ifndef _LOGGER_HPP_
    #define _LOGGER_HPP_

    #include <iostream>
    #include <memory>
    #include <vector>
    #include <mutex>

    namespace log
    {
    class Logger
    {
    protected:
    Logger(std::ostream& console);

    static std::vector<std::shared_ptr<std::ostream>> os;
    static std::mutex mutex;
    std::ostream& console;

    public:
    virtual ~Logger();

    static void tee(const std::vector<std::shared_ptr<std::ostream>> targets);

    template <typename T>
    friend Logger& operator<< (Logger& log, T val);
    friend Logger& operator<< (Logger& log, Logger& (&f)(Logger&));
    friend Logger& operator<< (Logger& log, std::ostream& (&f)(std::ostream&));

    friend Logger& done(Logger& log);
    friend Logger& endl(Logger& log);
    };

    class Log : public Logger
    {
    protected:
    char const* str;
    short int num;

    public:
    Log(std::ostream& console, short int num, const char* str);
    virtual ~Log();

    template <typename T>
    friend Logger& operator<< (Log& log, T val);
    friend Logger& operator<< (Log& log, Logger& (&f)(Logger&));
    friend Logger& operator<< (Log& log, std::ostream& (&f)(std::ostream&));
    };

    extern Logger& done(Logger& log);
    extern Logger& endl(Logger& log);

    extern Log fatal, error, warn, info, debug;
    };

    #include "logger.ipp"

    #endif /*LOGGER_HPP*/
    24 changes: 24 additions & 0 deletions logger.ipp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@

    namespace log
    {
    template <typename T>
    Logger& operator<< (Logger& log, T val)
    {
    log.console << val;
    for (const std::shared_ptr<std::ostream>& out : log.os)
    *out << val;
    return log;
    }

    template <typename T>
    Logger& operator<< (Log& loglvl, T val)
    {
    Log::mutex.lock();

    Logger log = loglvl;

    // Todo: timestamp
    log << '+' << loglvl.num << ' ' << loglvl.str << ' ';
    return log << val;
    }
    };
    9 changes: 9 additions & 0 deletions main.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,9 @@
    #include "logger.hpp"

    #include <iostream>

    int main(int argc, char *argv[])
    {
    log::info << "Starting..." << log::done;
    return EXIT_SUCCESS;
    }