/** * @file sink.h * * Defines classes for log sinks (i.e. outputs) */ #pragma once #include #include namespace l3pp { /** * Base class for a logging sink. It can only log some log entry to which some * formatting is applied (see Formatter). A Sink may be given a log level, * which filters out all entries below that level. By default is logs all * entries. */ class Sink { LogLevel level; FormatterPtr formatter; virtual void logEntry(std::string const& entry) const = 0; public: Sink() : level(LogLevel::ALL), formatter(std::make_shared()) { } Sink(FormatterPtr formatter) : level(LogLevel::ALL), formatter(formatter) { } /** * Default destructor. */ virtual ~Sink() {} LogLevel getLevel() const { return level; } void setLevel(LogLevel level) { this->level = level; } FormatterPtr getFormatter() const { return formatter; } void setFormatter(FormatterPtr formatter) { this->formatter = formatter; } /** * Logs the given message with context info */ void log(EntryContext const& context, std::string const& message) const; }; typedef std::shared_ptr SinkPtr; /** * Logging sink that wraps an arbitrary `std::ostream`. * It is meant to be used for streams like `std::cout` or `std::cerr`. */ class StreamSink: public Sink { /// Output stream. mutable std::ostream os; void logEntry(std::string const& entry) const override { os << entry << std::flush; } explicit StreamSink(std::ostream& _os) : os(_os.rdbuf()) {} public: /** * Create a StreamSink from some output stream. * @param os Output stream. */ static SinkPtr create(std::ostream& os) { return SinkPtr(new StreamSink(os)); } }; /** * Logging sink for file output. */ class FileSink: public Sink { /// File output stream. mutable std::ofstream os; void logEntry(std::string const& entry) const override { os << entry << std::flush; } explicit FileSink(const std::string& filename) : os(filename, std::ios::out) {} public: /** * Create a FileSink that logs to the specified file. * The file is truncated upon construction. * @param filename */ static SinkPtr create(const std::string& filename) { return SinkPtr(new FileSink(filename)); } }; }