• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }