#include "common/pkgmgr_interface.h"
#include "common/pkgmgr_signal.h"
#include "common/step/configuration/step_fail.h"
+#include "common/utils/file_logbackend.h"
namespace {
unsigned total_steps = steps_.size();
unsigned current_step = 1;
- ::utils::LogCore::GetCore().SetFileName(kLogFileName);
- ::utils::LogCore::GetCore().SetRotationSize(kLogRotationSize);
- ::utils::LogCore::GetCore().SetMaximumRotation(kLogMaximumRotation);
+ std::shared_ptr<utils::FileLogBackend> failure_logger =
+ std::shared_ptr<utils::FileLogBackend>(new utils::FileLogBackend(
+ kLogFileName, kLogRotationSize, kLogMaximumRotation));
+ ::utils::LogCore::GetCore().AddLogBackend(failure_logger);
for (; it != itEnd; ++it, ++current_step) {
status = SafeExecute(*it, &Step::precheck, "precheck");
ret = Result::UNDO_ERROR;
}
} while (it-- != itStart);
- ::utils::LogCore::GetCore().WriteLog();
+ failure_logger->WriteLogToFile();
} else {
do {
if (it == itEnd)
--- /dev/null
+// Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/utils/file_logbackend.h"
+
+#include <manifest_parser/utils/logging.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <fstream>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <utility>
+
+namespace utils {
+
+FileLogBackend::FileLogBackend(std::string file_name, int rotation_size,
+ int max_rotation)
+ : file_name_(std::move(file_name)), rotation_size_(rotation_size),
+ max_rotation_(max_rotation), log_stream_(
+ std::unique_ptr<std::ostringstream>(new std::ostringstream())) {
+}
+
+
+void FileLogBackend::WriteLog(LogLevel level, const std::string& /* tag */,
+ const std::string& logstr) {
+ if (level != LogLevel::LOG_DEBUG)
+ *log_stream_ << GetTimeStamp() << GetPid() << logstr << std::endl;
+}
+
+void FileLogBackend::WriteLogToFile() {
+ if (file_name_.empty())
+ return;
+
+ int size = GetFileSize(file_name_);
+ if (size > rotation_size_)
+ Rotate();
+
+ std::ofstream ofs(file_name_.c_str(), std::ios::app);
+ ofs << log_stream_->str();
+ ofs.close();
+
+ // clean the log stream
+ log_stream_->str("");
+ log_stream_->clear();
+}
+
+void FileLogBackend::Rotate() {
+ for (int i = max_rotation_; i > 0; i--) {
+ std::string old_log = file_name_ + "." + std::to_string(i);
+ // the oldest log will be removed
+ if (i == max_rotation_) {
+ std::remove(old_log.c_str());
+ } else {
+ std::string new_log = file_name_ + "." + std::to_string(i + 1);
+ std::rename(old_log.c_str(), new_log.c_str());
+ }
+ }
+ std::string new_log = file_name_ + ".1";
+ std::rename(file_name_.c_str(), new_log.c_str());
+}
+
+int FileLogBackend::GetFileSize(const std::string& file_name) {
+ struct stat sb;
+ int ret = stat(file_name.c_str(), &sb);
+ return ret == 0 ? sb.st_size : -1;
+}
+
+std::string FileLogBackend::GetTimeStamp() {
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+
+ time_t seconds = ts.tv_sec;
+ struct tm gmt;
+ if (!gmtime_r(&seconds, &gmt))
+ return "[]";
+ int32_t miliseconds = ts.tv_nsec / 1000000;
+
+ char buf[32];
+ strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &gmt);
+ char timestamp[32];
+ snprintf(timestamp, sizeof(timestamp), "[%s.%03d UTC]", buf, miliseconds);
+
+ return timestamp;
+}
+
+std::string FileLogBackend::GetPid() {
+ return "[" + std::to_string(getpid()) + "]";
+}
+
+} // namespace utils
--- /dev/null
+// Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_UTILS_FILE_LOGBACKEND_H_
+#define COMMON_UTILS_FILE_LOGBACKEND_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include <memory>
+#include <sstream>
+#include <string>
+
+namespace utils {
+
+class FileLogBackend : public ILogBackend {
+ public:
+ FileLogBackend(std::string file_name, int rotation_size, int max_rotation);
+ void WriteLog(LogLevel level, const std::string& tag,
+ const std::string& logstr) override;
+ void WriteLogToFile();
+
+ private:
+ void Rotate();
+ int GetFileSize(const std::string& file_name);
+ std::string GetTimeStamp();
+ std::string GetPid();
+
+ std::string file_name_;
+ int rotation_size_;
+ int max_rotation_;
+ std::unique_ptr<std::ostringstream> log_stream_;
+};
+
+} // namespace utils
+
+#endif // COMMON_UTILS_FILE_LOGBACKEND_H_