logging: split FileHandlerFactory into two classes
[folly.git] / folly / experimental / logging / FileHandlerFactory.cpp
index c398654f6a5f5a1df16f2ca8e94843558d9a51d4..c6b66459e0da236848eee37fce57409babedbcc0 100644 (file)
  */
 #include <folly/experimental/logging/FileHandlerFactory.h>
 
-#include <folly/Conv.h>
-#include <folly/experimental/logging/AsyncFileWriter.h>
-#include <folly/experimental/logging/ImmediateFileWriter.h>
+#include <folly/experimental/logging/FileWriterFactory.h>
 #include <folly/experimental/logging/StandardLogHandler.h>
 #include <folly/experimental/logging/StandardLogHandlerFactory.h>
 
-using std::make_shared;
-using std::shared_ptr;
-using std::string;
-
 namespace folly {
 
 class FileHandlerFactory::WriterFactory
@@ -32,73 +26,27 @@ class FileHandlerFactory::WriterFactory
  public:
   bool processOption(StringPiece name, StringPiece value) override {
     if (name == "path") {
-      if (!stream_.empty()) {
-        throw std::invalid_argument(
-            "cannot specify both \"path\" and \"stream\" "
-            "parameters for FileHandlerFactory");
-      }
       path_ = value.str();
       return true;
-    } else if (name == "stream") {
-      if (!path_.empty()) {
-        throw std::invalid_argument(
-            "cannot specify both \"path\" and \"stream\" "
-            "parameters for FileHandlerFactory");
-      }
-      stream_ = value.str();
-      return true;
-    } else if (name == "async") {
-      async_ = to<bool>(value);
-      return true;
-    } else if (name == "max_buffer_size") {
-      auto size = to<size_t>(value);
-      if (size == 0) {
-        throw std::invalid_argument(to<string>("must be a postive number"));
-      }
-      maxBufferSize_ = size;
-      return true;
-    } else {
-      return false;
     }
+
+    // TODO: In the future it would be nice to support log rotation, and
+    // add parameters to control when the log file should be rotated.
+
+    return fileWriterFactory_.processOption(name, value);
   }
 
   std::shared_ptr<LogWriter> createWriter() override {
     // Get the output file to use
-    File outputFile;
-    if (!path_.empty()) {
-      outputFile = File{path_, O_WRONLY | O_APPEND | O_CREAT};
-    } else if (stream_ == "stderr") {
-      outputFile = File{STDERR_FILENO, /* ownsFd */ false};
-    } else if (stream_ == "stdout") {
-      outputFile = File{STDOUT_FILENO, /* ownsFd */ false};
-    } else {
-      throw std::invalid_argument(to<string>(
-          "unknown stream for FileHandlerFactory: \"",
-          stream_,
-          "\" expected one of stdout or stderr"));
-    }
-
-    // Determine whether we should use ImmediateFileWriter or AsyncFileWriter
-    if (async_) {
-      auto asyncWriter = make_shared<AsyncFileWriter>(std::move(outputFile));
-      if (maxBufferSize_.hasValue()) {
-        asyncWriter->setMaxBufferSize(maxBufferSize_.value());
-      }
-      return asyncWriter;
-    } else {
-      if (maxBufferSize_.hasValue()) {
-        throw std::invalid_argument(to<string>(
-            "the \"max_buffer_size\" option is only valid for async file "
-            "handlers"));
-      }
-      return make_shared<ImmediateFileWriter>(std::move(outputFile));
+    if (path_.empty()) {
+      throw std::invalid_argument("no path specified for file handler");
     }
+    return fileWriterFactory_.createWriter(
+        File{path_, O_WRONLY | O_APPEND | O_CREAT});
   }
 
   std::string path_;
-  std::string stream_;
-  bool async_{true};
-  Optional<size_t> maxBufferSize_;
+  FileWriterFactory fileWriterFactory_;
 };
 
 std::shared_ptr<LogHandler> FileHandlerFactory::createHandler(