Apollo 10.0
自动驾驶开放平台
async_logger.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 The Apollo Authors. All Rights Reserved.
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 *****************************************************************************/
16
18
19#include <cstdlib>
20#include <string>
21#include <thread>
22#include <unordered_map>
23
24#include "cyber/base/macros.h"
26
27namespace apollo {
28namespace cyber {
29namespace logger {
30
31static const std::unordered_map<char, int> log_level_map = {
32 {'F', 3}, {'E', 2}, {'W', 1}, {'I', 0}};
33
34AsyncLogger::AsyncLogger(google::base::Logger* wrapped) : wrapped_(wrapped) {
35 active_buf_.reset(new std::deque<Msg>());
36 flushing_buf_.reset(new std::deque<Msg>());
37}
38
40
42 CHECK_EQ(state_.load(std::memory_order_acquire), INITTED);
43 state_.store(RUNNING, std::memory_order_release);
44 log_thread_ = std::thread(&AsyncLogger::RunThread, this);
45 // std::cout << "Async Logger Start!" << std::endl;
46}
47
49 state_.store(STOPPED, std::memory_order_release);
50 if (log_thread_.joinable()) {
51 log_thread_.join();
52 }
53
54 FlushBuffer(active_buf_);
55 ACHECK(active_buf_->empty());
56 ACHECK(flushing_buf_->empty());
57 // std::cout << "Async Logger Stop!" << std::endl;
58}
59
60void AsyncLogger::Write(bool force_flush, time_t timestamp, const char* message,
61 int message_len) {
62 if (cyber_unlikely(state_.load(std::memory_order_acquire) != RUNNING)) {
63 // std::cout << "Async Logger not running!" << std::endl;
64 return;
65 }
66 if (message_len > 0) {
67 auto msg_str = std::string(message, message_len);
68 while (flag_.test_and_set(std::memory_order_acquire)) {
69 cpu_relax();
70 }
71 active_buf_->emplace_back(timestamp, std::move(msg_str),
72 log_level_map.at(message[0]));
73 flag_.clear(std::memory_order_release);
74 }
75
76 if (force_flush && timestamp == 0 && message && message_len == 0) {
77 Stop();
78 }
79}
80
82 for (auto& module_logger : module_logger_map_) {
83 module_logger.second->Flush();
84 }
85}
86
87uint32_t AsyncLogger::LogSize() { return wrapped_->LogSize(); }
88
89void AsyncLogger::RunThread() {
90 while (state_ == RUNNING) {
91 while (flag_.test_and_set(std::memory_order_acquire)) {
92 cpu_relax();
93 }
94 active_buf_.swap(flushing_buf_);
95 flag_.clear(std::memory_order_release);
96 FlushBuffer(flushing_buf_);
97 if (active_buf_->size() < 800) {
98 std::this_thread::sleep_for(std::chrono::milliseconds(1));
99 }
100 }
101}
102
103void AsyncLogger::FlushBuffer(const std::unique_ptr<std::deque<Msg>>& buffer) {
104 std::string module_name = "";
105 while (!buffer->empty()) {
106 auto& msg = buffer->front();
107 FindModuleName(&(msg.message), &module_name);
108
109 if (module_logger_map_.find(module_name) == module_logger_map_.end()) {
110 std::string file_name = module_name + ".log.INFO.";
111 if (!FLAGS_log_dir.empty()) {
112 file_name = FLAGS_log_dir + "/" + file_name;
113 }
114 module_logger_map_[module_name].reset(
115 new LogFileObject(google::INFO, file_name.c_str()));
116 module_logger_map_[module_name]->SetSymlinkBasename(module_name.c_str());
117 }
118 const bool force_flush = msg.level > 0;
119 module_logger_map_.find(module_name)
120 ->second->Write(force_flush, msg.ts, msg.message.data(),
121 static_cast<int>(msg.message.size()));
122 buffer->pop_front();
123 }
124 Flush();
125}
126
127} // namespace logger
128} // namespace cyber
129} // namespace apollo
void Start()
start the async logger
void Flush() override
Flush any buffered messages.
void Write(bool force_flush, time_t timestamp, const char *message, int message_len) override
Write a message to the log.
AsyncLogger(google::base::Logger *wrapped)
uint32_t LogSize() override
Get the current LOG file size.
void cpu_relax()
Definition macros.h:53
#define cyber_unlikely(x)
Definition macros.h:30
#define ACHECK(cond)
Definition log.h:80
void FindModuleName(std::string *log_message, std::string *module_name)
Definition logger_util.h:66
class register implement
Definition arena_queue.h:37