| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <iomanip> |
| 6 #include <iostream> |
| 7 |
| 5 #include "base/logging.h" | 8 #include "base/logging.h" |
| 6 #include "services/flog/flog_logger_impl.h" | 9 #include "services/flog/flog_logger_impl.h" |
| 7 | 10 |
| 8 namespace mojo { | 11 namespace mojo { |
| 9 namespace flog { | 12 namespace flog { |
| 10 | 13 |
| 14 namespace { |
| 15 |
| 16 struct AsMicroseconds { |
| 17 explicit AsMicroseconds(uint64_t time_us) : time_us_(time_us) {} |
| 18 uint64_t time_us_; |
| 19 }; |
| 20 |
| 21 std::ostream& operator<<(std::ostream& os, AsMicroseconds value) { |
| 22 return os << std::setfill('0') << std::setw(6) << value.time_us_ % 1000000ull; |
| 23 } |
| 24 |
| 25 struct AsLogLevel { |
| 26 explicit AsLogLevel(uint32_t level) : level_(level) {} |
| 27 uint32_t level_; |
| 28 }; |
| 29 |
| 30 std::ostream& operator<<(std::ostream& os, AsLogLevel value) { |
| 31 switch (value.level_) { |
| 32 case MOJO_LOG_LEVEL_VERBOSE: |
| 33 return os << "VERBOSE"; |
| 34 case MOJO_LOG_LEVEL_INFO: |
| 35 return os << "INFO"; |
| 36 case MOJO_LOG_LEVEL_WARNING: |
| 37 return os << "WARNING"; |
| 38 case MOJO_LOG_LEVEL_ERROR: |
| 39 return os << "ERROR"; |
| 40 case MOJO_LOG_LEVEL_FATAL: |
| 41 return os << "FATAL"; |
| 42 default: |
| 43 return os << "UNKNOWN LEVEL " << value.level_; |
| 44 } |
| 45 } |
| 46 |
| 47 } // namespace |
| 48 |
| 11 // static | 49 // static |
| 12 std::shared_ptr<FlogLoggerImpl> FlogLoggerImpl::Create( | 50 std::shared_ptr<FlogLoggerImpl> FlogLoggerImpl::Create( |
| 13 InterfaceRequest<FlogLogger> request, | 51 InterfaceRequest<FlogLogger> request, |
| 14 uint32_t log_id, | 52 uint32_t log_id, |
| 15 const std::string& label, | 53 const std::string& label, |
| 16 std::shared_ptr<FlogDirectory> directory, | 54 std::shared_ptr<FlogDirectory> directory, |
| 17 FlogServiceImpl* owner) { | 55 FlogServiceImpl* owner) { |
| 18 return std::shared_ptr<FlogLoggerImpl>( | 56 return std::shared_ptr<FlogLoggerImpl>( |
| 19 new FlogLoggerImpl(request.Pass(), log_id, label, directory, owner)); | 57 new FlogLoggerImpl(request.Pass(), log_id, label, directory, owner)); |
| 20 } | 58 } |
| 21 | 59 |
| 22 FlogLoggerImpl::FlogLoggerImpl(InterfaceRequest<FlogLogger> request, | 60 FlogLoggerImpl::FlogLoggerImpl(InterfaceRequest<FlogLogger> request, |
| 23 uint32_t log_id, | 61 uint32_t log_id, |
| 24 const std::string& label, | 62 const std::string& label, |
| 25 std::shared_ptr<FlogDirectory> directory, | 63 std::shared_ptr<FlogDirectory> directory, |
| 26 FlogServiceImpl* owner) | 64 FlogServiceImpl* owner) |
| 27 : FlogServiceImpl::ProductBase(owner), | 65 : FlogServiceImpl::ProductBase(owner), |
| 28 file_(directory->GetFile(log_id, label, true)) { | 66 file_(directory->GetFile(log_id, label, true)) { |
| 29 mojo::internal::MessageValidatorList validators; | 67 mojo::internal::MessageValidatorList validators; |
| 30 router_.reset(new mojo::internal::Router( | 68 router_.reset(new mojo::internal::Router( |
| 31 request.PassMessagePipe(), std::move(validators), | 69 request.PassMessagePipe(), std::move(validators), |
| 32 Environment::GetDefaultAsyncWaiter())); | 70 Environment::GetDefaultAsyncWaiter())); |
| 33 router_->set_incoming_receiver(this); | 71 router_->set_incoming_receiver(this); |
| 34 router_->set_connection_error_handler([this]() { ReleaseFromOwner(); }); | 72 router_->set_connection_error_handler([this]() { ReleaseFromOwner(); }); |
| 73 stub_.set_sink(this); |
| 35 } | 74 } |
| 36 | 75 |
| 37 FlogLoggerImpl::~FlogLoggerImpl() {} | 76 FlogLoggerImpl::~FlogLoggerImpl() {} |
| 38 | 77 |
| 39 bool FlogLoggerImpl::Accept(Message* message) { | 78 bool FlogLoggerImpl::Accept(Message* message) { |
| 40 DCHECK(message != nullptr); | 79 DCHECK(message != nullptr); |
| 41 DCHECK(message->data_num_bytes() > 0); | 80 DCHECK(message->data_num_bytes() > 0); |
| 42 DCHECK(message->data() != nullptr); | 81 DCHECK(message->data() != nullptr); |
| 43 | 82 |
| 44 uint32_t message_size = message->data_num_bytes(); | 83 uint32_t message_size = message->data_num_bytes(); |
| 45 | 84 |
| 46 WriteData(sizeof(message_size), &message_size); | 85 WriteData(sizeof(message_size), &message_size); |
| 47 WriteData(message_size, message->data()); | 86 WriteData(message_size, message->data()); |
| 48 | 87 |
| 88 // Call the stub to output mojo logger messages to stderr. This has to |
| 89 // happen after we write the message to the file, because deserialization |
| 90 // mutates the message. |
| 91 // TODO(dalesat): Provide a switch to turn this off. |
| 92 stub_.Accept(message); |
| 93 |
| 49 return true; | 94 return true; |
| 50 } | 95 } |
| 51 | 96 |
| 52 bool FlogLoggerImpl::AcceptWithResponder(Message* message, | 97 bool FlogLoggerImpl::AcceptWithResponder(Message* message, |
| 53 MessageReceiverWithStatus* responder) { | 98 MessageReceiverWithStatus* responder) { |
| 54 DCHECK(false) << "FlogLogger has no methods with responses"; | 99 DCHECK(false) << "FlogLogger has no methods with responses"; |
| 55 abort(); | 100 abort(); |
| 56 } | 101 } |
| 57 | 102 |
| 58 void FlogLoggerImpl::WriteData(uint32_t data_size, const void* data) { | 103 void FlogLoggerImpl::WriteData(uint32_t data_size, const void* data) { |
| 59 DCHECK(data_size > 0); | 104 DCHECK(data_size > 0); |
| 60 DCHECK(data != nullptr); | 105 DCHECK(data != nullptr); |
| 61 DCHECK(file_); | 106 DCHECK(file_); |
| 62 | 107 |
| 63 Array<uint8_t> bytes_to_write = Array<uint8_t>::New(data_size); | 108 Array<uint8_t> bytes_to_write = Array<uint8_t>::New(data_size); |
| 64 memcpy(bytes_to_write.data(), data, data_size); | 109 memcpy(bytes_to_write.data(), data, data_size); |
| 65 file_->Write(bytes_to_write.Pass(), 0, files::Whence::FROM_CURRENT, | 110 file_->Write(bytes_to_write.Pass(), 0, files::Whence::FROM_CURRENT, |
| 66 [data_size](files::Error error, uint32 bytes_written) { | 111 [data_size](files::Error error, uint32 bytes_written) { |
| 67 DCHECK(error == files::Error::OK); | 112 DCHECK(error == files::Error::OK); |
| 68 DCHECK(bytes_written == data_size); | 113 DCHECK(bytes_written == data_size); |
| 69 // TODO(dalesat): Handle error. | 114 // TODO(dalesat): Handle error. |
| 70 }); | 115 }); |
| 71 } | 116 } |
| 72 | 117 |
| 118 void FlogLoggerImpl::LogMojoLoggerMessage(int64_t time_us, |
| 119 int32_t log_level, |
| 120 const String& message, |
| 121 const String& source_file, |
| 122 uint32_t source_line) { |
| 123 std::cerr << AsMicroseconds(time_us) << " " << AsLogLevel(log_level) << ":" |
| 124 << source_file << "#" << source_line << " " << message << std::endl; |
| 125 } |
| 126 |
| 127 void FlogLoggerImpl::LogChannelCreation(int64_t time_us, |
| 128 uint32_t channel_id, |
| 129 const String& type_name) {} |
| 130 |
| 131 void FlogLoggerImpl::LogChannelMessage(int64_t time_us, |
| 132 uint32_t channel_id, |
| 133 mojo::Array<uint8_t> data) {} |
| 134 |
| 135 void FlogLoggerImpl::LogChannelDeletion(int64_t time_us, uint32_t channel_id) {} |
| 136 |
| 73 } // namespace flog | 137 } // namespace flog |
| 74 } // namespace mojo | 138 } // namespace mojo |
| OLD | NEW |