| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include <chrono> |
| 6 #include <iomanip> |
| 7 #include <iostream> |
| 8 |
| 9 #include "base/bind.h" |
| 10 #include "mojo/environment/scoped_chromium_init.h" |
| 11 #include "mojo/public/c/system/main.h" |
| 12 #include "mojo/public/cpp/application/application_impl_base.h" |
| 13 #include "mojo/public/cpp/application/connect.h" |
| 14 #include "mojo/public/cpp/application/run_application.h" |
| 15 #include "mojo/services/flog/interfaces/flog.mojom.h" |
| 16 |
| 17 namespace mojo { |
| 18 namespace flog { |
| 19 namespace examples { |
| 20 |
| 21 struct AsNiceDateTime { |
| 22 explicit AsNiceDateTime(uint64_t time_us) : time_us_(time_us) {} |
| 23 uint64_t time_us_; |
| 24 }; |
| 25 |
| 26 std::ostream& operator<<(std::ostream& os, AsNiceDateTime value) { |
| 27 std::time_t time = std::chrono::system_clock::to_time_t( |
| 28 std::chrono::time_point<std::chrono::system_clock>( |
| 29 std::chrono::microseconds(value.time_us_))); |
| 30 std::tm* tm = localtime(&time); |
| 31 return os << std::setw(4) << tm->tm_year + 1900 << "/" << std::setw(2) |
| 32 << std::setfill('0') << tm->tm_mon + 1 << "/" << std::setw(2) |
| 33 << tm->tm_mday << " " << std::setw(2) << tm->tm_hour << ":" |
| 34 << std::setw(2) << tm->tm_min << ":" << std::setw(2) << tm->tm_sec; |
| 35 } |
| 36 |
| 37 struct AsMicroseconds { |
| 38 explicit AsMicroseconds(uint64_t time_us) : time_us_(time_us) {} |
| 39 uint64_t time_us_; |
| 40 }; |
| 41 |
| 42 std::ostream& operator<<(std::ostream& os, AsMicroseconds value) { |
| 43 return os << std::setfill('0') << std::setw(6) << value.time_us_ % 1000000ull; |
| 44 } |
| 45 |
| 46 struct AsLogLevel { |
| 47 explicit AsLogLevel(uint32_t level) : level_(level) {} |
| 48 uint32_t level_; |
| 49 }; |
| 50 |
| 51 std::ostream& operator<<(std::ostream& os, AsLogLevel value) { |
| 52 switch (value.level_) { |
| 53 case MOJO_LOG_LEVEL_VERBOSE: |
| 54 return os << "VERBOSE"; |
| 55 case MOJO_LOG_LEVEL_INFO: |
| 56 return os << "INFO"; |
| 57 case MOJO_LOG_LEVEL_WARNING: |
| 58 return os << "WARNING"; |
| 59 case MOJO_LOG_LEVEL_ERROR: |
| 60 return os << "ERROR"; |
| 61 case MOJO_LOG_LEVEL_FATAL: |
| 62 return os << "FATAL"; |
| 63 default: |
| 64 return os << "UNKNOWN LEVEL " << value.level_; |
| 65 } |
| 66 } |
| 67 |
| 68 class FlogViewerApp : public mojo::ApplicationImplBase { |
| 69 public: |
| 70 FlogViewerApp() {} |
| 71 |
| 72 ~FlogViewerApp() override {} |
| 73 |
| 74 // ApplicationImplBase overrides. |
| 75 void OnInitialize() override { |
| 76 ProcessArgs(args()); |
| 77 |
| 78 if (show_last_) { |
| 79 ShowLastLog(); |
| 80 } else if (log_id_ == 0) { |
| 81 ShowLogs(); |
| 82 } else { |
| 83 ShowLog(log_id_); |
| 84 } |
| 85 } |
| 86 |
| 87 private: |
| 88 // Processes arguments. |
| 89 void ProcessArgs(const std::vector<std::string>& args) { |
| 90 for (size_t i = 1; i < args.size(); ++i) { |
| 91 const std::string& arg = args[i]; |
| 92 |
| 93 if (arg == "--last") { |
| 94 show_last_ = true; |
| 95 continue; |
| 96 } |
| 97 |
| 98 uint32_t id; |
| 99 std::istringstream istream(arg); |
| 100 if (!(istream >> id) || id == 0) { |
| 101 Usage(); |
| 102 } |
| 103 log_id_ = id; |
| 104 } |
| 105 } |
| 106 |
| 107 void Usage() { |
| 108 std::cout << std::endl; |
| 109 std::cout << "mojo/devtools/common/mojo_run " |
| 110 "\"https://core.mojoapps.io/flog_viewer.mojo [ id ]\"" |
| 111 << std::endl; |
| 112 std::cout << std::endl; |
| 113 Terminate(MOJO_RESULT_OK); |
| 114 } |
| 115 |
| 116 void EnsureService() { |
| 117 if (!service_) { |
| 118 ConnectToService(shell(), "mojo:flog", GetProxy(&service_)); |
| 119 } |
| 120 } |
| 121 |
| 122 // Shows log descriptions. |
| 123 void ShowLogs() { |
| 124 EnsureService(); |
| 125 |
| 126 service_->GetLogDescriptions( |
| 127 [this](Array<FlogDescriptionPtr> descriptions) { |
| 128 std::cout << std::endl; |
| 129 std::cout << " id label" << std::endl; |
| 130 std::cout << "-------- ---------------------------------------------" |
| 131 << std::endl; |
| 132 |
| 133 for (const FlogDescriptionPtr& description : descriptions) { |
| 134 std::cout << std::setw(8) << description->log_id << " " |
| 135 << description->label << std::endl; |
| 136 } |
| 137 |
| 138 std::cout << std::endl; |
| 139 |
| 140 Terminate(MOJO_RESULT_OK); |
| 141 }); |
| 142 } |
| 143 |
| 144 // Shows entries from a log. |
| 145 void ShowLog(uint32_t log_id) { |
| 146 MOJO_DCHECK(log_id != 0); |
| 147 |
| 148 EnsureService(); |
| 149 |
| 150 service_->CreateReader(GetProxy(&reader_), log_id); |
| 151 |
| 152 std::cout << std::endl; |
| 153 ShowEntries(0); |
| 154 } |
| 155 |
| 156 // Show the log with the highest id. |
| 157 void ShowLastLog() { |
| 158 EnsureService(); |
| 159 |
| 160 service_->GetLogDescriptions( |
| 161 [this](Array<FlogDescriptionPtr> descriptions) { |
| 162 uint32_t last_id = 0; |
| 163 |
| 164 for (const FlogDescriptionPtr& description : descriptions) { |
| 165 if (last_id < description->log_id) { |
| 166 last_id = description->log_id; |
| 167 } |
| 168 } |
| 169 |
| 170 if (last_id == 0) { |
| 171 std::cout << std::endl; |
| 172 std::cout << "no logs found" << std::endl; |
| 173 std::cout << std::endl; |
| 174 Terminate(MOJO_RESULT_OK); |
| 175 return; |
| 176 } |
| 177 |
| 178 ShowLog(last_id); |
| 179 }); |
| 180 } |
| 181 |
| 182 void ShowEntries(uint32_t start_index) { |
| 183 MOJO_DCHECK(reader_); |
| 184 reader_->GetEntries(start_index, kGetEntriesMaxCount, |
| 185 [this, start_index](Array<FlogEntryPtr> entries) { |
| 186 for (const FlogEntryPtr& entry : entries) { |
| 187 ShowEntry(entry); |
| 188 } |
| 189 |
| 190 if (entries.size() == kGetEntriesMaxCount) { |
| 191 ShowEntries(start_index + kGetEntriesMaxCount); |
| 192 } else { |
| 193 std::cout << std::endl; |
| 194 Terminate(MOJO_RESULT_OK); |
| 195 } |
| 196 }); |
| 197 } |
| 198 |
| 199 void ShowEntry(const FlogEntryPtr& entry) { |
| 200 if (previous_time_us_ / 1000000ull != entry->time_us / 1000000ull) { |
| 201 std::cout << AsNiceDateTime(entry->time_us) << std::endl; |
| 202 } |
| 203 |
| 204 previous_time_us_ = entry->time_us; |
| 205 |
| 206 if (entry->details->is_mojo_logger_message()) { |
| 207 FlogMojoLoggerMessageEntryDetailsPtr details = |
| 208 entry->details->get_mojo_logger_message().Pass(); |
| 209 std::cout << AsMicroseconds(entry->time_us) << " " |
| 210 << AsLogLevel(details->log_level) << ":" << details->source_file |
| 211 << "#" << details->source_line << " " << details->message |
| 212 << std::endl; |
| 213 return; |
| 214 } |
| 215 |
| 216 std::cout << AsMicroseconds(entry->time_us) << " " << entry->channel_id |
| 217 << " "; |
| 218 |
| 219 if (entry->details->is_channel_creation()) { |
| 220 FlogChannelCreationEntryDetailsPtr details = |
| 221 entry->details->get_channel_creation().Pass(); |
| 222 std::cout << "channel created, type " << details->type_name << std::endl; |
| 223 } else if (entry->details->is_channel_message()) { |
| 224 FlogChannelMessageEntryDetailsPtr details = |
| 225 entry->details->get_channel_message().Pass(); |
| 226 std::cout << "channel message, size " << details->data.size() |
| 227 << std::endl; |
| 228 } else if (entry->details->is_channel_deletion()) { |
| 229 FlogChannelDeletionEntryDetailsPtr details = |
| 230 entry->details->get_channel_deletion().Pass(); |
| 231 std::cout << "channel deleted" << std::endl; |
| 232 } else { |
| 233 std::cout << "NO KNOWN DETAILS" << std::endl; |
| 234 } |
| 235 } |
| 236 |
| 237 private: |
| 238 static const uint32_t kGetEntriesMaxCount = 1024; |
| 239 |
| 240 FlogServicePtr service_; |
| 241 FlogReaderPtr reader_; |
| 242 uint32_t log_id_ = 0; |
| 243 bool show_last_ = false; |
| 244 uint64_t previous_time_us_ = 0; |
| 245 }; |
| 246 |
| 247 } // namespace examples |
| 248 } // namespace flog |
| 249 } // namespace mojo |
| 250 |
| 251 MojoResult MojoMain(MojoHandle application_request) { |
| 252 mojo::ScopedChromiumInit init; |
| 253 mojo::flog::examples::FlogViewerApp flog_viewer_app; |
| 254 return mojo::RunApplication(application_request, &flog_viewer_app); |
| 255 } |
| OLD | NEW |