Skip to content

Commit

Permalink
Add NetLog record method to Cobalt panel in Devtools (youtube#1798)
Browse files Browse the repository at this point in the history
Much like the utility button to capture and download a Trace, this CL
adds a button to the Cobalt tab of Devtools for capturing a NetLog.

View it here - https://screenshot.googleplex.com/ATA2L2GcEH6W272 

See here for more details on NetLog -
https://github.com/youtube/cobalt/blob/main/cobalt/doc/net_log.md

b/305257093
  • Loading branch information
sideb0ard authored Oct 20, 2023
1 parent 66cf902 commit 301a02e
Show file tree
Hide file tree
Showing 13 changed files with 205 additions and 12 deletions.
1 change: 1 addition & 0 deletions cobalt/browser/idl_files.gni
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ source_idl_files = [
"//cobalt/h5vcc/h5vcc_screen.idl",
"//cobalt/h5vcc/h5vcc_system.idl",
"//cobalt/h5vcc/h5vcc_trace_event.idl",
"//cobalt/h5vcc/h5vcc_net_log.idl",
"//cobalt/h5vcc/h5vcc_updater.idl",

"//cobalt/media_capture/blob_event.idl",
Expand Down
2 changes: 2 additions & 0 deletions cobalt/h5vcc/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ static_library("h5vcc") {
"h5vcc_event_listener_container.h",
"h5vcc_metrics.cc",
"h5vcc_metrics.h",
"h5vcc_net_log.cc",
"h5vcc_net_log.h",
"h5vcc_platform_service.cc",
"h5vcc_platform_service.h",
"h5vcc_runtime.cc",
Expand Down
2 changes: 2 additions & 0 deletions cobalt/h5vcc/h5vcc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ H5vcc::H5vcc(const Settings& settings) {
storage_ =
new H5vccStorage(settings.network_module, settings.persistent_settings);
trace_event_ = new H5vccTraceEvent();
net_log_ = new H5vccNetLog(settings.network_module);
#if SB_IS(EVERGREEN)
updater_ = new H5vccUpdater(settings.updater_module);
system_ = new H5vccSystem(updater_);
Expand Down Expand Up @@ -80,6 +81,7 @@ void H5vcc::TraceMembers(script::Tracer* tracer) {
tracer->Trace(storage_);
tracer->Trace(system_);
tracer->Trace(trace_event_);
tracer->Trace(net_log_);
#if SB_IS(EVERGREEN)
tracer->Trace(updater_);
#endif
Expand Down
3 changes: 3 additions & 0 deletions cobalt/h5vcc/h5vcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "cobalt/h5vcc/h5vcc_audio_config_array.h"
#include "cobalt/h5vcc/h5vcc_crash_log.h"
#include "cobalt/h5vcc/h5vcc_metrics.h"
#include "cobalt/h5vcc/h5vcc_net_log.h"
#include "cobalt/h5vcc/h5vcc_runtime.h"
#include "cobalt/h5vcc/h5vcc_settings.h"
#include "cobalt/h5vcc/h5vcc_storage.h"
Expand Down Expand Up @@ -85,6 +86,7 @@ class H5vcc : public script::Wrappable {
const scoped_refptr<H5vccTraceEvent>& trace_event() const {
return trace_event_;
}
const scoped_refptr<H5vccNetLog>& net_log() const { return net_log_; }
#if SB_IS(EVERGREEN)
const scoped_refptr<H5vccUpdater>& updater() const { return updater_; }
#endif
Expand All @@ -103,6 +105,7 @@ class H5vcc : public script::Wrappable {
scoped_refptr<H5vccStorage> storage_;
scoped_refptr<H5vccSystem> system_;
scoped_refptr<H5vccTraceEvent> trace_event_;
scoped_refptr<H5vccNetLog> net_log_;
#if SB_IS(EVERGREEN)
scoped_refptr<H5vccUpdater> updater_;
#endif
Expand Down
1 change: 1 addition & 0 deletions cobalt/h5vcc/h5vcc.idl
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ interface H5vcc {
readonly attribute H5vccStorage storage;
readonly attribute H5vccSystem system;
readonly attribute H5vccTraceEvent traceEvent;
readonly attribute H5vccNetLog netLog;
[Conditional=SB_IS_EVERGREEN]
readonly attribute H5vccUpdater updater;
};
43 changes: 43 additions & 0 deletions cobalt/h5vcc/h5vcc_net_log.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2023 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/h5vcc/h5vcc_net_log.h"

#include "base/files/file_util.h"
#include "base/path_service.h"
#include "cobalt/base/cobalt_paths.h"
#include "cobalt/network/cobalt_net_log.h"

namespace cobalt {
namespace h5vcc {

H5vccNetLog::H5vccNetLog(cobalt::network::NetworkModule* network_module)
: network_module_{network_module} {}

void H5vccNetLog::Start() { network_module_->StartNetLog(); }

void H5vccNetLog::Stop() { network_module_->StopNetLog(); }

std::string H5vccNetLog::StopAndRead() {
base::FilePath netlog_path = network_module_->StopNetLog();
std::string netlog_output{};
if (!netlog_path.empty()) {
ReadFileToString(netlog_path, &netlog_output);
}
return netlog_output;
}


} // namespace h5vcc
} // namespace cobalt
45 changes: 45 additions & 0 deletions cobalt/h5vcc/h5vcc_net_log.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright 2023 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_H5VCC_H5VCC_NET_LOG_H_
#define COBALT_H5VCC_H5VCC_NET_LOG_H_

#include <string>

#include "cobalt/network/network_module.h"
#include "cobalt/script/wrappable.h"

namespace cobalt {
namespace h5vcc {

class H5vccNetLog : public script::Wrappable {
public:
explicit H5vccNetLog(cobalt::network::NetworkModule* network_module);

void Start();
void Stop();
std::string StopAndRead();

DEFINE_WRAPPABLE_TYPE(H5vccNetLog);

private:
cobalt::network::NetworkModule* network_module_ = nullptr;

DISALLOW_COPY_AND_ASSIGN(H5vccNetLog);
};

} // namespace h5vcc
} // namespace cobalt

#endif // COBALT_H5VCC_H5VCC_NET_LOG_H_
19 changes: 19 additions & 0 deletions cobalt/h5vcc/h5vcc_net_log.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2023 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

interface H5vccNetLog {
void start();
void stop();
DOMString stopAndRead();
};
25 changes: 20 additions & 5 deletions cobalt/network/cobalt_net_log.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,29 @@ namespace network {

CobaltNetLog::CobaltNetLog(const base::FilePath& log_path,
net::NetLogCaptureMode capture_mode)
: net_log_logger_(
net::FileNetLogObserver::CreateUnbounded(log_path, nullptr)) {
net_log_logger_->StartObserving(this, capture_mode);
}
: capture_mode_(capture_mode),
net_log_logger_(
net::FileNetLogObserver::CreateUnbounded(log_path, nullptr)) {}

CobaltNetLog::~CobaltNetLog() {
// Remove the observers we own before we're destroyed.
net_log_logger_->StopObserving(nullptr, base::OnceClosure());
StopObserving();
}

void CobaltNetLog::StartObserving() {
if (!is_observing_) {
is_observing_ = true;
net_log_logger_->StartObserving(this, capture_mode_);
} else {
DLOG(WARNING) << "Already observing NetLog.";
}
}

void CobaltNetLog::StopObserving() {
if (is_observing_) {
is_observing_ = false;
net_log_logger_->StopObserving(nullptr, base::OnceClosure());
}
}

} // namespace network
Expand Down
7 changes: 6 additions & 1 deletion cobalt/network/cobalt_net_log.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,13 @@ class CobaltNetLog : public ::net::NetLog {
::net::NetLogCaptureMode capture_mode);
~CobaltNetLog() override;

void StartObserving();
void StopObserving();

private:
std::unique_ptr<net::FileNetLogObserver> net_log_logger_;
bool is_observing_{false};
net::NetLogCaptureMode capture_mode_;
std::unique_ptr<net::FileNetLogObserver> net_log_logger_{nullptr};

DISALLOW_COPY_AND_ASSIGN(CobaltNetLog);
};
Expand Down
32 changes: 27 additions & 5 deletions cobalt/network/network_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
#include "base/bind.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "cobalt/base/cobalt_paths.h"
#include "cobalt/network/network_system.h"
#include "cobalt/network/switches.h"
#include "net/url_request/static_http_user_agent_settings.h"
Expand All @@ -33,6 +35,7 @@ namespace {
const char kCaptureModeIncludeCookiesAndCredentials[] =
"IncludeCookiesAndCredentials";
const char kCaptureModeIncludeSocketBytes[] = "IncludeSocketBytes";
const char kDefaultNetLogName[] = "cobalt_netlog.json";
#endif
} // namespace

Expand Down Expand Up @@ -159,11 +162,12 @@ void NetworkModule::Initialize(const std::string& user_agent_string,
}

#if defined(ENABLE_NETWORK_LOGGING)
base::FilePath result;
base::PathService::Get(cobalt::paths::DIR_COBALT_DEBUG_OUT, &result);
net_log_path_ = result.Append(kDefaultNetLogName);
net::NetLogCaptureMode capture_mode;
if (command_line->HasSwitch(switches::kNetLog)) {
// If this is not a valid path, net logs will be sent to VLOG(1).
base::FilePath net_log_path =
command_line->GetSwitchValuePath(switches::kNetLog);
net::NetLogCaptureMode capture_mode;
net_log_path_ = command_line->GetSwitchValuePath(switches::kNetLog);
if (command_line->HasSwitch(switches::kNetLogCaptureMode)) {
std::string capture_mode_string =
command_line->GetSwitchValueASCII(switches::kNetLogCaptureMode);
Expand All @@ -173,7 +177,10 @@ void NetworkModule::Initialize(const std::string& user_agent_string,
capture_mode = net::NetLogCaptureMode::IncludeSocketBytes();
}
}
net_log_.reset(new CobaltNetLog(net_log_path, capture_mode));
net_log_.reset(new CobaltNetLog(net_log_path_, capture_mode));
net_log_->StartObserving();
} else {
net_log_.reset(new CobaltNetLog(net_log_path_, capture_mode));
}
#endif

Expand Down Expand Up @@ -244,5 +251,20 @@ void NetworkModule::AddClientHintHeaders(
}
}

void NetworkModule::StartNetLog() {
#if defined(ENABLE_NETWORK_LOGGING)
LOG(INFO) << "Starting NetLog capture";
net_log_->StartObserving();
#endif
}

base::FilePath NetworkModule::StopNetLog() {
#if defined(ENABLE_NETWORK_LOGGING)
LOG(INFO) << "Stopping NetLog capture";
net_log_->StopObserving();
#endif
return net_log_path_;
}

} // namespace network
} // namespace cobalt
9 changes: 8 additions & 1 deletion cobalt/network/network_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ class NetworkModule : public base::MessageLoop::DestructionObserver {
// From base::MessageLoop::DestructionObserver.
void WillDestroyCurrentMessageLoop() override;

// Used to capture NetLog from Devtools
void StartNetLog();
base::FilePath StopNetLog();


private:
void Initialize(const std::string& user_agent_string,
base::EventDispatcher* event_dispatcher);
Expand All @@ -163,7 +168,9 @@ class NetworkModule : public base::MessageLoop::DestructionObserver {
scoped_refptr<network::DialServiceProxy> dial_service_proxy_;
#endif
std::unique_ptr<network_bridge::NetPoster> net_poster_;
std::unique_ptr<CobaltNetLog> net_log_;

base::FilePath net_log_path_;
std::unique_ptr<CobaltNetLog> net_log_{nullptr};
Options options_;

DISALLOW_COPY_AND_ASSIGN(NetworkModule);
Expand Down
28 changes: 28 additions & 0 deletions third_party/devtools/front_end/cobalt/cobalt.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,32 @@ export default class CobaltPanel extends UI.VBox {
});
}));
});

