فهرست منبع

Enhance file_appender with all property settings.

Sam Jaffe 6 سال پیش
والد
کامیت
049e0a4db3
2فایلهای تغییر یافته به همراه36 افزوده شده و 12 حذف شده
  1. 1 0
      include/logger/detail/appender.h
  2. 35 12
      src/loggers/file_appender.cxx

+ 1 - 0
include/logger/detail/appender.h

@@ -4,6 +4,7 @@
 
 namespace logging {
   struct appender {
+    appender(level min = level::debug) : min_log_level(min) {}
     virtual ~appender() = default;
     virtual void write(std::string const & msg) = 0;
     virtual void flush() = 0;

+ 35 - 12
src/loggers/file_appender.cxx

@@ -20,17 +20,24 @@ namespace logging {
   level level_from_string(std::string const & value);
 }
 
+struct buffer : std::filebuf {
+  buffer(properties const & props);
+  buffer * setbuf(char* data, std::streamsize n);
+};
+
 class file_appender : public appender {
 public:
-  static std::shared_ptr<appender> create(properties const&);
+  static std::shared_ptr<appender> create(properties const & props);
   
-  explicit file_appender(const std::string& fname, bool append);
+  explicit file_appender(properties const & props);
   
   void write(std::string const & msg) override;
   void flush() override;
 private:
   bool flush_immediately_{false};
-  std::ofstream out_;
+  buffer rdbuf_;
+  std::ostream out_;
+  std::unique_ptr<char[]> buffer_;
 };
 
 using namespace logging::property;
@@ -38,25 +45,41 @@ properties const DEFAULT_FILE_APPENDER{_obj({
   {"immediateFlush", _v(true)},
   {"threshold", _v("ERROR")},
   {"filename", {}}, // Will throw if accessed
-  {"fileAppend", _v(true)}/*,
+  {"fileAppend", _v(true)},
   {"bufferedIO", _v(false)},
-  {"bufferSize", _v(8192)}*/
+  {"bufferSize", _v(8192)}
 })};
 
 std::shared_ptr<appender> file_appender::create(properties const & props) {
   properties const actual = DEFAULT_FILE_APPENDER.mergedWith(props);
-  file_appender app(actual["filename"], actual["fileAppend"]);
-  app.flush_immediately_ = actual["immediateFlush"];
-  app.min_log_level = level_from_string(actual["threshold"]);
-  return std::make_shared<file_appender>(std::move(app));
+  return std::make_shared<file_appender>(actual);
 }
 
 static std::ios_base::openmode mode(bool append) {
-  return (append ? std::ios_base::app : 0) | std::ios_base::out;
+  return append ? std::ios_base::app : 0;
+}
+
+buffer::buffer(properties const & props) : std::filebuf() {
+  if (open(props["filename"], mode(props["fileAppend"])) == nullptr) {
+    // TODO: throw
+  }
 }
 
-file_appender::file_appender(const std::string& fname, bool append)
-: out_(fname, mode(append)) {}
+buffer * buffer::setbuf(char* data, std::streamsize n) {
+  std::filebuf::setbuf(data, n);
+  return this;
+}
+
+file_appender::file_appender(properties const & props)
+: appender(level_from_string(props["threshold"])),
+  flush_immediately_(props["immediateFlush"]),
+  rdbuf_(props), out_(&rdbuf_) {
+  if (props["bufferedIO"]) {
+    int const size = props["bufferSize"];
+    buffer_.reset(new char[size]);
+    rdbuf_.setbuf(buffer_.get(), size);
+  }
+}
 
 void file_appender::write(std::string const & msg) {
   out_ << msg;