Apollo 10.0
自动驾驶开放平台
apollo::cyber::logger::LogFileObject类 参考

#include <log_file_object.h>

类 apollo::cyber::logger::LogFileObject 继承关系图:
apollo::cyber::logger::LogFileObject 的协作图:

Public 成员函数

 LogFileObject (LogSeverity severity, const char *base_filename)
 
 ~LogFileObject ()
 
void Write (bool force_flush, time_t timestamp, const char *message, int message_len) override
 
void SetBasename (const char *basename)
 
void SetExtension (const char *ext)
 
void SetSymlinkBasename (const char *symlink_basename)
 
void Flush () override
 
uint32 LogSize () override
 
void FlushUnlocked ()
 
const string & hostname ()
 

详细描述

在文件 log_file_object.h44 行定义.

构造及析构函数说明

◆ LogFileObject()

apollo::cyber::logger::LogFileObject::LogFileObject ( LogSeverity  severity,
const char *  base_filename 
)

在文件 log_file_object.cc72 行定义.

73 : base_filename_selected_(base_filename != nullptr),
74 base_filename_((base_filename != nullptr) ? base_filename : ""),
75 symlink_basename_("UNKNOWN"),
76 filename_extension_(),
77 file_(NULL),
78 severity_(severity),
79 bytes_since_flush_(0),
80 file_length_(0),
81 rollover_attempt_(kRolloverAttemptFrequency - 1),
82 next_flush_time_(0) {
83 if (base_filename_.empty()) {
84 base_filename_ = "UNKNOWN";
85 }
86 assert(severity >= 0);
87 assert(severity < NUM_SEVERITIES);
88}

◆ ~LogFileObject()

apollo::cyber::logger::LogFileObject::~LogFileObject ( )

在文件 log_file_object.cc90 行定义.

90 {
91 std::lock_guard<std::mutex> lock(lock_);
92 if (file_ != nullptr) {
93 fclose(file_);
94 file_ = nullptr;
95 }
96}

成员函数说明

◆ Flush()

void apollo::cyber::logger::LogFileObject::Flush ( )
override

在文件 log_file_object.cc130 行定义.

130 {
131 std::lock_guard<std::mutex> lock(lock_);
133}

◆ FlushUnlocked()

void apollo::cyber::logger::LogFileObject::FlushUnlocked ( )

在文件 log_file_object.cc135 行定义.

135 {
136 if (file_ != nullptr) {
137 fflush(file_);
138 bytes_since_flush_ = 0;
139 }
140 // Figure out when we are due for another flush.
141 const int64 next =
142 (FLAGS_logbufsecs * static_cast<int64>(1000000)); // in usec
143 next_flush_time_ = CycleClock_Now() + UsecToCycles(next);
144}
int64_t UsecToCycles(int64_t usec)
Definition logger_util.h:47

◆ hostname()

const string & apollo::cyber::logger::LogFileObject::hostname ( )

在文件 log_file_object.cc309 行定义.

309 {
310 if (hostname_.empty()) {
311 GetHostName(&hostname_);
312 if (hostname_.empty()) {
313 hostname_ = "(unknown)";
314 }
315 }
316 return hostname_;
317}

◆ LogSize()

uint32 apollo::cyber::logger::LogFileObject::LogSize ( )
inlineoverride

在文件 log_file_object.h63 行定义.

63 {
64 std::lock_guard<std::mutex> lock(lock_);
65 return file_length_;
66 }

◆ SetBasename()

void apollo::cyber::logger::LogFileObject::SetBasename ( const char *  basename)

在文件 log_file_object.cc98 行定义.

98 {
99 std::lock_guard<std::mutex> lock(lock_);
100 base_filename_selected_ = true;
101 if (base_filename_ != basename) {
102 // Get rid of old log file since we are changing names
103 if (file_ != nullptr) {
104 fclose(file_);
105 file_ = nullptr;
106 rollover_attempt_ = kRolloverAttemptFrequency - 1;
107 }
108 base_filename_ = basename;
109 }
110}

◆ SetExtension()

void apollo::cyber::logger::LogFileObject::SetExtension ( const char *  ext)

在文件 log_file_object.cc112 行定义.

112 {
113 std::lock_guard<std::mutex> lock(lock_);
114 if (filename_extension_ != ext) {
115 // Get rid of old log file since we are changing names
116 if (file_ != nullptr) {
117 fclose(file_);
118 file_ = nullptr;
119 rollover_attempt_ = kRolloverAttemptFrequency - 1;
120 }
121 filename_extension_ = ext;
122 }
123}

◆ SetSymlinkBasename()

