file_appender.cxx 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. //
  2. // file_logger.cxx
  3. // logging
  4. //
  5. // Created by Sam Jaffe on 4/1/19.
  6. //
  7. #include <fstream>
  8. #include "expect/expect.hpp"
  9. #include "resource_factory/prototype_factory.hpp"
  10. #include "logger/detail/appender.h"
  11. #include "logger/log_manager.h"
  12. #include "logger/properties.h"
  13. using namespace logging;
  14. namespace logging {
  15. level level_from_string(std::string const & value);
  16. }
  17. class file_appender : public appender {
  18. public:
  19. static std::shared_ptr<appender> create(properties const&);
  20. explicit file_appender(const std::string& fname, bool append);
  21. void write(std::string const & msg) override;
  22. void flush() override;
  23. private:
  24. bool flush_immediately_{false};
  25. std::ofstream out_;
  26. };
  27. using namespace logging::property;
  28. properties const DEFAULT_FILE_APPENDER{_obj({
  29. {"immediateFlush", _v(true)},
  30. {"threshold", _v("ERROR")},
  31. {"filename", {}}, // Will throw if accessed
  32. {"fileAppend", _v(true)}/*,
  33. {"bufferedIO", _v(false)},
  34. {"bufferSize", _v(8192)}*/
  35. })};
  36. std::shared_ptr<appender> file_appender::create(properties const & props) {
  37. properties const actual = DEFAULT_FILE_APPENDER.mergedWith(props);
  38. file_appender app(actual["filename"], actual["fileAppend"]);
  39. app.flush_immediately_ = actual["immediateFlush"];
  40. app.min_log_level = level_from_string(actual["threshold"]);
  41. return std::make_shared<file_appender>(std::move(app));
  42. }
  43. static std::ios_base::openmode mode(bool append) {
  44. return (append ? std::ios_base::app : 0) | std::ios_base::out;
  45. }
  46. file_appender::file_appender(const std::string& fname, bool append)
  47. : out_(fname, mode(append)) {}
  48. void file_appender::write(std::string const & msg) {
  49. out_ << msg;
  50. if (flush_immediately_) { flush(); }
  51. }
  52. void file_appender::flush() { out_.flush(); }
  53. namespace {
  54. bool _ = appenders::instance().bind("File", file_appender::create);
  55. }