diff --git a/producer/folder_monitor_producer/CMakeLists.txt b/producer/folder_monitor_producer/CMakeLists.txt
index 5f1e83364aa434eecedf61245d962010bdf6b743..813dab2a2cbb9fdf567fb8e39d2d2590f40190f8 100644
--- a/producer/folder_monitor_producer/CMakeLists.txt
+++ b/producer/folder_monitor_producer/CMakeLists.txt
@@ -1,6 +1,8 @@
 set(TARGET_NAME folder-monitor-producer)
 set(SOURCE_FILES
         src/event_detector.cpp
+        src/foldermon_config.cpp
+        src/foldermon_logger.cpp
         )
 
 
@@ -34,13 +36,17 @@ set_target_properties(${TARGET_NAME}-bin PROPERTIES RUNTIME_OUTPUT_DIRECTORY
 ################################
 # Testing
 ################################
+set_property(TARGET ${TARGET_NAME} PROPERTY ENABLE_EXPORTS true)
+
 set(TEST_SOURCE_FILES
         unittests/test_foldermon_config.cpp
+        unittests/mock_foldermon_config.cpp
+#        unittests/test_event_detector_factory.cpp
    )
 
 set(TEST_LIBRARIES "${TARGET_NAME}")
 
-#gtest(${TARGET_NAME} "${TEST_SOURCE_FILES}" "${TEST_LIBRARIES}")
+gtest(${TARGET_NAME} "${TEST_SOURCE_FILES}" "${TEST_LIBRARIES}" ${CMAKE_CURRENT_SOURCE_DIR}/src/foldermon_main.cpp)
 
 install(TARGETS ${TARGET_NAME}-bin DESTINATION bin)
 
diff --git a/producer/folder_monitor_producer/src/foldermon_config.cpp b/producer/folder_monitor_producer/src/foldermon_config.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2d89a9276f35c2eda5ff6dc34c581368591cab49
--- /dev/null
+++ b/producer/folder_monitor_producer/src/foldermon_config.cpp
@@ -0,0 +1,77 @@
+#include "foldermon_config.h"
+#include "foldermon_config_factory.h"
+#include "io/io_factory.h"
+#include "json_parser/json_parser.h"
+
+namespace asapo {
+
+FolderMonConfig config;
+
+FolderMonConfigFactory::FolderMonConfigFactory() : io__{GenerateDefaultIO()} {
+
+}
+
+Error FolderMonConfigFactory::ParseConfigFile(std::string file_name) {
+    JsonFileParser parser(file_name, &io__);
+    Error err = nullptr;
+    (err = parser.GetString("AsapoEndpoint", &config.asapo_endpoint)) ||
+    (err = parser.GetString("Tag", &config.tag)) ||
+    (err = parser.GetString("BeamtimeID", &config.beamtime_id)) ||
+    (err = parser.GetString("Mode", &config.mode_str)) ||
+    (err = parser.GetUInt64("NThreads", &config.nthreads)) ||
+    (err = parser.GetString("LogLevel", &config.log_level_str));
+    return err;
+}
+
+
+Error FolderMonConfigFactory::CheckConfig() {
+    Error err;
+    (err = CheckMode()) ||
+    (err = CheckLogLevel()) ||
+    (err = CheckNThreads());
+    return err;
+}
+
+
+Error FolderMonConfigFactory::SetConfigFromFile(std::string file_name) {
+    auto  err = ParseConfigFile(file_name);
+    if (err) {
+        return err;
+    }
+
+    return CheckConfig();
+}
+
+Error FolderMonConfigFactory::CheckMode() {
+    if (config.mode_str == "tcp") {
+        config.mode = RequestHandlerType::kTcp;
+    } else if (config.mode_str == "filesystem") {
+        config.mode = RequestHandlerType::kFilesystem;
+    } else {
+        return  TextError("wrong producer mode: " + config.mode_str);
+    }
+    return nullptr;
+}
+
+Error FolderMonConfigFactory::CheckLogLevel() {
+    Error err;
+    config.log_level = StringToLogLevel(config.log_level_str, &err);
+    return err;
+}
+
+
+Error FolderMonConfigFactory::CheckNThreads() {
+    if (config.nthreads == 0 || config.nthreads > kMaxProcessingThreads ) {
+        return  TextError("NThreads should between 1 and " + std::to_string(kMaxProcessingThreads));
+    }
+    return nullptr;
+}
+
+
+
+const FolderMonConfig*  GetFolderMonConfig() {
+    return &config;
+}
+
+
+}
\ No newline at end of file
diff --git a/producer/folder_monitor_producer/src/foldermon_config.h b/producer/folder_monitor_producer/src/foldermon_config.h
new file mode 100644
index 0000000000000000000000000000000000000000..06e9c1b827028f2dd68832cd62662212374f9cc4
--- /dev/null
+++ b/producer/folder_monitor_producer/src/foldermon_config.h
@@ -0,0 +1,30 @@
+#ifndef ASAPO_FolderMon_CONFIG_H
+#define ASAPO_FolderMon_CONFIG_H
+
+#include "io/io.h"
+#include "common/error.h"
+#include "logger/logger.h"
+#include "producer/common.h"
+#include "foldermon_config_factory.h"
+
+namespace asapo {
+
+struct FolderMonConfig {
+    std::string asapo_endpoint;
+    LogLevel log_level = LogLevel::Info;
+    std::string tag;
+    uint64_t nthreads = 1;
+    std::string beamtime_id;
+    RequestHandlerType mode = RequestHandlerType::kTcp;
+  private:
+    std::string log_level_str;
+    std::string mode_str;
+    friend FolderMonConfigFactory;
+};
+
+const FolderMonConfig* GetFolderMonConfig();
+
+}
+
+
+#endif //ASAPO_FolderMon_CONFIG_H
diff --git a/producer/folder_monitor_producer/src/foldermon_config_factory.h b/producer/folder_monitor_producer/src/foldermon_config_factory.h
new file mode 100644
index 0000000000000000000000000000000000000000..c35ebd2f888dc8a0d318cd17c077c07f319ea093
--- /dev/null
+++ b/producer/folder_monitor_producer/src/foldermon_config_factory.h
@@ -0,0 +1,27 @@
+#ifndef ASAPO_FolderMon_CONFIG_FACTORY__H
+#define ASAPO_FolderMon_CONFIG_FACTORY__H
+
+#include "io/io.h"
+#include "common/error.h"
+
+namespace asapo {
+
+class FolderMonConfigFactory {
+  public:
+    FolderMonConfigFactory();
+    Error SetConfigFromFile(std::string file_name);
+  public:
+    std::unique_ptr<IO> io__;
+  private:
+    Error ParseConfigFile(std::string file_name);
+    Error CheckMode();
+    Error CheckLogLevel();
+    Error CheckNThreads();
+    Error CheckConfig();
+
+};
+
+}
+
+
+#endif //ASAPO_FolderMon_CONFIG_FACTORY__H
diff --git a/producer/folder_monitor_producer/src/foldermon_logger.cpp b/producer/folder_monitor_producer/src/foldermon_logger.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..20ab66a9820e5cf7543d19451811c38258f35c34
--- /dev/null
+++ b/producer/folder_monitor_producer/src/foldermon_logger.cpp
@@ -0,0 +1,10 @@
+#include "foldermon_logger.h"
+
+namespace asapo {
+
+AbstractLogger* GetDefaultFolderMonLogger() {
+    static Logger logger = asapo::CreateDefaultLoggerBin("producer ");
+    return logger.get();
+}
+
+}
diff --git a/producer/folder_monitor_producer/src/foldermon_logger.h b/producer/folder_monitor_producer/src/foldermon_logger.h
new file mode 100644
index 0000000000000000000000000000000000000000..e5365234dcae764721866caaaaa72b4b486529cb
--- /dev/null
+++ b/producer/folder_monitor_producer/src/foldermon_logger.h
@@ -0,0 +1,14 @@
+#ifndef ASAPO_FolderMon_LOGGER_H
+#define ASAPO_FolderMon_LOGGER_H
+
+#include "logger/logger.h"
+
+namespace asapo {
+
+
+AbstractLogger* GetDefaultFolderMonLogger();
+
+}
+
+
+#endif //ASAPO_FolderMon_LOGGER_H
diff --git a/producer/folder_monitor_producer/src/foldermon_main.cpp b/producer/folder_monitor_producer/src/foldermon_main.cpp
index 3a518ec12140302ea288945038238570e777452e..03c44d2b1f12b198571080d8b8d4be5fbf3799ac 100644
--- a/producer/folder_monitor_producer/src/foldermon_main.cpp
+++ b/producer/folder_monitor_producer/src/foldermon_main.cpp
@@ -5,9 +5,50 @@
 #include <thread>
 
 #include "asapo_producer.h"
+#include "foldermon_config.h"
+#include "foldermon_config_factory.h"
+
+
+using asapo::Producer;
+using asapo::FolderMonConfigFactory;
+using asapo::Error;
+using asapo::GetFolderMonConfig;
+
+Error ReadConfigFile(int argc, char* argv[]) {
+    if (argc != 2) {
+        std::cerr << "Usage: " << argv[0] << " <config file>" << std::endl;
+        exit(EXIT_FAILURE);
+    }
+    FolderMonConfigFactory factory;
+    return factory.SetConfigFromFile(argv[1]);
+}
+
+std::unique_ptr<Producer> CreateProducer() {
+    auto config = GetFolderMonConfig();
+
+
+    Error err;
+    auto producer = Producer::Create(config->asapo_endpoint, config->nthreads,
+                                            config->mode, config->beamtime_id, &err);
+    if(err) {
+        std::cerr << "cannot create producer: " << err << std::endl;
+        exit(EXIT_FAILURE);
+    }
+
+    producer->SetLogLevel(config->log_level);
+    return producer;
+}
 
 
 int main (int argc, char* argv[]) {
+    auto err = ReadConfigFile(argc, argv);
+    if (err) {
+        std::cerr << "cannot read config file: " << err->Explain() << std::endl;
+        return EXIT_FAILURE;
+    }
+
+    auto producer = CreateProducer();
+
     return EXIT_SUCCESS;
 }
 
diff --git a/producer/folder_monitor_producer/unittests/foldermon_mocking.h b/producer/folder_monitor_producer/unittests/foldermon_mocking.h
new file mode 100644
index 0000000000000000000000000000000000000000..57f230bc67442db8f35708cd41065c2da281ca4e
--- /dev/null
+++ b/producer/folder_monitor_producer/unittests/foldermon_mocking.h
@@ -0,0 +1,8 @@
+//
+// Created by yakubov on 22/08/18.
+//
+
+#ifndef ASAPO_FOLDERMON_MOCKING_H
+#define ASAPO_FOLDERMON_MOCKING_H
+
+#endif //ASAPO_FOLDERMON_MOCKING_H
diff --git a/producer/folder_monitor_producer/unittests/mock_foldermon_config.cpp b/producer/folder_monitor_producer/unittests/mock_foldermon_config.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bca6b9f8249f93ce75651c25defb243306513206
--- /dev/null
+++ b/producer/folder_monitor_producer/unittests/mock_foldermon_config.cpp
@@ -0,0 +1,70 @@
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+
+#include "mock_foldermon_config.h"
+#include "../src/foldermon_config_factory.h"
+#include "../src/foldermon_config.h"
+
+#include <unittests/MockIO.h>
+
+using testing::_;
+
+namespace asapo {
+
+Error SetFolderMonConfig (const FolderMonConfig& config) {
+    MockIO mock_io;
+    FolderMonConfigFactory config_factory;
+    config_factory.io__ = std::unique_ptr<IO> {&mock_io};
+
+    std::string log_level;
+    switch (config.log_level) {
+    case LogLevel::Error:
+        log_level = "error";
+        break;
+    case LogLevel::Warning:
+        log_level = "warning";
+        break;
+    case LogLevel::Info:
+        log_level = "info";
+        break;
+    case LogLevel::Debug:
+        log_level = "debug";
+        break;
+    case LogLevel::None:
+        log_level = "none";
+        break;
+    }
+
+    std::string mode = "tcp";
+    if (config.mode == RequestHandlerType::kFilesystem) {
+        mode = "filesystem";
+    }
+
+    if (config.asapo_endpoint == "wrongmode") {
+        mode = "bla";
+    }
+
+    auto config_string = std::string("{\"BeamtimeID\":") + "\"" + config.beamtime_id + "\"";
+    config_string += "," + std::string("\"Mode\":") + "\"" + mode + "\"";
+    config_string += "," + std::string("\"NThreads\":") + std::to_string(config.nthreads);
+    config_string += "," + std::string("\"LogLevel\":") + "\"" + log_level + "\"";
+    config_string += "," + std::string("\"Tag\":") + "\"" + config.tag + "\"";
+    config_string += "," + std::string("\"AsapoEndpoint\":") + "\"" + config.asapo_endpoint + "\"";
+
+    config_string += "}";
+
+
+    EXPECT_CALL(mock_io, ReadFileToString_t("fname", _)).WillOnce(
+        testing::Return(config_string)
+    );
+
+    auto err = config_factory.SetConfigFromFile("fname");
+
+    config_factory.io__.release();
+
+    return err;
+}
+
+}
+
+
diff --git a/producer/folder_monitor_producer/unittests/mock_foldermon_config.h b/producer/folder_monitor_producer/unittests/mock_foldermon_config.h
new file mode 100644
index 0000000000000000000000000000000000000000..bf3c2374a0d58306bbe2dbe02db466ea8f8e1bc0
--- /dev/null
+++ b/producer/folder_monitor_producer/unittests/mock_foldermon_config.h
@@ -0,0 +1,14 @@
+#ifndef ASAPO_MOCK_RECEIVER_CONFIG_H
+#define ASAPO_MOCK_RECEIVER_CONFIG_H
+
+#include "../src/foldermon_config.h"
+
+
+namespace asapo {
+
+Error SetFolderMonConfig (const FolderMonConfig& config);
+
+}
+
+
+#endif
diff --git a/producer/folder_monitor_producer/unittests/test_event_detector_factory.cpp b/producer/folder_monitor_producer/unittests/test_event_detector_factory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c7b0ef8ed3ec0dd98f14b6d9d70868517989bb68
--- /dev/null
+++ b/producer/folder_monitor_producer/unittests/test_event_detector_factory.cpp
@@ -0,0 +1,52 @@
+#include <gtest/gtest.h>
+#include <gmock/gmock.h>
+
+#include "foldermon_mocking.h"
+#include "mock_foldermon_config.h"
+
+using ::testing::Test;
+using ::testing::_;
+using ::testing::Eq;
+using ::testing::Ne;
+
+using ::asapo::Error;
+
+
+//using asapo::EventDetectorFactory;
+using asapo::FolderMonConfig;
+
+namespace {
+
+
+class FactoryTests : public Test {
+ public:
+  //EventDetectorFactory factory;
+  Error err{nullptr};
+  FolderMonConfig config;
+  std::string asapo_endpoint{"endpoint"};
+  void SetUp() override {
+      config.asapo_endpoint = asapo_endpoint;
+      asapo::SetFolderMonConfig(config);
+  }
+  void TearDown() override {
+  }
+};
+
+TEST_F(FactoryTests, ErrorOnWrongCode) {
+//    ASSERT_THAT(err, Ne(nullptr));
+}
+
+
+
+TEST_F(FactoryTests, DoNotAddDiskWriterIfNotWanted) {
+//    config.write_to_disk = false;
+//    SetReceiverConfig(config);
+
+//      ASSERT_THAT(err, Eq(nullptr));
+//    ASSERT_THAT(request->GetListHandlers().size(), Eq(2));
+//    ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerAuthorize*>(request->GetListHandlers()[0]), Ne(nullptr));
+//    ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerDbWrite*>(request->GetListHandlers().back()), Ne(nullptr));
+}
+
+
+}
diff --git a/producer/folder_monitor_producer/unittests/test_foldermon_config.cpp b/producer/folder_monitor_producer/unittests/test_foldermon_config.cpp
index cad0aebb653d23ddcb9830c58a35e98f5528e2ed..f6b5cd761945f7ceba73ae42d7f3685c5fee06fc 100644
--- a/producer/folder_monitor_producer/unittests/test_foldermon_config.cpp
+++ b/producer/folder_monitor_producer/unittests/test_foldermon_config.cpp
@@ -2,6 +2,10 @@
 #include <gmock/gmock.h>
 #include <unittests/MockIO.h>
 
+#include "../src/foldermon_config.h"
+#include "../src/foldermon_config_factory.h"
+#include "mock_foldermon_config.h"
+
 using ::testing::Test;
 using ::testing::Return;
 using ::testing::_;
@@ -22,21 +26,70 @@ using ::asapo::FileDescriptor;
 using ::asapo::SocketDescriptor;
 using ::asapo::MockIO;
 
+using ::asapo::FolderMonConfigFactory;
+using asapo::FolderMonConfig;
+
 namespace {
 
 
 class ConfigTests : public Test {
   public:
     MockIO mock_io;
+    FolderMonConfigFactory config_factory;
     void SetUp() override {
+        config_factory.io__ = std::unique_ptr<asapo::IO> {&mock_io};
     }
     void TearDown() override {
+        config_factory.io__.release();
     }
 
 };
 
 
-TEST_F(ConfigTests, ReadSettings) {
+TEST_F(ConfigTests, ReadSettingsOK) {
+    asapo::FolderMonConfig test_config;
+    test_config.nthreads = 10;
+    test_config.tag = "folderMon1";
+    test_config.log_level = asapo::LogLevel::Error;
+    test_config.beamtime_id = "test";
+    test_config.asapo_endpoint = "uri:001";
+    test_config.mode = asapo::RequestHandlerType::kTcp;
+
+    auto err = asapo::SetFolderMonConfig(test_config);
+
+    auto config = asapo::GetFolderMonConfig();
+
+    ASSERT_THAT(err, Eq(nullptr));
+    ASSERT_THAT(config->log_level, Eq(asapo::LogLevel::Error));
+    ASSERT_THAT(config->tag, Eq("folderMon1"));
+    ASSERT_THAT(config->nthreads, Eq(10));
+    ASSERT_THAT(config->beamtime_id, Eq("test"));
+    ASSERT_THAT(config->asapo_endpoint, Eq("uri:001"));
+    ASSERT_THAT(config->mode, Eq(asapo::RequestHandlerType::kTcp));
 }
 
+TEST_F(ConfigTests, ReadSettingsChecksNthreads) {
+    asapo::FolderMonConfig test_config;
+    test_config.nthreads = 0;
+
+    auto err = asapo::SetFolderMonConfig(test_config);
+    ASSERT_THAT(err, Ne(nullptr));
+
+    test_config.nthreads = asapo::kMaxProcessingThreads + 1;
+
+    err = asapo::SetFolderMonConfig(test_config);
+    ASSERT_THAT(err, Ne(nullptr));
+
+}
+
+
+TEST_F(ConfigTests, ReadSettingsChecksMode) {
+    asapo::FolderMonConfig test_config;
+    test_config.nthreads = 1;
+    test_config.asapo_endpoint = "wrongmode"; // we use it to set mode string to some wrong value
+    auto err = asapo::SetFolderMonConfig(test_config);
+    ASSERT_THAT(err, Ne(nullptr));
+}
+
+
 }
diff --git a/receiver/CMakeLists.txt b/receiver/CMakeLists.txt
index 3390a85d7cab61dfcd39cd450408f9aae2d38e19..e13af4c7e7bc1b6d535e2a4506e99a9b1a736a8d 100644
--- a/receiver/CMakeLists.txt
+++ b/receiver/CMakeLists.txt
@@ -7,7 +7,7 @@ set(SOURCE_FILES
         src/statistics.cpp
         src/statistics_sender_influx_db.cpp
         src/receiver_config.cpp
-        src/producer_logger.cpp
+        src/receiver_logger.cpp
         src/request_handler_db_write.cpp
         src/request_handler_authorize.cpp
         src/statistics_sender_fluentd.cpp
diff --git a/receiver/src/producer_logger.cpp b/receiver/src/receiver_logger.cpp
similarity index 100%
rename from receiver/src/producer_logger.cpp
rename to receiver/src/receiver_logger.cpp