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());
100 if (::localtime_r(&now, &tm) == nullptr)
101 std::cerr << "Failed to get local time" << std::endl;
103 std::string log("[" + std::to_string(tm.tm_hour)
105 + std::to_string(tm.tm_min)
107 + std::to_string(tm.tm_sec) + "] ");
111 size_t written = 0, size = log.size();
112 const char *data = log.c_str();
114 while (written < size) {
115 int bytes = ::write(fd, data + written, size-written);
118 } else if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) {
121 std::cerr << "Failed to write log" << std::endl;
128 void FileLogSink::sink(const std::string &message)
130 auto level = message.substr(0, message.find('<'));
131 auto subMsg = message.substr(message.find(':') + 1);
134 switch (audit::StringToLogLevel(level)) {
135 case audit::LogLevel::Error:
136 log.append("[ERROR] : " + subMsg);
138 case audit::LogLevel::Warning:
139 log.append("[WARN] : " + subMsg);
141 case audit::LogLevel::Debug:
142 log.append("[DEBUG] : " + subMsg);
144 case audit::LogLevel::Info:
145 log.append("[INFO] : " + subMsg);
147 case audit::LogLevel::Trace:
148 log.append("[TRACE] : " + subMsg);
151 log.append("[SILENT] : " + subMsg);