diff --git a/logging/BUILD.gn b/logging/BUILD.gn index b48394db4a..ef9d589645 100644 --- a/logging/BUILD.gn +++ b/logging/BUILD.gn @@ -421,20 +421,6 @@ if (rtc_enable_protobuf) { } } } - if (rtc_include_tests) { - rtc_executable("rtc_event_log2stats") { - testonly = true - sources = [ - "rtc_event_log/rtc_event_log2stats.cc", - ] - deps = [ - ":rtc_event_log_api", - ":rtc_event_log_proto", - "../rtc_base:checks", - "../rtc_base:rtc_base_approved", - ] - } - } } rtc_source_set("ice_log") { diff --git a/logging/rtc_event_log/rtc_event_log2stats.cc b/logging/rtc_event_log/rtc_event_log2stats.cc deleted file mode 100644 index da8f23a5ec..0000000000 --- a/logging/rtc_event_log/rtc_event_log2stats.cc +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "logging/rtc_event_log/rtc_event_log.h" -#include "rtc_base/checks.h" -#include "rtc_base/flags.h" -#include "rtc_base/ignore_wundef.h" -#include "rtc_base/logging.h" - -// Files generated at build-time by the protobuf compiler. -RTC_PUSH_IGNORING_WUNDEF() -#ifdef WEBRTC_ANDROID_PLATFORM_BUILD -#include "external/webrtc/webrtc/logging/rtc_event_log/rtc_event_log.pb.h" -#else -#include "logging/rtc_event_log/rtc_event_log.pb.h" -#endif -RTC_POP_IGNORING_WUNDEF() - -namespace { - -WEBRTC_DEFINE_bool(help, false, "Prints this message."); - -struct Stats { - int count = 0; - size_t total_size = 0; -}; - -// We are duplicating some parts of the parser here because we want to get -// access to raw protobuf events. -std::pair ParseVarInt(std::istream& stream) { - uint64_t varint = 0; - for (size_t bytes_read = 0; bytes_read < 10; ++bytes_read) { - // The most significant bit of each byte is 0 if it is the last byte in - // the varint and 1 otherwise. Thus, we take the 7 least significant bits - // of each byte and shift them 7 bits for each byte read previously to get - // the (unsigned) integer. - int byte = stream.get(); - if (stream.eof()) { - return std::make_pair(varint, false); - } - RTC_DCHECK_GE(byte, 0); - RTC_DCHECK_LE(byte, 255); - varint |= static_cast(byte & 0x7F) << (7 * bytes_read); - if ((byte & 0x80) == 0) { - return std::make_pair(varint, true); - } - } - return std::make_pair(varint, false); -} - -bool ParseEvents(const std::string& filename, - std::vector* events) { - std::ifstream stream(filename, std::ios_base::in | std::ios_base::binary); - if (!stream.good() || !stream.is_open()) { - RTC_LOG(LS_WARNING) << "Could not open file for reading."; - return false; - } - - const size_t kMaxEventSize = (1u << 16) - 1; - std::vector tmp_buffer(kMaxEventSize); - uint64_t tag; - uint64_t message_length; - bool success; - - RTC_DCHECK(stream.good()); - - while (1) { - // Check whether we have reached end of file. - stream.peek(); - if (stream.eof()) { - return true; - } - - // Read the next message tag. The tag number is defined as - // (fieldnumber << 3) | wire_type. In our case, the field number is - // supposed to be 1 and the wire type for an length-delimited field is 2. - const uint64_t kExpectedTag = (1 << 3) | 2; - std::tie(tag, success) = ParseVarInt(stream); - if (!success) { - RTC_LOG(LS_WARNING) - << "Missing field tag from beginning of protobuf event."; - return false; - } else if (tag != kExpectedTag) { - RTC_LOG(LS_WARNING) - << "Unexpected field tag at beginning of protobuf event."; - return false; - } - - // Read the length field. - std::tie(message_length, success) = ParseVarInt(stream); - if (!success) { - RTC_LOG(LS_WARNING) << "Missing message length after protobuf field tag."; - return false; - } else if (message_length > kMaxEventSize) { - RTC_LOG(LS_WARNING) << "Protobuf message length is too large."; - return false; - } - - // Read the next protobuf event to a temporary char buffer. - stream.read(tmp_buffer.data(), message_length); - if (stream.gcount() != static_cast(message_length)) { - RTC_LOG(LS_WARNING) << "Failed to read protobuf message from file."; - return false; - } - - // Parse the protobuf event from the buffer. - webrtc::rtclog::Event event; - if (!event.ParseFromArray(tmp_buffer.data(), message_length)) { - RTC_LOG(LS_WARNING) << "Failed to parse protobuf message."; - return false; - } - events->push_back(event); - } -} - -// TODO(terelius): Should this be placed in some utility file instead? -std::string EventTypeToString(webrtc::rtclog::Event::EventType event_type) { - switch (event_type) { - case webrtc::rtclog::Event::UNKNOWN_EVENT: - return "UNKNOWN_EVENT"; - case webrtc::rtclog::Event::LOG_START: - return "LOG_START"; - case webrtc::rtclog::Event::LOG_END: - return "LOG_END"; - case webrtc::rtclog::Event::RTP_EVENT: - return "RTP_EVENT"; - case webrtc::rtclog::Event::RTCP_EVENT: - return "RTCP_EVENT"; - case webrtc::rtclog::Event::AUDIO_PLAYOUT_EVENT: - return "AUDIO_PLAYOUT_EVENT"; - case webrtc::rtclog::Event::LOSS_BASED_BWE_UPDATE: - return "LOSS_BASED_BWE_UPDATE"; - case webrtc::rtclog::Event::DELAY_BASED_BWE_UPDATE: - return "DELAY_BASED_BWE_UPDATE"; - case webrtc::rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT: - return "VIDEO_RECV_CONFIG"; - case webrtc::rtclog::Event::VIDEO_SENDER_CONFIG_EVENT: - return "VIDEO_SEND_CONFIG"; - case webrtc::rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT: - return "AUDIO_RECV_CONFIG"; - case webrtc::rtclog::Event::AUDIO_SENDER_CONFIG_EVENT: - return "AUDIO_SEND_CONFIG"; - case webrtc::rtclog::Event::AUDIO_NETWORK_ADAPTATION_EVENT: - return "AUDIO_NETWORK_ADAPTATION"; - case webrtc::rtclog::Event::BWE_PROBE_CLUSTER_CREATED_EVENT: - return "BWE_PROBE_CREATED"; - case webrtc::rtclog::Event::BWE_PROBE_RESULT_EVENT: - return "BWE_PROBE_RESULT"; - case webrtc::rtclog::Event::ALR_STATE_EVENT: - return "ALR_STATE_EVENT"; - case webrtc::rtclog::Event::ICE_CANDIDATE_PAIR_CONFIG: - return "ICE_CANDIDATE_PAIR_CONFIG"; - case webrtc::rtclog::Event::ICE_CANDIDATE_PAIR_EVENT: - return "ICE_CANDIDATE_PAIR_EVENT"; - } - RTC_NOTREACHED(); - return "UNKNOWN_EVENT"; -} - -} // namespace - -// This utility will print basic information about each packet to stdout. -// Note that parser will assert if the protobuf event is missing some required -// fields and we attempt to access them. We don't handle this at the moment. -int main(int argc, char* argv[]) { - std::string program_name = argv[0]; - std::string usage = - "Tool for file usage statistics from an RtcEventLog.\n" - "Run " + - program_name + - " --help for usage.\n" - "Example usage:\n" + - program_name + " input.rel\n"; - if (rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, true) || FLAG_help || - argc != 2) { - std::cout << usage; - if (FLAG_help) { - rtc::FlagList::Print(nullptr, false); - return 0; - } - return 1; - } - std::string file_name = argv[1]; - - std::vector events; - if (!ParseEvents(file_name, &events)) { - RTC_LOG(LS_ERROR) << "Failed to parse event log."; - return -1; - } - - // Get file size - FILE* file = fopen(file_name.c_str(), "rb"); - fseek(file, 0L, SEEK_END); - int64_t file_size = ftell(file); - fclose(file); - - // We are deliberately using low level protobuf functions to get the stats - // since the convenience functions in the parser would CHECK that the events - // are well formed. - std::map stats; - int malformed_events = 0; - size_t malformed_event_size = 0; - size_t accumulated_event_size = 0; - for (const webrtc::rtclog::Event& event : events) { - size_t serialized_size = event.ByteSizeLong(); - // When the event is written on the disk, it is part of an EventStream - // object. The event stream will prepend a 1 byte field number/wire type, - // and a varint encoding (base 128) of the event length. - serialized_size = - 1 + (1 + (serialized_size > 127) + (serialized_size > 16383)) + - serialized_size; - - if (event.has_type() && event.has_timestamp_us()) { - stats[event.type()].count++; - stats[event.type()].total_size += serialized_size; - } else { - // The event is missing the type or the timestamp field. - malformed_events++; - malformed_event_size += serialized_size; - } - accumulated_event_size += serialized_size; - } - - printf("Type \tCount\tTotal size\tAverage size\tPercent\n"); - printf( - "-----------------------------------------------------------------------" - "\n"); - for (const auto it : stats) { - printf("%-22s\t%5d\t%10zu\t%12.2lf\t%7.2lf\n", - EventTypeToString(it.first).c_str(), it.second.count, - it.second.total_size, - static_cast(it.second.total_size) / it.second.count, - static_cast(it.second.total_size) / file_size * 100); - } - if (malformed_events != 0) { - printf("%-22s\t%5d\t%10zu\t%12.2lf\t%7.2lf\n", "MALFORMED", - malformed_events, malformed_event_size, - static_cast(malformed_event_size) / malformed_events, - static_cast(malformed_event_size) / file_size * 100); - } - if (file_size - accumulated_event_size != 0) { - printf("WARNING: %" PRId64 " bytes not accounted for\n", - file_size - accumulated_event_size); - } - - return 0; -}