Commit efe6f793 authored by Steven Holte's avatar Steven Holte Committed by Commit Bot

Improve chrome://ukm to decode hashes and show metrics.

Also displays data grouped by source ID.

Change-Id: Ibd7b796e9a92b50fbbc15ef96e748d650da9fa8a
Reviewed-on: https://chromium-review.googlesource.com/587393Reviewed-by: default avatarRobert Kaplow <rkaplow@chromium.org>
Commit-Queue: Steven Holte <holte@chromium.org>
Cr-Commit-Position: refs/heads/master@{#491110}
parent 90008510
......@@ -12,6 +12,7 @@ static_library("debug_page") {
"//base",
"//components/ukm",
"//content/public/browser",
"//services/metrics/public/cpp:ukm_builders",
"//url",
]
}
......@@ -10,11 +10,27 @@
#include "base/strings/stringprintf.h"
#include "components/ukm/ukm_service.h"
#include "components/ukm/ukm_source.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "url/gurl.h"
namespace ukm {
namespace debug {
namespace {
struct SourceData {
UkmSource* source;
std::vector<mojom::UkmEntry*> entries;
};
std::string GetName(ukm::builders::DecodeMap& decode_map, uint64_t hash) {
if (decode_map.count(hash))
return decode_map[hash];
return base::StringPrintf("Unknown %" PRIu64, hash);
}
} // namespace
DebugPage::DebugPage(ServiceGetter service_getter)
: service_getter_(service_getter) {}
......@@ -54,18 +70,35 @@ void DebugPage::StartDataRequest(
data.append(
base::StringPrintf("<p>SessionId:%d</p>", ukm_service->session_id_));
data.append("<h2>Sources</h2>");
auto decode_map = ::ukm::builders::CreateDecodeMap();
std::map<SourceId, SourceData> source_data;
for (const auto& kv : ukm_service->sources_) {
const auto* src = kv.second.get();
data.append(base::StringPrintf("<p>Id:%" PRId64 " Url:%s</p>", src->id(),
src->url().spec().c_str()));
source_data[kv.first].source = kv.second.get();
}
data.append("<h2>Entries</h2>");
for (const auto& v : ukm_service->entries_) {
const auto* entry = v.get();
data.append(base::StringPrintf("<h3>Id:%" PRId64 " Hash:%" PRIu64 "</h3>",
entry->source_id, entry->event_hash));
source_data[v.get()->source_id].entries.push_back(v.get());
}
data.append("<h2>Sources</h2>");
for (const auto& kv : source_data) {
const auto* src = kv.second.source;
if (src) {
data.append(base::StringPrintf("<h3>Id:%" PRId64 " Url:%s</h3>",
src->id(), src->url().spec().c_str()));
} else {
data.append(base::StringPrintf("<h3>Id:%" PRId64 "</h3>", kv.first));
}
for (auto* entry : kv.second.entries) {
data.append(
base::StringPrintf("<h4>Entry:%s</h4>",
GetName(decode_map, entry->event_hash).c_str()));
for (const auto& metric : entry->metrics) {
data.append(base::StringPrintf(
"<h5>Metric:%s Value:%" PRId64 "</h5>",
GetName(decode_map, metric->metric_hash).c_str(), metric->value));
}
}
}
}
......
......@@ -27,6 +27,8 @@ HEADER = """
#ifndef SERVICES_METRICS_PUBLIC_CPP_UKM_BUILDERS_H
#define SERVICES_METRICS_PUBLIC_CPP_UKM_BUILDERS_H
#include <map>
#include "services/metrics/public/cpp/ukm_entry_builder_base.h"
namespace ukm {{
......@@ -34,6 +36,9 @@ namespace builders {{
{decls}
typedef std::map<uint64_t, const char*> DecodeMap;
DecodeMap CreateDecodeMap();
}} // namespace builders
}} // namespace ukm
......@@ -53,6 +58,12 @@ namespace builders {{
{impls}
std::map<uint64_t, const char*> CreateDecodeMap() {{
return {{
{decodes}
}};
}}
}} // namespace builders
}} // namespace ukm
"""
......@@ -63,19 +74,24 @@ class {name} : public ::ukm::internal::UkmEntryBuilderBase {{
{name}(ukm::SourceId source_id);
~{name}() override;
static const char kEntryName[];
{setters}
}};
"""
SETTER_DECL = """
static const char k{metric}Name[];
{name}& Set{metric}(int64_t value);
"""
BUILDER_IMPL = """
const char {name}::kEntryName[] = "{raw}";
{name}::{name}(ukm::SourceId source_id) :
::ukm::internal::UkmEntryBuilderBase(
source_id,
base::HashMetricName("{raw}")) {{
base::HashMetricName(kEntryName)) {{
}}
{name}::~{name}() = default;
......@@ -84,12 +100,23 @@ BUILDER_IMPL = """
"""
SETTER_IMPL = """
const char {name}::k{metric}Name[] = "{raw}";
{name}& {name}::Set{metric}(int64_t value) {{
AddMetric(base::HashMetricName("{raw}"), value);
AddMetric(base::HashMetricName(k{metric}Name), value);
return *this;
}}
"""
ENTRY_DECODE = """
{{base::HashMetricName({name}::kEntryName), {name}::kEntryName}},
{metric_decodes}
"""
METRIC_DECODE = """
{{base::HashMetricName({name}::k{metric}Name), {name}::k{metric}Name}},
"""
parser = argparse.ArgumentParser(description='Generate UKM entry builders')
parser.add_argument('--input', help='Path to ukm.xml')
parser.add_argument('--output', help='Path to generated directory')
......@@ -128,14 +155,27 @@ def GetBuilderImpl(event):
return BUILDER_IMPL.format(name=builder_name, raw=event['name'],
setters=setters)
def GetBody(data):
impls = "\n".join(GetBuilderImpl(event) for event in data['events'])
return BODY.format(impls=impls)
def WriteBody(outdir, data):
output = open(os.path.join(outdir, "ukm_builders.cc"), 'w')
output.write(GetBody(data))
def GetMetricDecode(builder_name, metric):
metric_name = sanitize_name(metric['name'])
return METRIC_DECODE.format(name=builder_name, metric=metric_name)
def GetEntryDecode(event):
builder_name = sanitize_name(event['name'])
metric_decodes = "\n".join(GetMetricDecode(builder_name, metric)
for metric in event['metrics'])
return ENTRY_DECODE.format(name=builder_name,
metric_decodes=metric_decodes)
def GetBody(data):
impls = "\n".join(GetBuilderImpl(event) for event in data['events'])
decodes = "\n".join(GetEntryDecode(event) for event in data['events'])
return BODY.format(impls=impls, decodes=decodes)
def main(argv):
args = parser.parse_args()
data = model.UKM_XML_TYPE.Parse(open(args.input).read())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment