| // Copyright 2020 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/media_router/browser/logger_impl.h" |
| |
| #include <string_view> |
| |
| #include "base/i18n/time_formatting.h" |
| #include "base/json/json_string_value_serializer.h" |
| #include "base/values.h" |
| #include "components/media_router/browser/log_util.h" |
| #include "components/media_router/common/media_source.h" |
| #include "components/media_router/common/mojom/logger.mojom-shared.h" |
| #include "url/gurl.h" |
| |
| namespace media_router { |
| |
| namespace { |
| |
| constexpr size_t kEntriesCapacity = 1000; |
| |
| constexpr size_t kComponentMaxLength = 64; |
| constexpr size_t kMessageMaxLength = 1024; |
| constexpr size_t kSourceMaxLength = 64; |
| |
| const char* AsString(LoggerImpl::Severity severity) { |
| switch (severity) { |
| case LoggerImpl::Severity::kInfo: |
| return "Info"; |
| case LoggerImpl::Severity::kWarning: |
| return "Warning"; |
| case LoggerImpl::Severity::kError: |
| return "Error"; |
| } |
| } |
| |
| const char* AsString(mojom::LogCategory category) { |
| switch (category) { |
| case mojom::LogCategory::kDiscovery: |
| return "Discovery"; |
| case mojom::LogCategory::kRoute: |
| return "Route"; |
| case mojom::LogCategory::kMirroring: |
| return "Mirroring"; |
| case mojom::LogCategory::kUi: |
| return "UI"; |
| } |
| } |
| |
| std::string_view TruncateComponent(std::string_view component) { |
| return component.substr(0, kComponentMaxLength); |
| } |
| |
| std::string_view TruncateMessage(std::string_view message) { |
| return message.substr(0, kMessageMaxLength); |
| } |
| |
| } // namespace |
| |
| LoggerImpl::LoggerImpl() : capacity_(kEntriesCapacity) {} |
| |
| LoggerImpl::~LoggerImpl() { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| } |
| |
| void LoggerImpl::LogInfo(mojom::LogCategory category, |
| const std::string& component, |
| const std::string& message, |
| const std::string& sink_id, |
| const std::string& media_source, |
| const std::string& session_id) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| Log(Severity::kInfo, category, base::Time::Now(), component, message, sink_id, |
| media_source, session_id); |
| } |
| |
| void LoggerImpl::LogWarning(mojom::LogCategory category, |
| const std::string& component, |
| const std::string& message, |
| const std::string& sink_id, |
| const std::string& media_source, |
| const std::string& session_id) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| Log(Severity::kWarning, category, base::Time::Now(), component, message, |
| sink_id, media_source, session_id); |
| } |
| |
| void LoggerImpl::LogError(mojom::LogCategory category, |
| const std::string& component, |
| const std::string& message, |
| const std::string& sink_id, |
| const std::string& media_source, |
| const std::string& session_id) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| Log(Severity::kError, category, base::Time::Now(), component, message, |
| sink_id, media_source, session_id); |
| } |
| |
| void LoggerImpl::BindReceiver(mojo::PendingReceiver<mojom::Logger> receiver) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| receivers_.Add(this, std::move(receiver)); |
| } |
| |
| void LoggerImpl::Log(Severity severity, |
| mojom::LogCategory category, |
| base::Time time, |
| const std::string& component, |
| const std::string& message, |
| const std::string& sink_id, |
| const std::string& media_source, |
| const std::string& session_id) { |
| DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| entries_.emplace_back( |
| severity, category, time, TruncateComponent(component), |
| TruncateMessage(message), log_util::TruncateId(sink_id), |
| MediaSource(media_source).TruncateForLogging(kSourceMaxLength), |
| log_util::TruncateId(session_id)); |
| if (entries_.size() > capacity_) { |
| entries_.pop_front(); |
| } |
| } |
| |
| std::string LoggerImpl::GetLogsAsJson() const { |
| std::string json; |
| JSONStringValueSerializer serializer(&json); |
| serializer.set_pretty_print(true); |
| if (!serializer.Serialize(GetLogsAsValue())) { |
| DVLOG(1) << "Failed to serialize log to JSON."; |
| return ""; |
| } |
| return json; |
| } |
| |
| base::Value LoggerImpl::GetLogsAsValue() const { |
| base::Value::List entries_val; |
| for (const auto& entry : entries_) { |
| entries_val.Append(AsValue(entry)); |
| } |
| return base::Value(std::move(entries_val)); |
| } |
| |
| LoggerImpl::Entry::Entry(Severity severity, |
| mojom::LogCategory category, |
| base::Time time, |
| std::string_view component, |
| std::string_view message, |
| std::string_view sink_id, |
| std::string media_source, |
| std::string_view session_id) |
| : severity(severity), |
| category(category), |
| time(time), |
| component(component), |
| message(message), |
| sink_id(sink_id), |
| media_source(std::move(media_source)), |
| session_id(session_id) {} |
| |
| LoggerImpl::Entry::Entry(Entry&& other) |
| : severity(other.severity), |
| category(other.category), |
| time(other.time), |
| component(std::move(other.component)), |
| message(std::move(other.message)), |
| sink_id(std::move(other.sink_id)), |
| media_source(std::move(other.media_source)), |
| session_id(std::move(other.session_id)) {} |
| |
| LoggerImpl::Entry::~Entry() = default; |
| |
| // static |
| base::Value::Dict LoggerImpl::AsValue(const LoggerImpl::Entry& entry) { |
| base::Value::Dict entry_val; |
| entry_val.Set("severity", base::Value(AsString(entry.severity))); |
| entry_val.Set("category", base::Value(AsString(entry.category))); |
| entry_val.Set( |
| "time", |
| base::Value(base::TimeFormatTimeOfDayWithMilliseconds(entry.time))); |
| entry_val.Set("component", base::Value(entry.component)); |
| entry_val.Set("message", base::Value(entry.message)); |
| entry_val.Set("sinkId", base::Value(entry.sink_id)); |
| entry_val.Set("mediaSource", base::Value(entry.media_source)); |
| entry_val.Set("sessionId", base::Value(entry.session_id)); |
| return entry_val; |
| } |
| |
| } // namespace media_router |