1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "hhlog.h"
17
18 static constexpr int FILE_MODE = 0644;
19
~HHLogger()20 HHLogger::~HHLogger()
21 {
22 stop_.store(true);
23 if (logSaver_.joinable()) {
24 logSaver_.join();
25 }
26 if (fd_ >= 0) {
27 close(fd_);
28 }
29 }
30
InitLogger(const int logLevel,const std::string & logFile)31 int HHLogger::InitLogger(const int logLevel, const std::string& logFile)
32 {
33 // Init logLevel, stop_, timer_ and buf_
34 logLevel_ = logLevel;
35 if (UpdateTimer() != 0) {
36 return -1;
37 }
38 constexpr enum RingBuffer::MemAlignShift memAlign {RingBuffer::MemAlignShift::W_ALIGN_SHIFT};
39 buf_.reset(new RingBuffer {SizeConsts::RING_BUF_SIZE, memAlign});
40 if (buf_ == nullptr or (not (*buf_))) {
41 return -1;
42 }
43
44 // open and link log file
45 if (logFile.compare("stdout") == 0) {
46 // use stdout as log file
47 if (fcntl(STDOUT_FILENO, F_GETFL) != 0) {
48 // stdout closed, reopen it
49 fd_ = open("/dev/stdout", O_WRONLY);
50 } else {
51 fd_ = STDOUT_FILENO;
52 }
53 if (fd_ < 0) {
54 return -1;
55 }
56 return 0;
57 }
58 auto fileName = GetLogFileName();
59 if (fileName.length() == 0) {
60 return -1;
61 }
62 fd_ = open(fileName.c_str(), O_WRONLY | O_CREAT, FILE_MODE);
63 if (fd_ < 0) {
64 return -1;
65 }
66 unlink(logFile.c_str());
67 if (link(fileName.c_str(), logFile.c_str()) != 0) {
68 return -1;
69 }
70
71 return 0;
72 }
73
Start(const int logLevel,const std::string & logFile)74 int HHLogger::Start(const int logLevel, const std::string& logFile)
75 {
76 if (logLevel == HHLOG_NONE) {
77 HHLOGD(true, "hhlog level is NONE!");
78 return 0;
79 }
80 #if defined(HH_LOGGER_DEBUG) || defined(HH_LOGGER_INFO) || defined(HH_LOGGER_WARN) || \
81 defined(HH_LOGGER_ERROR) || defined(HH_LOGGER_FATAL)
82 if (InitLogger(logLevel, logFile) != 0) {
83 return -1;
84 }
85 #endif
86 return 0;
87 }
88
GetLogFileName() const89 std::string HHLogger::GetLogFileName() const
90 {
91 auto timer = timer_.load();
92 time_t now = (time_t) timer.tv_sec;
93 struct tm* tmPtr {nullptr};
94 tmPtr = localtime(&now);
95 if (tmPtr == nullptr) {
96 return "";
97 }
98 std::stringstream ss;
99 constexpr int yearStart {1900};
100 constexpr int monthStart {1};
101 ss << "/data/local/tmp/";
102 ss << std::to_string(tmPtr->tm_year + yearStart) << ".";
103 ss << std::to_string(tmPtr->tm_mon + monthStart) << ".";
104 ss << std::to_string(tmPtr->tm_mday) << "_";
105 ss << std::to_string(tmPtr->tm_hour) << ".";
106 ss << std::to_string(tmPtr->tm_min) << ".";
107 ss << std::to_string(tmPtr->tm_sec) << ".hhlog";
108 return ss.str();
109 }
110
GetFormatTime() const111 std::string HHLogger::GetFormatTime() const
112 {
113 auto timer = timer_.load();
114 time_t now = (time_t) timer.tv_sec;
115 struct tm* tmPtr {nullptr};
116 tmPtr = localtime(&now);
117 if (tmPtr == nullptr) {
118 return "";
119 }
120 std::stringstream ss;
121 constexpr int yearStart {1900};
122 constexpr int monthStart {1};
123 ss << std::to_string(tmPtr->tm_year + yearStart) << "-";
124 ss << std::to_string(tmPtr->tm_mon + monthStart) << "-";
125 ss << std::to_string(tmPtr->tm_mday) << " ";
126 ss << std::to_string(tmPtr->tm_hour) << ":";
127 ss << std::to_string(tmPtr->tm_min) << ":";
128 ss << std::to_string(tmPtr->tm_sec);
129 return ss.str();
130 }
131
UpdateTimer()132 int HHLogger::UpdateTimer()
133 {
134 struct timeval timer;
135 int ret = gettimeofday(&timer, nullptr);
136 if (ret != 0) {
137 return -1;
138 }
139 timer_.store(timer);
140 return 0;
141 }
142
SaveLog()143 int HHLogger::SaveLog()
144 {
145 while (true) {
146 if (UpdateTimer() != 0) {
147 return -1;
148 }
149 auto dataSize = buf_->GetDataSize();
150 if (stop_.load() and (dataSize == 0)) {
151 return 0;
152 }
153 if (dataSize) {
154 ssize_t ret = buf_->Write(fd_, dataSize);
155 if (ret <= 0) {
156 stop_.store(true);
157 return -1;
158 }
159 }
160 }
161 return 0;
162 }