1*333d2b36SAndroid Build Coastguard Worker// Copyright 2018 Google Inc. All rights reserved. 2*333d2b36SAndroid Build Coastguard Worker// 3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*333d2b36SAndroid Build Coastguard Worker// 7*333d2b36SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*333d2b36SAndroid Build Coastguard Worker// 9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*333d2b36SAndroid Build Coastguard Worker// limitations under the License. 14*333d2b36SAndroid Build Coastguard Worker 15*333d2b36SAndroid Build Coastguard Worker// Package metrics represents the metrics system for Android Platform Build Systems. 16*333d2b36SAndroid Build Coastguard Workerpackage metrics 17*333d2b36SAndroid Build Coastguard Worker 18*333d2b36SAndroid Build Coastguard Worker// This is the main heart of the metrics system for Android Platform Build Systems. 19*333d2b36SAndroid Build Coastguard Worker// The starting of the soong_ui (cmd/soong_ui/main.go), the metrics system is 20*333d2b36SAndroid Build Coastguard Worker// initialized by the invocation of New and is then stored in the context 21*333d2b36SAndroid Build Coastguard Worker// (ui/build/context.go) to be used throughout the system. During the build 22*333d2b36SAndroid Build Coastguard Worker// initialization phase, several functions in this file are invoked to store 23*333d2b36SAndroid Build Coastguard Worker// information such as the environment, build configuration and build metadata. 24*333d2b36SAndroid Build Coastguard Worker// There are several scoped code that has Begin() and defer End() functions 25*333d2b36SAndroid Build Coastguard Worker// that captures the metrics and is them added as a perfInfo into the set 26*333d2b36SAndroid Build Coastguard Worker// of the collected metrics. Finally, when soong_ui has finished the build, 27*333d2b36SAndroid Build Coastguard Worker// the defer Dump function is invoked to store the collected metrics to the 28*333d2b36SAndroid Build Coastguard Worker// raw protobuf file in the $OUT directory and this raw protobuf file will be 29*333d2b36SAndroid Build Coastguard Worker// uploaded to the destination. See ui/build/upload.go for more details. The 30*333d2b36SAndroid Build Coastguard Worker// filename of the raw protobuf file and the list of files to be uploaded is 31*333d2b36SAndroid Build Coastguard Worker// defined in cmd/soong_ui/main.go. See ui/metrics/event.go for the explanation 32*333d2b36SAndroid Build Coastguard Worker// of what an event is and how the metrics system is a stack based system. 33*333d2b36SAndroid Build Coastguard Worker 34*333d2b36SAndroid Build Coastguard Workerimport ( 35*333d2b36SAndroid Build Coastguard Worker "os" 36*333d2b36SAndroid Build Coastguard Worker "runtime" 37*333d2b36SAndroid Build Coastguard Worker "strings" 38*333d2b36SAndroid Build Coastguard Worker "time" 39*333d2b36SAndroid Build Coastguard Worker 40*333d2b36SAndroid Build Coastguard Worker "android/soong/shared" 41*333d2b36SAndroid Build Coastguard Worker 42*333d2b36SAndroid Build Coastguard Worker "google.golang.org/protobuf/proto" 43*333d2b36SAndroid Build Coastguard Worker 44*333d2b36SAndroid Build Coastguard Worker soong_metrics_proto "android/soong/ui/metrics/metrics_proto" 45*333d2b36SAndroid Build Coastguard Worker mk_metrics_proto "android/soong/ui/metrics/mk_metrics_proto" 46*333d2b36SAndroid Build Coastguard Worker) 47*333d2b36SAndroid Build Coastguard Worker 48*333d2b36SAndroid Build Coastguard Workerconst ( 49*333d2b36SAndroid Build Coastguard Worker // Below is a list of names passed in to the Begin tracing functions. These 50*333d2b36SAndroid Build Coastguard Worker // names are used to group a set of metrics. 51*333d2b36SAndroid Build Coastguard Worker 52*333d2b36SAndroid Build Coastguard Worker // Setup and tear down of the build systems. 53*333d2b36SAndroid Build Coastguard Worker RunSetupTool = "setup" 54*333d2b36SAndroid Build Coastguard Worker RunShutdownTool = "shutdown" 55*333d2b36SAndroid Build Coastguard Worker TestRun = "test" 56*333d2b36SAndroid Build Coastguard Worker 57*333d2b36SAndroid Build Coastguard Worker // List of build system tools. 58*333d2b36SAndroid Build Coastguard Worker RunSoong = "soong" 59*333d2b36SAndroid Build Coastguard Worker PrimaryNinja = "ninja" 60*333d2b36SAndroid Build Coastguard Worker RunKati = "kati" 61*333d2b36SAndroid Build Coastguard Worker RunBazel = "bazel" 62*333d2b36SAndroid Build Coastguard Worker 63*333d2b36SAndroid Build Coastguard Worker // Overall build from building the graph to building the target. 64*333d2b36SAndroid Build Coastguard Worker Total = "total" 65*333d2b36SAndroid Build Coastguard Worker) 66*333d2b36SAndroid Build Coastguard Worker 67*333d2b36SAndroid Build Coastguard Worker// Metrics is a struct that stores collected metrics during the course of a 68*333d2b36SAndroid Build Coastguard Worker// build. It is later dumped to protobuf files. See underlying metrics protos 69*333d2b36SAndroid Build Coastguard Worker// for further details on what information is collected. 70*333d2b36SAndroid Build Coastguard Workertype Metrics struct { 71*333d2b36SAndroid Build Coastguard Worker // Protobuf containing various top-level build metrics. These include: 72*333d2b36SAndroid Build Coastguard Worker // 1. Build identifiers (ex: branch ID, requested product, hostname, 73*333d2b36SAndroid Build Coastguard Worker // originating command) 74*333d2b36SAndroid Build Coastguard Worker // 2. Per-subprocess top-level metrics (ex: ninja process IO and runtime). 75*333d2b36SAndroid Build Coastguard Worker // Note that, since these metrics are reported by soong_ui, there is little 76*333d2b36SAndroid Build Coastguard Worker // insight that can be provided into performance breakdowns of individual 77*333d2b36SAndroid Build Coastguard Worker // subprocesses. 78*333d2b36SAndroid Build Coastguard Worker metrics soong_metrics_proto.MetricsBase 79*333d2b36SAndroid Build Coastguard Worker 80*333d2b36SAndroid Build Coastguard Worker // Protobuf containing metrics pertaining to number of makefiles in a build. 81*333d2b36SAndroid Build Coastguard Worker mkMetrics mk_metrics_proto.MkMetrics 82*333d2b36SAndroid Build Coastguard Worker 83*333d2b36SAndroid Build Coastguard Worker // A list of pending build events. 84*333d2b36SAndroid Build Coastguard Worker EventTracer *EventTracer 85*333d2b36SAndroid Build Coastguard Worker} 86*333d2b36SAndroid Build Coastguard Worker 87*333d2b36SAndroid Build Coastguard Worker// New returns a pointer of Metrics to store a set of metrics. 88*333d2b36SAndroid Build Coastguard Workerfunc New() (metrics *Metrics) { 89*333d2b36SAndroid Build Coastguard Worker m := &Metrics{ 90*333d2b36SAndroid Build Coastguard Worker metrics: soong_metrics_proto.MetricsBase{}, 91*333d2b36SAndroid Build Coastguard Worker mkMetrics: mk_metrics_proto.MkMetrics{}, 92*333d2b36SAndroid Build Coastguard Worker EventTracer: &EventTracer{}, 93*333d2b36SAndroid Build Coastguard Worker } 94*333d2b36SAndroid Build Coastguard Worker return m 95*333d2b36SAndroid Build Coastguard Worker} 96*333d2b36SAndroid Build Coastguard Worker 97*333d2b36SAndroid Build Coastguard Workerfunc (m *Metrics) SetTotalMakefiles(total int) { 98*333d2b36SAndroid Build Coastguard Worker m.mkMetrics.TotalMakefiles = uint32(total) 99*333d2b36SAndroid Build Coastguard Worker} 100*333d2b36SAndroid Build Coastguard Worker 101*333d2b36SAndroid Build Coastguard Workerfunc (m *Metrics) SetToplevelMakefiles(total int) { 102*333d2b36SAndroid Build Coastguard Worker m.mkMetrics.ToplevelMakefiles = uint32(total) 103*333d2b36SAndroid Build Coastguard Worker} 104*333d2b36SAndroid Build Coastguard Worker 105*333d2b36SAndroid Build Coastguard Workerfunc (m *Metrics) DumpMkMetrics(outPath string) { 106*333d2b36SAndroid Build Coastguard Worker shared.Save(&m.mkMetrics, outPath) 107*333d2b36SAndroid Build Coastguard Worker} 108*333d2b36SAndroid Build Coastguard Worker 109*333d2b36SAndroid Build Coastguard Worker// SetTimeMetrics stores performance information from an executed block of 110*333d2b36SAndroid Build Coastguard Worker// code. 111*333d2b36SAndroid Build Coastguard Workerfunc (m *Metrics) SetTimeMetrics(perf soong_metrics_proto.PerfInfo) { 112*333d2b36SAndroid Build Coastguard Worker switch perf.GetName() { 113*333d2b36SAndroid Build Coastguard Worker case RunKati: 114*333d2b36SAndroid Build Coastguard Worker m.metrics.KatiRuns = append(m.metrics.KatiRuns, &perf) 115*333d2b36SAndroid Build Coastguard Worker case RunSoong: 116*333d2b36SAndroid Build Coastguard Worker m.metrics.SoongRuns = append(m.metrics.SoongRuns, &perf) 117*333d2b36SAndroid Build Coastguard Worker case RunBazel: 118*333d2b36SAndroid Build Coastguard Worker m.metrics.BazelRuns = append(m.metrics.BazelRuns, &perf) 119*333d2b36SAndroid Build Coastguard Worker case PrimaryNinja: 120*333d2b36SAndroid Build Coastguard Worker m.metrics.NinjaRuns = append(m.metrics.NinjaRuns, &perf) 121*333d2b36SAndroid Build Coastguard Worker case RunSetupTool: 122*333d2b36SAndroid Build Coastguard Worker m.metrics.SetupTools = append(m.metrics.SetupTools, &perf) 123*333d2b36SAndroid Build Coastguard Worker case Total: 124*333d2b36SAndroid Build Coastguard Worker m.metrics.Total = &perf 125*333d2b36SAndroid Build Coastguard Worker } 126*333d2b36SAndroid Build Coastguard Worker} 127*333d2b36SAndroid Build Coastguard Worker 128*333d2b36SAndroid Build Coastguard Workerfunc (m *Metrics) SetCriticalPathInfo(criticalPathInfo soong_metrics_proto.CriticalPathInfo) { 129*333d2b36SAndroid Build Coastguard Worker m.metrics.CriticalPathInfo = &criticalPathInfo 130*333d2b36SAndroid Build Coastguard Worker} 131*333d2b36SAndroid Build Coastguard Worker 132*333d2b36SAndroid Build Coastguard Worker// SetFatalOrPanicMessage stores a non-zero exit and the relevant message in the latest event if 133*333d2b36SAndroid Build Coastguard Worker// available or the metrics base. 134*333d2b36SAndroid Build Coastguard Workerfunc (m *Metrics) SetFatalOrPanicMessage(errMsg string) { 135*333d2b36SAndroid Build Coastguard Worker if m == nil { 136*333d2b36SAndroid Build Coastguard Worker return 137*333d2b36SAndroid Build Coastguard Worker } 138*333d2b36SAndroid Build Coastguard Worker if event := m.EventTracer.peek(); event != nil { 139*333d2b36SAndroid Build Coastguard Worker event.nonZeroExitCode = true 140*333d2b36SAndroid Build Coastguard Worker event.errorMsg = &errMsg 141*333d2b36SAndroid Build Coastguard Worker } else { 142*333d2b36SAndroid Build Coastguard Worker m.metrics.ErrorMessage = proto.String(errMsg) 143*333d2b36SAndroid Build Coastguard Worker } 144*333d2b36SAndroid Build Coastguard Worker m.metrics.NonZeroExit = proto.Bool(true) 145*333d2b36SAndroid Build Coastguard Worker} 146*333d2b36SAndroid Build Coastguard Worker 147*333d2b36SAndroid Build Coastguard Worker// BuildConfig stores information about the build configuration. 148*333d2b36SAndroid Build Coastguard Workerfunc (m *Metrics) BuildConfig(b *soong_metrics_proto.BuildConfig) { 149*333d2b36SAndroid Build Coastguard Worker m.metrics.BuildConfig = b 150*333d2b36SAndroid Build Coastguard Worker} 151*333d2b36SAndroid Build Coastguard Worker 152*333d2b36SAndroid Build Coastguard Worker// SystemResourceInfo stores information related to the host system such 153*333d2b36SAndroid Build Coastguard Worker// as total CPU and memory. 154*333d2b36SAndroid Build Coastguard Workerfunc (m *Metrics) SystemResourceInfo(b *soong_metrics_proto.SystemResourceInfo) { 155*333d2b36SAndroid Build Coastguard Worker m.metrics.SystemResourceInfo = b 156*333d2b36SAndroid Build Coastguard Worker} 157*333d2b36SAndroid Build Coastguard Worker 158*333d2b36SAndroid Build Coastguard Worker// ExpConfigFetcher stores information about the expconfigfetcher. 159*333d2b36SAndroid Build Coastguard Workerfunc (m *Metrics) ExpConfigFetcher(b *soong_metrics_proto.ExpConfigFetcher) { 160*333d2b36SAndroid Build Coastguard Worker m.metrics.ExpConfigFetcher = b 161*333d2b36SAndroid Build Coastguard Worker} 162*333d2b36SAndroid Build Coastguard Worker 163*333d2b36SAndroid Build Coastguard Worker// SetMetadataMetrics sets information about the build such as the target 164*333d2b36SAndroid Build Coastguard Worker// product, host architecture and out directory. 165*333d2b36SAndroid Build Coastguard Workerfunc (m *Metrics) SetMetadataMetrics(metadata map[string]string) { 166*333d2b36SAndroid Build Coastguard Worker for k, v := range metadata { 167*333d2b36SAndroid Build Coastguard Worker switch k { 168*333d2b36SAndroid Build Coastguard Worker case "BUILD_ID": 169*333d2b36SAndroid Build Coastguard Worker m.metrics.BuildId = proto.String(v) 170*333d2b36SAndroid Build Coastguard Worker case "PLATFORM_VERSION_CODENAME": 171*333d2b36SAndroid Build Coastguard Worker m.metrics.PlatformVersionCodename = proto.String(v) 172*333d2b36SAndroid Build Coastguard Worker case "TARGET_PRODUCT": 173*333d2b36SAndroid Build Coastguard Worker m.metrics.TargetProduct = proto.String(v) 174*333d2b36SAndroid Build Coastguard Worker case "TARGET_BUILD_VARIANT": 175*333d2b36SAndroid Build Coastguard Worker switch v { 176*333d2b36SAndroid Build Coastguard Worker case "user": 177*333d2b36SAndroid Build Coastguard Worker m.metrics.TargetBuildVariant = soong_metrics_proto.MetricsBase_USER.Enum() 178*333d2b36SAndroid Build Coastguard Worker case "userdebug": 179*333d2b36SAndroid Build Coastguard Worker m.metrics.TargetBuildVariant = soong_metrics_proto.MetricsBase_USERDEBUG.Enum() 180*333d2b36SAndroid Build Coastguard Worker case "eng": 181*333d2b36SAndroid Build Coastguard Worker m.metrics.TargetBuildVariant = soong_metrics_proto.MetricsBase_ENG.Enum() 182*333d2b36SAndroid Build Coastguard Worker } 183*333d2b36SAndroid Build Coastguard Worker case "TARGET_ARCH": 184*333d2b36SAndroid Build Coastguard Worker m.metrics.TargetArch = arch(v) 185*333d2b36SAndroid Build Coastguard Worker case "TARGET_ARCH_VARIANT": 186*333d2b36SAndroid Build Coastguard Worker m.metrics.TargetArchVariant = proto.String(v) 187*333d2b36SAndroid Build Coastguard Worker case "TARGET_CPU_VARIANT": 188*333d2b36SAndroid Build Coastguard Worker m.metrics.TargetCpuVariant = proto.String(v) 189*333d2b36SAndroid Build Coastguard Worker case "HOST_ARCH": 190*333d2b36SAndroid Build Coastguard Worker m.metrics.HostArch = arch(v) 191*333d2b36SAndroid Build Coastguard Worker case "HOST_2ND_ARCH": 192*333d2b36SAndroid Build Coastguard Worker m.metrics.Host_2NdArch = arch(v) 193*333d2b36SAndroid Build Coastguard Worker case "HOST_OS_EXTRA": 194*333d2b36SAndroid Build Coastguard Worker m.metrics.HostOsExtra = proto.String(v) 195*333d2b36SAndroid Build Coastguard Worker case "HOST_CROSS_OS": 196*333d2b36SAndroid Build Coastguard Worker m.metrics.HostCrossOs = proto.String(v) 197*333d2b36SAndroid Build Coastguard Worker case "HOST_CROSS_ARCH": 198*333d2b36SAndroid Build Coastguard Worker m.metrics.HostCrossArch = proto.String(v) 199*333d2b36SAndroid Build Coastguard Worker case "HOST_CROSS_2ND_ARCH": 200*333d2b36SAndroid Build Coastguard Worker m.metrics.HostCross_2NdArch = proto.String(v) 201*333d2b36SAndroid Build Coastguard Worker case "OUT_DIR": 202*333d2b36SAndroid Build Coastguard Worker m.metrics.OutDir = proto.String(v) 203*333d2b36SAndroid Build Coastguard Worker } 204*333d2b36SAndroid Build Coastguard Worker } 205*333d2b36SAndroid Build Coastguard Worker} 206*333d2b36SAndroid Build Coastguard Worker 207*333d2b36SAndroid Build Coastguard Worker// arch returns the corresponding MetricsBase_Arch based on the string 208*333d2b36SAndroid Build Coastguard Worker// parameter. 209*333d2b36SAndroid Build Coastguard Workerfunc arch(a string) *soong_metrics_proto.MetricsBase_Arch { 210*333d2b36SAndroid Build Coastguard Worker switch a { 211*333d2b36SAndroid Build Coastguard Worker case "arm": 212*333d2b36SAndroid Build Coastguard Worker return soong_metrics_proto.MetricsBase_ARM.Enum() 213*333d2b36SAndroid Build Coastguard Worker case "arm64": 214*333d2b36SAndroid Build Coastguard Worker return soong_metrics_proto.MetricsBase_ARM64.Enum() 215*333d2b36SAndroid Build Coastguard Worker case "x86": 216*333d2b36SAndroid Build Coastguard Worker return soong_metrics_proto.MetricsBase_X86.Enum() 217*333d2b36SAndroid Build Coastguard Worker case "x86_64": 218*333d2b36SAndroid Build Coastguard Worker return soong_metrics_proto.MetricsBase_X86_64.Enum() 219*333d2b36SAndroid Build Coastguard Worker default: 220*333d2b36SAndroid Build Coastguard Worker return soong_metrics_proto.MetricsBase_UNKNOWN.Enum() 221*333d2b36SAndroid Build Coastguard Worker } 222*333d2b36SAndroid Build Coastguard Worker} 223*333d2b36SAndroid Build Coastguard Worker 224*333d2b36SAndroid Build Coastguard Worker// SetBuildDateTime sets the build date and time. The value written 225*333d2b36SAndroid Build Coastguard Worker// to the protobuf file is in seconds. 226*333d2b36SAndroid Build Coastguard Workerfunc (m *Metrics) SetBuildDateTime(buildTimestamp time.Time) { 227*333d2b36SAndroid Build Coastguard Worker m.metrics.BuildDateTimestamp = proto.Int64(buildTimestamp.UnixNano() / int64(time.Second)) 228*333d2b36SAndroid Build Coastguard Worker} 229*333d2b36SAndroid Build Coastguard Worker 230*333d2b36SAndroid Build Coastguard Worker// SetBuildCommand adds the build command specified by the user to the 231*333d2b36SAndroid Build Coastguard Worker// list of collected metrics. 232*333d2b36SAndroid Build Coastguard Workerfunc (m *Metrics) SetBuildCommand(cmd []string) { 233*333d2b36SAndroid Build Coastguard Worker m.metrics.BuildCommand = proto.String(strings.Join(cmd, " ")) 234*333d2b36SAndroid Build Coastguard Worker} 235*333d2b36SAndroid Build Coastguard Worker 236*333d2b36SAndroid Build Coastguard Worker// AddChangedEnvironmentVariable adds the changed environment variable to 237*333d2b36SAndroid Build Coastguard Worker// ChangedEnvironmentVariable field. 238*333d2b36SAndroid Build Coastguard Workerfunc (m *Metrics) AddChangedEnvironmentVariable(ChangedEnvironmentVariable string) { 239*333d2b36SAndroid Build Coastguard Worker m.metrics.ChangedEnvironmentVariable = append(m.metrics.ChangedEnvironmentVariable, 240*333d2b36SAndroid Build Coastguard Worker ChangedEnvironmentVariable) 241*333d2b36SAndroid Build Coastguard Worker} 242*333d2b36SAndroid Build Coastguard Worker 243*333d2b36SAndroid Build Coastguard Worker// Dump exports the collected metrics from the executed build to the file at 244*333d2b36SAndroid Build Coastguard Worker// out path. 245*333d2b36SAndroid Build Coastguard Workerfunc (m *Metrics) Dump(out string) error { 246*333d2b36SAndroid Build Coastguard Worker // ignore the error if the hostname could not be retrieved as it 247*333d2b36SAndroid Build Coastguard Worker // is not a critical metric to extract. 248*333d2b36SAndroid Build Coastguard Worker if hostname, err := os.Hostname(); err == nil { 249*333d2b36SAndroid Build Coastguard Worker m.metrics.Hostname = proto.String(hostname) 250*333d2b36SAndroid Build Coastguard Worker } 251*333d2b36SAndroid Build Coastguard Worker m.metrics.HostOs = proto.String(runtime.GOOS) 252*333d2b36SAndroid Build Coastguard Worker 253*333d2b36SAndroid Build Coastguard Worker return shared.Save(&m.metrics, out) 254*333d2b36SAndroid Build Coastguard Worker} 255*333d2b36SAndroid Build Coastguard Worker 256*333d2b36SAndroid Build Coastguard Worker// SetSoongBuildMetrics sets the metrics collected from the soong_build 257*333d2b36SAndroid Build Coastguard Worker// execution. 258*333d2b36SAndroid Build Coastguard Workerfunc (m *Metrics) SetSoongBuildMetrics(metrics *soong_metrics_proto.SoongBuildMetrics) { 259*333d2b36SAndroid Build Coastguard Worker m.metrics.SoongBuildMetrics = metrics 260*333d2b36SAndroid Build Coastguard Worker} 261*333d2b36SAndroid Build Coastguard Worker 262*333d2b36SAndroid Build Coastguard Worker// A CriticalUserJourneysMetrics is a struct that contains critical user journey 263*333d2b36SAndroid Build Coastguard Worker// metrics. These critical user journeys are defined under cuj/cuj.go file. 264*333d2b36SAndroid Build Coastguard Workertype CriticalUserJourneysMetrics struct { 265*333d2b36SAndroid Build Coastguard Worker // A list of collected CUJ metrics. 266*333d2b36SAndroid Build Coastguard Worker cujs soong_metrics_proto.CriticalUserJourneysMetrics 267*333d2b36SAndroid Build Coastguard Worker} 268*333d2b36SAndroid Build Coastguard Worker 269*333d2b36SAndroid Build Coastguard Worker// NewCriticalUserJourneyMetrics returns a pointer of CriticalUserJourneyMetrics 270*333d2b36SAndroid Build Coastguard Worker// to capture CUJs metrics. 271*333d2b36SAndroid Build Coastguard Workerfunc NewCriticalUserJourneysMetrics() *CriticalUserJourneysMetrics { 272*333d2b36SAndroid Build Coastguard Worker return &CriticalUserJourneysMetrics{} 273*333d2b36SAndroid Build Coastguard Worker} 274*333d2b36SAndroid Build Coastguard Worker 275*333d2b36SAndroid Build Coastguard Worker// Add adds a set of collected metrics from an executed critical user journey. 276*333d2b36SAndroid Build Coastguard Workerfunc (c *CriticalUserJourneysMetrics) Add(name string, metrics *Metrics) { 277*333d2b36SAndroid Build Coastguard Worker c.cujs.Cujs = append(c.cujs.Cujs, &soong_metrics_proto.CriticalUserJourneyMetrics{ 278*333d2b36SAndroid Build Coastguard Worker Name: proto.String(name), 279*333d2b36SAndroid Build Coastguard Worker Metrics: &metrics.metrics, 280*333d2b36SAndroid Build Coastguard Worker }) 281*333d2b36SAndroid Build Coastguard Worker} 282*333d2b36SAndroid Build Coastguard Worker 283*333d2b36SAndroid Build Coastguard Worker// Dump saves the collected CUJs metrics to the raw protobuf file. 284*333d2b36SAndroid Build Coastguard Workerfunc (c *CriticalUserJourneysMetrics) Dump(filename string) (err error) { 285*333d2b36SAndroid Build Coastguard Worker return shared.Save(&c.cujs, filename) 286*333d2b36SAndroid Build Coastguard Worker} 287