#include "common/utils/file_logbackend.h"
#include <manifest_parser/utils/logging.h>
+#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
namespace utils {
-FileLogBackend::FileLogBackend(std::string file_name, int rotation_size,
+FileLogBackend::FileLogBackend(std::string file_path, int rotation_size,
int max_rotation)
- : file_name_(std::move(file_name)), rotation_size_(rotation_size),
+ : file_path_(std::move(file_path)), rotation_size_(rotation_size),
max_rotation_(max_rotation), log_stream_(
std::unique_ptr<std::ostringstream>(new std::ostringstream())) {
}
}
void FileLogBackend::WriteLogToFile() {
- if (file_name_.empty())
+ if (file_path_.empty())
return;
- int size = GetFileSize(file_name_);
+ int size = GetFileSize(file_path_);
if (size > rotation_size_)
if (!Rotate())
return;
- std::ofstream ofs(file_name_.c_str(), std::ios::app);
+ std::ofstream ofs(file_path_.c_str(), std::ios::app);
ofs << log_stream_->str();
ofs.close();
log_stream_->str("");
log_stream_->clear();
- if (chmod(file_name_.c_str(), kDefaultMode640) != 0)
+ if (chmod(file_path_.c_str(), kDefaultMode640) != 0)
LOG(ERROR) << "Failed to set permission on log, errno : " << errno;
}
bool FileLogBackend::Rotate() {
+ std::string logdir = GetLogDir();
+ int dirfd = open(logdir.c_str(), O_DIRECTORY);
for (int i = max_rotation_; i > 0; i--) {
- std::string old_log = file_name_ + "." + std::to_string(i);
+ std::string old_log = GetFileName() + "." + std::to_string(i);
+ if (dirfd < 0) {
+ LOG(ERROR) << "Failed to open dir(" << logdir << "), errno : " << errno;
+ return false;
+ }
struct stat tmp_buffer;
- if (stat(old_log.c_str(), &tmp_buffer) != 0)
+ if (fstatat(dirfd, old_log.c_str(), &tmp_buffer, 0) != 0)
continue;
// the oldest log will be removed
if (i == max_rotation_) {
- if (std::remove(old_log.c_str()) != 0)
+ if (unlinkat(dirfd, old_log.c_str(), 0) != 0) {
+ close(dirfd);
return false;
+ }
} else {
- std::string new_log = file_name_ + "." + std::to_string(i + 1);
- if (std::rename(old_log.c_str(), new_log.c_str()) != 0)
+ std::string new_log = GetFileName() + "." + std::to_string(i + 1);
+ if (renameat(dirfd, old_log.c_str(), dirfd, new_log.c_str()) != 0) {
+ close(dirfd);
return false;
+ }
}
}
- std::string new_log = file_name_ + ".1";
- if (std::rename(file_name_.c_str(), new_log.c_str()) != 0)
+ std::string new_log = GetFileName() + ".1";
+ if (renameat(dirfd, file_path_.c_str(), dirfd, new_log.c_str()) != 0) {
+ close(dirfd);
return false;
+ }
+ close(dirfd);
return true;
}
return std::to_string(getpid()) + "|";
}
+std::string FileLogBackend::GetLogDir() {
+ return file_path_.substr(0, file_path_.find_last_of("\\/") + 1);
+}
+
+std::string FileLogBackend::GetFileName() {
+ return file_path_.substr(file_path_.find_last_of("\\/") + 1);
+}
+
} // namespace utils
class FileLogBackend : public ILogBackend {
public:
- FileLogBackend(std::string file_name, int rotation_size, int max_rotation);
+ FileLogBackend(std::string file_path, int rotation_size, int max_rotation);
void WriteLog(LogLevel level, const std::string& tag,
const std::string& logstr) override;
void WriteLogToFile();
private:
bool Rotate();
- int GetFileSize(const std::string& file_name);
+ int GetFileSize(const std::string& file_path);
std::string GetTimeStamp();
std::string GetPid();
+ std::string GetLogDir();
+ std::string GetFileName();
- std::string file_name_;
+ std::string file_path_;
int rotation_size_;
int max_rotation_;
std::unique_ptr<std::ostringstream> log_stream_;