const netLogContainer = this.element.createChild('div', 'netlog-container');
netLogContainer.appendChild(UI.createTextButton(Common.UIString('Start NetLog'), event => {
console.log("Start NetLog");
this.run(`(function() { window.h5vcc.netLog.start();})()`);
console.log("Started NetLog");
}));
netLogContainer.appendChild(UI.createTextButton(Common.UIString('Stop NetLog'), event => {
console.log("Stop NetLog");
this.run(`(function() { window.h5vcc.netLog.stop();})()`);
console.log("Stopped NetLog");
}));
netLogContainer.appendChild(UI.createTextButton(Common.UIString('Download NetLog'), event => {
console.log("Download Trace");
this.run(`(function() { return window.h5vcc.netLog.stopAndRead();})()`).then(function (result) {
const netlog_file = 'net_log.json';
download_element.setAttribute('href', 'data:text/plain;charset=utf-8,' +
encodeURIComponent(result.result.value));
download_element.setAttribute('download', netlog_file);
console.log("Downloaded NetLog");
download_element.click();
download_element.setAttribute('href', undefined);
});
}));


const debugLogContainer = this.element.createChild('div', 'debug-log-container');
debugLogContainer.appendChild(UI.createTextButton(Common.UIString('DebugLog On'), event => {
this._cobaltAgent.invoke_sendConsoleCommand({
Expand All @@ -69,6 +95,7 @@ export default class CobaltPanel extends UI.VBox {
command: 'debug_log', message: 'off'
});
}));

const lifecycleContainer = this.element.createChild('div', 'lifecycle-container');
lifecycleContainer.appendChild(UI.createTextButton(Common.UIString('Blur'), event => {
this._cobaltAgent.invoke_sendConsoleCommand({ command: 'blur' });
Expand All @@ -88,6 +115,7 @@ export default class CobaltPanel extends UI.VBox {
lifecycleContainer.appendChild(UI.createTextButton(Common.UIString('Quit'), event => {
this._cobaltAgent.invoke_sendConsoleCommand({ command: 'quit' });
}));

const consoleContainer = this.element.createChild('div', 'console-container');
consoleContainer.appendChild(UI.createTextButton(Common.UIString('DebugCommand'), event => {
const outputElement = document.getElementsByClassName('console-output')[0];
Expand Down

0 comments on commit 301a02e

Please sign in to comment.