blob: d4dea64559efbc6b88d38028441a95521e9ec7ea [file] [log] [blame]
Austin Schuhf2a50ba2016-12-24 16:16:26 -08001#include <dirent.h>
2#include <errno.h>
3#include <fcntl.h>
4#include <mntent.h>
5#include <pwd.h>
brians343bc112013-02-10 01:53:46 +00006#include <stdio.h>
7#include <stdlib.h>
brians343bc112013-02-10 01:53:46 +00008#include <string.h>
brians343bc112013-02-10 01:53:46 +00009#include <sys/types.h>
Austin Schuhf2a50ba2016-12-24 16:16:26 -080010#include <time.h>
11#include <unistd.h>
12#include <string>
brians343bc112013-02-10 01:53:46 +000013
Austin Schuhf2a50ba2016-12-24 16:16:26 -080014#include <chrono>
brians343bc112013-02-10 01:53:46 +000015#include <map>
Brian Silverman88471dc2014-02-15 22:35:42 -080016#include <unordered_set>
brians343bc112013-02-10 01:53:46 +000017
John Park33858a32018-09-28 23:05:48 -070018#include "aos/die.h"
19#include "aos/logging/binary_log_file.h"
20#include "aos/logging/implementations.h"
James Kuszmaul011b67a2019-12-15 12:52:34 -080021#include "aos/logging/log_namer.h"
John Park33858a32018-09-28 23:05:48 -070022#include "aos/time/time.h"
John Park398c74a2018-10-20 21:17:39 -070023#include "aos/configuration.h"
24#include "aos/init.h"
25#include "aos/ipc_lib/queue.h"
brians343bc112013-02-10 01:53:46 +000026
Brian Silvermanf665d692013-02-17 22:11:39 -080027namespace aos {
28namespace logging {
Brian Silverman14fd0fb2014-01-14 21:42:01 -080029namespace linux_code {
Brian Silvermanf665d692013-02-17 22:11:39 -080030namespace {
brians343bc112013-02-10 01:53:46 +000031
Brian Silvermanab6615c2013-03-05 20:29:29 -080032int BinaryLogReaderMain() {
Brian Silvermanf665d692013-02-17 22:11:39 -080033 InitNRT();
brians343bc112013-02-10 01:53:46 +000034
James Kuszmaul011b67a2019-12-15 12:52:34 -080035 const std::string file_name = GetLogName("aos_log");
36 int fd = open(file_name.c_str(), O_SYNC | O_APPEND | O_RDWR | O_CREAT,
brians343bc112013-02-10 01:53:46 +000037 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
brians343bc112013-02-10 01:53:46 +000038 if (fd == -1) {
James Kuszmaul011b67a2019-12-15 12:52:34 -080039 AOS_PLOG(FATAL, "opening file '%s' failed", file_name.c_str());
brians343bc112013-02-10 01:53:46 +000040 }
Brian Silvermanab5ba472014-04-18 15:26:14 -070041 LogFileWriter writer(fd);
brians343bc112013-02-10 01:53:46 +000042
Brian Silvermancb5da1f2015-12-05 22:19:58 -050043 RawQueue *queue = GetLoggingQueue();
44
Brian Silvermanf5ca4d02015-03-01 16:52:24 -050045 ::std::unordered_set<uint32_t> written_type_ids;
Brian Silvermanf5ca4d02015-03-01 16:52:24 -050046
brians343bc112013-02-10 01:53:46 +000047 while (true) {
Brian Silvermancb5da1f2015-12-05 22:19:58 -050048 const LogMessage *const msg =
Brian Silverman18c2c362016-01-02 14:18:32 -080049 static_cast<const LogMessage *>(queue->ReadMessage(RawQueue::kNonBlock));
50 if (msg == NULL) {
51 // If we've emptied the queue, then wait for a bit before starting to read
52 // again so the queue can buffer up some logs. This avoids lots of context
53 // switches and mutex contention which happens if we're constantly reading
54 // new messages as they come in.
Austin Schuhf2a50ba2016-12-24 16:16:26 -080055 ::std::this_thread::sleep_for(::std::chrono::milliseconds(100));
Brian Silverman18c2c362016-01-02 14:18:32 -080056 continue;
57 }
brians343bc112013-02-10 01:53:46 +000058
Brian Silverman664db1a2014-03-20 17:06:29 -070059 const size_t raw_output_length =
Brian Silverman88471dc2014-02-15 22:35:42 -080060 sizeof(LogFileMessageHeader) + msg->name_length + msg->message_length;
Brian Silverman664db1a2014-03-20 17:06:29 -070061 size_t output_length = raw_output_length;
Brian Silverman91660632014-03-21 20:52:03 -070062 LogFileMessageHeader *const output = writer.GetWritePosition(output_length);
brians343bc112013-02-10 01:53:46 +000063 char *output_strings = reinterpret_cast<char *>(output) + sizeof(*output);
Brian Silverman88471dc2014-02-15 22:35:42 -080064 output->name_size = msg->name_length;
65 output->message_size = msg->message_length;
brians343bc112013-02-10 01:53:46 +000066 output->source = msg->source;
Brian Silvermanf665d692013-02-17 22:11:39 -080067 output->level = msg->level;
68 output->time_sec = msg->seconds;
69 output->time_nsec = msg->nseconds;
70 output->sequence = msg->sequence;
Brian Silverman88471dc2014-02-15 22:35:42 -080071 memcpy(output_strings, msg->name, msg->name_length);
72
73 switch (msg->type) {
74 case LogMessage::Type::kString:
75 memcpy(output_strings + msg->name_length, msg->message,
76 msg->message_length);
77 output->type = LogFileMessageHeader::MessageType::kString;
78 break;
Brian Silverman88471dc2014-02-15 22:35:42 -080079 }
80
Brian Silverman664db1a2014-03-20 17:06:29 -070081 if (output->message_size - msg->message_length !=
82 output_length - raw_output_length) {
Austin Schuhf257f3c2019-10-27 21:00:43 -070083 AOS_LOG(FATAL, "%zu != %zu\n", output->message_size - msg->message_length,
84 output_length - raw_output_length);
Brian Silverman664db1a2014-03-20 17:06:29 -070085 }
86
Brian Silvermanaf221b82013-09-01 13:57:50 -070087 futex_set(&output->marker);
brians343bc112013-02-10 01:53:46 +000088
Brian Silvermancb5da1f2015-12-05 22:19:58 -050089 queue->FreeMessage(msg);
brians343bc112013-02-10 01:53:46 +000090 }
91
Brian Silvermanf665d692013-02-17 22:11:39 -080092 Cleanup();
93 return 0;
94}
95
96} // namespace
Brian Silverman14fd0fb2014-01-14 21:42:01 -080097} // namespace linux_code
Brian Silvermanf665d692013-02-17 22:11:39 -080098} // namespace logging
99} // namespace aos
100
101int main() {
Brian Silverman14fd0fb2014-01-14 21:42:01 -0800102 return ::aos::logging::linux_code::BinaryLogReaderMain();
brians343bc112013-02-10 01:53:46 +0000103}