2 * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
23 #include <sys/types.h>
28 #include "file-sink.h"
32 #define MAX_LOG_LEN 16
35 std::string getFileName(const std::string &path)
38 auto pos = path.rfind('/');
39 pos = (pos == std::string::npos) ? 0 : pos + 1;
40 name = path.substr(pos, path.size());
45 FileLogSink::FileLogSink(const std::string& name)
46 : path("/opt/var/log/"), fd(-1)
48 path.append(getFileName(name));
49 fd = ::open(path.c_str(), O_CREAT | O_RDWR | O_APPEND | O_SYNC, 0664);
52 FileLogSink::~FileLogSink()
57 void FileLogSink::resize()
59 std::lock_guard<std::recursive_mutex> lock(mtx);
62 int blkcnt = MAX_LOG_LEN;
65 if (::lstat(path.c_str(), &st) < 0) {
66 std::cerr << "Invalid log file" << std::endl;
70 blksize = st.st_blksize;
72 blkcnt = (st.st_size / blksize) + 1;
74 if (blkcnt <= MAX_LOG_LEN)
77 ret = ::fallocate(fd, FALLOC_FL_COLLAPSE_RANGE, 0, blksize*(blkcnt-MAX_LOG_LEN));
79 std::cerr << "Failed to collapse the log file : " << errno << std::endl;
82 void FileLogSink::write(const std::string &message)
84 std::lock_guard<std::recursive_mutex> lock(mtx);
87 auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
88 std::tm tm = *std::localtime(&now);
89 std::string log("[" + std::to_string(tm.tm_hour)
91 + std::to_string(tm.tm_min)
93 + std::to_string(tm.tm_sec) + "] ");
97 size_t written = 0, size = log.size();
98 const char *data = log.c_str();
100 while (written < size) {
101 int bytes = ::write(fd, data + written, size-written);
104 } else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
107 std::cerr << "Failed to write log" << std::endl;
114 void FileLogSink::sink(const std::string &message)
116 auto level = message.substr(0, message.find('<'));
117 auto subMsg = message.substr(message.find(':') + 1);
120 switch (audit::StringToLogLevel(level)) {
121 case audit::LogLevel::Error:
122 log.append("[" + this->tag + " ERROR] : " + subMsg);
124 case audit::LogLevel::Warning:
125 log.append("[" + this->tag + " WARN] : " + subMsg);
127 case audit::LogLevel::Debug:
128 log.append("[" + this->tag + " DEBUG] : " + subMsg);
130 case audit::LogLevel::Info:
131 log.append("[" + this->tag + " INFO] : " + subMsg);
133 case audit::LogLevel::Trace:
134 log.append("[" + this->tag + " TRACE] : " + subMsg);
137 log.append("[" + this->tag + " SILENT] : " + subMsg);