void apollo::cyber::logger::LogFileObject::SetSymlinkBasename ( const char *  symlink_basename)

在文件 log_file_object.cc125 行定义.

125 {
126 std::lock_guard<std::mutex> lock(lock_);
127 symlink_basename_ = symlink_basename;
128}

◆ Write()

void apollo::cyber::logger::LogFileObject::Write ( bool  force_flush,
time_t  timestamp,
const char *  message,
int  message_len 
)
override

在文件 log_file_object.cc204 行定义.

205 {
206 std::lock_guard<std::mutex> lock(lock_);
207
208 // We don't log if the base_name_ is "" (which means "don't write")
209 if (base_filename_selected_ && base_filename_.empty()) {
210 return;
211 }
212
213 if (static_cast<int>(file_length_ >> 20) >= MaxLogSize() || PidHasChanged()) {
214 if (file_ != nullptr) {
215 fclose(file_);
216 }
217 file_ = nullptr;
218 file_length_ = bytes_since_flush_ = 0;
219 rollover_attempt_ = kRolloverAttemptFrequency - 1;
220 }
221
222 // If there's no destination file, make one before outputting
223 if (file_ == nullptr) {
224 // Try to rollover the log file every 32 log messages. The only time
225 // this could matter would be when we have trouble creating the log
226 // file. If that happens, we'll lose lots of log messages, of course!
227 if (++rollover_attempt_ != kRolloverAttemptFrequency) {
228 return;
229 }
230 rollover_attempt_ = 0;
231
232 struct ::tm tm_time;
233 localtime_r(&timestamp, &tm_time);
234
235 // The logfile's filename will have the date/time & pid in it
236 ostringstream time_pid_stream;
237 time_pid_stream.fill('0');
238 time_pid_stream << 1900 + tm_time.tm_year << setw(2) << 1 + tm_time.tm_mon
239 << setw(2) << tm_time.tm_mday << '-' << setw(2)
240 << tm_time.tm_hour << setw(2) << tm_time.tm_min << setw(2)
241 << tm_time.tm_sec << '.' << GetMainThreadPid();
242 const string& time_pid_string = time_pid_stream.str();
243
244 // base filename always selected.
245 if (base_filename_selected_) {
246 if (!CreateLogfile(time_pid_string)) {
247 perror("Could not create log file");
248 fprintf(stderr, "COULD NOT CREATE LOGFILE '%s'!\n",
249 time_pid_string.c_str());
250 return;
251 }
252 }
253
254 // Write a header message into the log file
255 ostringstream file_header_stream;
256 file_header_stream.fill('0');
257 file_header_stream << "Log file created at: " << 1900 + tm_time.tm_year
258 << '/' << setw(2) << 1 + tm_time.tm_mon << '/' << setw(2)
259 << tm_time.tm_mday << ' ' << setw(2) << tm_time.tm_hour
260 << ':' << setw(2) << tm_time.tm_min << ':' << setw(2)
261 << tm_time.tm_sec << '\n'
262 << "Running on machine: " << hostname() << '\n'
263 << "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu "
264 << "threadid file:line] msg" << '\n';
265 const string& file_header_string = file_header_stream.str();
266
267 const int header_len = static_cast<int>(file_header_string.size());
268 if (file_ == nullptr) {
269 return;
270 }
271 fwrite(file_header_string.data(), 1, header_len, file_);
272 file_length_ += header_len;
273 bytes_since_flush_ += header_len;
274 }
275
276 // Write to LOG file
277 if (!stop_writing) {
278 // fwrite() doesn't return an error when the disk is full, for
279 // messages that are less than 4096 bytes. When the disk is full,
280 // it returns the message length for messages that are less than
281 // 4096 bytes. fwrite() returns 4096 for message lengths that are
282 // greater than 4096, thereby indicating an error.
283 errno = 0;
284 fwrite(message, 1, message_len, file_);
285 if (FLAGS_stop_logging_if_full_disk &&
286 errno == ENOSPC) { // disk full, stop writing to disk
287 stop_writing = true; // until the disk is
288 return;
289 } else {
290 file_length_ += message_len;
291 bytes_since_flush_ += message_len;
292 }
293 } else {
294 if (CycleClock_Now() >= next_flush_time_) {
295 stop_writing = false; // check to see if disk has free space.
296 }
297 return; // no need to flush
298 }
299
300 // See important msgs *now*. Also, flush logs at least every 10^6 chars,
301 // or every "FLAGS_logbufsecs" seconds.
302 if (force_flush || (bytes_since_flush_ >= 1000000) ||
303 (CycleClock_Now() >= next_flush_time_)) {
305 }
306}

该类的文档由以下文件生成: