Apollo  6.0
Open source self driving car software
async_logger.h
Go to the documentation of this file.
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 
17 #ifndef CYBER_LOGGER_ASYNC_LOGGER_H_
18 #define CYBER_LOGGER_ASYNC_LOGGER_H_
19 
20 #include <atomic>
21 #include <condition_variable>
22 #include <cstdint>
23 #include <ctime>
24 #include <deque>
25 #include <iostream>
26 #include <memory>
27 #include <mutex>
28 #include <string>
29 #include <thread>
30 #include <unordered_map>
31 #include <utility>
32 #include <vector>
33 
34 #include "glog/logging.h"
35 
36 #include "cyber/common/macros.h"
38 
39 namespace apollo {
40 namespace cyber {
41 namespace logger {
42 
73 class AsyncLogger : public google::base::Logger {
74  public:
75  explicit AsyncLogger(google::base::Logger* wrapped);
76 
77  ~AsyncLogger();
78 
82  void Start();
83 
90  void Stop();
91 
104  void Write(bool force_flush, time_t timestamp, const char* message,
105  int message_len) override;
106 
110  void Flush() override;
111 
119  uint32_t LogSize() override;
120 
126  std::thread* LogThread() { return &log_thread_; }
127 
128  private:
129  // A buffered message.
130  //
131  // TODO(todd): using std::string for buffered messages is convenient but not
132  // as efficient as it could be. It's better to make the buffers just be
133  // Arenas and allocate both the message data and Msg struct from them, forming
134  // a linked list.
135  struct Msg {
136  time_t ts;
137  std::string message;
138  int32_t level;
139  Msg() : ts(0), message(), level(google::INFO) {}
140  Msg(time_t ts, std::string&& message, int32_t level)
141  : ts(ts), message(std::move(message)), level(level) {}
142  Msg(const Msg& rsh) {
143  ts = rsh.ts;
144  message = rsh.message;
145  level = rsh.level;
146  }
147  Msg(Msg&& rsh) {
148  ts = rsh.ts;
149  message = rsh.message;
150  level = rsh.level;
151  }
152  Msg& operator=(Msg&& rsh) {
153  ts = rsh.ts;
154  message = std::move(rsh.message);
155  level = rsh.level;
156  return *this;
157  }
158  Msg& operator=(const Msg& rsh) {
159  ts = rsh.ts;
160  message = rsh.message;
161  level = rsh.level;
162  return *this;
163  }
164  };
165 
166  void RunThread();
167  void FlushBuffer(const std::unique_ptr<std::deque<Msg>>& msg);
168 
169  google::base::Logger* const wrapped_;
170  std::thread log_thread_;
171 
172  // Count of how many times the writer thread has flushed the buffers.
173  // 64 bits should be enough to never worry about overflow.
174  std::atomic<uint64_t> flush_count_ = {0};
175 
176  // Count of how many times the writer thread has dropped the log messages.
177  // 64 bits should be enough to never worry about overflow.
178  uint64_t drop_count_ = 0;
179 
180  // The buffer to which application threads append new log messages.
181  std::unique_ptr<std::deque<Msg>> active_buf_;
182 
183  // The buffer currently being flushed by the logger thread, cleared
184  // after a successful flush.
185  std::unique_ptr<std::deque<Msg>> flushing_buf_;
186 
187  // Trigger for the logger thread to stop.
188  enum State { INITTED, RUNNING, STOPPED };
189  std::atomic<State> state_ = {INITTED};
190  std::atomic_flag flag_ = ATOMIC_FLAG_INIT;
191  std::unordered_map<std::string, std::unique_ptr<LogFileObject>>
192  module_logger_map_;
193 
195 };
196 
197 } // namespace logger
198 } // namespace cyber
199 } // namespace apollo
200 
201 #endif // CYBER_LOGGER_ASYNC_LOGGER_H_
Wrapper for a glog Logger which asynchronously writes log messages. This class starts a new thread re...
Definition: async_logger.h:73
uint32_t LogSize() override
Get the current LOG file size. The return value is an approximate value since some logged data may no...
std::thread * LogThread()
get the log thead
Definition: async_logger.h:126
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
#define DISALLOW_COPY_AND_ASSIGN(classname)
Definition: macros.h:48
void Start()
start the async logger
void Stop()
Stop the thread. Flush() and Write() must not be called after this. NOTE: this is currently only used...
void Flush() override
Flush any buffered messages.
AsyncLogger(google::base::Logger *wrapped)
void Write(bool force_flush, time_t timestamp, const char *message, int message_len) override
Write a message to the log. Start() must have been called.