diff --git a/src/log_manager.cpp b/src/log_manager.cpp
new file mode 100644
index 0000000..b78b7e8
--- /dev/null
+++ b/src/log_manager.cpp
@@ -0,0 +1,254 @@
+/**
+ * @brief Log manager.
+ *
+ * This file is part of HostLogger project.
+ *
+ * Copyright (c) 2018 YADRO
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "config.hpp"
+#include "log_manager.hpp"
+
+#include <set>
+#include <vector>
+#include <cstring>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+// Path to the Unix Domain socket file used to read host's logs
+#define HOSTLOG_SOCKET_PATH     "\0obmc-console"
+// Number of connection attempts
+#define HOSTLOG_SOCKET_ATTEMPTS 60
+// Pause between connection attempts in seconds
+#define HOSTLOG_SOCKET_PAUSE    1
+// Max buffer size to read from socket
+#define MAX_SOCKET_BUFFER_SIZE  512
+
+
+LogManager::LogManager()
+: fd_(-1)
+{
+}
+
+
+LogManager::~LogManager()
+{
+    closeHostLog();
+}
+
+
+int LogManager::openHostLog()
+{
+    int rc;
+
+    do {
+        // Create socket
+        fd_ = socket(AF_UNIX, SOCK_STREAM, 0);
+        if (fd_ == -1) {
+            rc = errno;
+            fprintf(stderr, "Unable to create socket: error [%i] %s\n", rc, strerror(rc));
+            break;
+        }
+
+        // Set non-blocking mode for socket
+        int opt = 1;
+        rc = ioctl(fd_, FIONBIO, &opt);
+        if (rc != 0) {
+            rc = errno;
+            fprintf(stderr, "Unable to set non-blocking mode for log socket: error [%i] %s\n", rc, strerror(rc));
+            break;
+        }
+
+        sockaddr_un sa = { 0 };
+        sa.sun_family = AF_UNIX;
+        constexpr int min_path = sizeof(HOSTLOG_SOCKET_PATH) < sizeof(sa.sun_path) ?
+                                 sizeof(HOSTLOG_SOCKET_PATH) : sizeof(sa.sun_path);
+        memcpy(&sa.sun_path, HOSTLOG_SOCKET_PATH, min_path);
+
+        // Connect to host's log stream via socket.
+        // The owner of the socket (server) is obmc-console service and
+        // we have a dependency on it written in the systemd unit file, but
+        // we can't guarantee that the socket is initialized at the moment.
+        rc = -1;
+        for (int attempt = 0; rc != 0 && attempt < HOSTLOG_SOCKET_ATTEMPTS; ++attempt) {
+            rc = connect(fd_, reinterpret_cast<const sockaddr*>(&sa), sizeof(sa));
+            sleep(HOSTLOG_SOCKET_PAUSE);
+        }
+        if (rc < 0) {
+            rc = errno;
+            fprintf(stderr, "Unable to connect to host log socket: error [%i] %s\n", rc, strerror(rc));
+        }
+    }
+    while (false);
+
+    if (rc != 0)
+        closeHostLog();
+
+    return rc;
+}
+
+
+void LogManager::closeHostLog()
+{
+    if (fd_ != -1) {
+        ::close(fd_);
+        fd_ = -1;
+    }
+}
+
+
+int LogManager::getHostLogFd() const
+{
+    return fd_;
+}
+
+
+int LogManager::handleHostLog()
+{
+    int rc = 0;
+    std::vector<char> buff(MAX_SOCKET_BUFFER_SIZE);
+    size_t readLen = MAX_SOCKET_BUFFER_SIZE;
+
+    // Read all existing data from log stream
+    while (rc == 0 && readLen != 0) {
+        rc = readHostLog(&buff[0], buff.size(), readLen);
+        if (rc == 0 && readLen != 0)
+            storage_.parse(&buff[0], readLen);
+    }
+
+    return rc;
+}
+
+
+int LogManager::flush()
+{
+    int rc;
+
+    if (storage_.empty())
+        return 0; // Nothing to save
+
+    const std::string logFile = prepareLogPath();
+    if (logFile.empty())
+        return EIO;
+
+    rc = storage_.write(logFile.c_str());
+    if (rc != 0)
+        return rc;
+
+    storage_.clear();
+
+    // Non critical tasks, don't check returned status
+    rotateLogFiles();
+
+    return 0;
+}
+
+
+int LogManager::readHostLog(char* buffer, size_t bufferLen, size_t& readLen) const
+{
+    int rc = 0;
+
+    const ssize_t rsz = ::read(fd_, buffer, bufferLen);
+    if (rsz >= 0)
+        readLen = static_cast<size_t>(rsz);
+    else {
+        readLen = 0;
+        if (errno != EAGAIN && errno != EWOULDBLOCK) {
+            rc = errno;
+            fprintf(stderr, "Unable to read host log: error [%i] %s\n", rc, strerror(rc));
+        }
+    }
+
+    return rc;
+}
+
+
+std::string LogManager::prepareLogPath() const
+{
+    // Create path for logs
+    if (::access(loggerConfig.path, F_OK) != 0) {
+        const std::string logPath(loggerConfig.path);
+        const size_t len = logPath.length();
+        size_t pos = 0;
+        while (pos < len - 1) {
+            pos = logPath.find('/', pos + 1);
+            const std::string createPath = logPath.substr(0, pos);
+            if (::mkdir(createPath.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0 && errno != EEXIST) {
+                const int rc = errno;
+                fprintf(stderr, "Unable to create dir %s: error [%i] %s\n", createPath.c_str(), rc, strerror(rc));
+                return std::string();
+            }
+        }
+    }
+
+    // Construct log file name
+    time_t ts;
+    time(&ts);
+    tm lt = { 0 };
+    localtime_r(&ts, &lt);
+    char fileName[64];
+    snprintf(fileName, sizeof(fileName), "/host_%i%02i%02i_%02i%02i%02i.log.gz",
+            lt.tm_year + 1900, lt.tm_mon + 1, lt.tm_mday,
+            lt.tm_hour, lt.tm_min, lt.tm_sec);
+
+    return std::string(loggerConfig.path) + fileName;
+}
+
+
+int LogManager::rotateLogFiles() const
+{
+    if (loggerConfig.rotationLimit == 0)
+        return 0; // Not applicable
+
+    int rc = 0;
+
+    // Get file list to std::set
+    std::set<std::string> logFiles;
+    DIR* dh = opendir(loggerConfig.path);
+    if (!dh) {
+        rc = errno;
+        fprintf(stderr, "Unable to open directory %s: error [%i] %s\n", loggerConfig.path, rc, strerror(rc));
+        return rc;
+    }
+    dirent *dir;
+    while ((dir = readdir(dh))) {
+        if (dir->d_type != DT_DIR)
+            logFiles.insert(dir->d_name);
+    }
+    closedir(dh);
+
+    // Log file has a name with a timestamp generated by prepareLogPath().
+    // The sorted array of names (std::set) will contain the oldest file on the
+    // top.
+    // Remove oldest files.
+    int filesToRemove = static_cast<int>(logFiles.size()) - loggerConfig.rotationLimit;
+    while (rc == 0 && --filesToRemove >= 0) {
+        std::string fileToRemove = loggerConfig.path;
+        fileToRemove += '/';
+        fileToRemove += *logFiles.begin();
+        if (::unlink(fileToRemove.c_str()) == -1) {
+            rc = errno;
+            fprintf(stderr, "Unable to delete file %s: error [%i] %s\n", fileToRemove.c_str(), rc, strerror(rc));
+        }
+        logFiles.erase(fileToRemove);
+    }
+
+    return rc;
+}
