1// Copyright 2018 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package metrics 16 17import ( 18 "io/ioutil" 19 "os" 20 "strconv" 21 22 "android/soong/ui/metrics/metrics_proto" 23 24 "github.com/golang/protobuf/proto" 25) 26 27const ( 28 RunSetupTool = "setup" 29 RunKati = "kati" 30 RunSoong = "soong" 31 PrimaryNinja = "ninja" 32 TestRun = "test" 33) 34 35type Metrics struct { 36 metrics metrics_proto.MetricsBase 37 TimeTracer TimeTracer 38} 39 40func New() (metrics *Metrics) { 41 m := &Metrics{ 42 metrics: metrics_proto.MetricsBase{}, 43 TimeTracer: &timeTracerImpl{}, 44 } 45 return m 46} 47 48func (m *Metrics) SetTimeMetrics(perf metrics_proto.PerfInfo) { 49 switch perf.GetName() { 50 case RunKati: 51 m.metrics.KatiRuns = append(m.metrics.KatiRuns, &perf) 52 break 53 case RunSoong: 54 m.metrics.SoongRuns = append(m.metrics.SoongRuns, &perf) 55 break 56 case PrimaryNinja: 57 m.metrics.NinjaRuns = append(m.metrics.NinjaRuns, &perf) 58 break 59 default: 60 // ignored 61 } 62} 63 64func (m *Metrics) SetMetadataMetrics(metadata map[string]string) { 65 for k, v := range metadata { 66 switch k { 67 case "BUILD_ID": 68 m.metrics.BuildId = proto.String(v) 69 break 70 case "PLATFORM_VERSION_CODENAME": 71 m.metrics.PlatformVersionCodename = proto.String(v) 72 break 73 case "TARGET_PRODUCT": 74 m.metrics.TargetProduct = proto.String(v) 75 break 76 case "TARGET_BUILD_VARIANT": 77 switch v { 78 case "user": 79 m.metrics.TargetBuildVariant = metrics_proto.MetricsBase_USER.Enum() 80 case "userdebug": 81 m.metrics.TargetBuildVariant = metrics_proto.MetricsBase_USERDEBUG.Enum() 82 case "eng": 83 m.metrics.TargetBuildVariant = metrics_proto.MetricsBase_ENG.Enum() 84 default: 85 // ignored 86 } 87 case "TARGET_ARCH": 88 m.metrics.TargetArch = m.getArch(v) 89 case "TARGET_ARCH_VARIANT": 90 m.metrics.TargetArchVariant = proto.String(v) 91 case "TARGET_CPU_VARIANT": 92 m.metrics.TargetCpuVariant = proto.String(v) 93 case "HOST_ARCH": 94 m.metrics.HostArch = m.getArch(v) 95 case "HOST_2ND_ARCH": 96 m.metrics.Host_2NdArch = m.getArch(v) 97 case "HOST_OS": 98 m.metrics.HostOs = proto.String(v) 99 case "HOST_OS_EXTRA": 100 m.metrics.HostOsExtra = proto.String(v) 101 case "HOST_CROSS_OS": 102 m.metrics.HostCrossOs = proto.String(v) 103 case "HOST_CROSS_ARCH": 104 m.metrics.HostCrossArch = proto.String(v) 105 case "HOST_CROSS_2ND_ARCH": 106 m.metrics.HostCross_2NdArch = proto.String(v) 107 case "OUT_DIR": 108 m.metrics.OutDir = proto.String(v) 109 default: 110 // ignored 111 } 112 } 113} 114 115func (m *Metrics) getArch(arch string) *metrics_proto.MetricsBase_ARCH { 116 switch arch { 117 case "arm": 118 return metrics_proto.MetricsBase_ARM.Enum() 119 case "arm64": 120 return metrics_proto.MetricsBase_ARM64.Enum() 121 case "x86": 122 return metrics_proto.MetricsBase_X86.Enum() 123 case "x86_64": 124 return metrics_proto.MetricsBase_X86_64.Enum() 125 default: 126 return metrics_proto.MetricsBase_UNKNOWN.Enum() 127 } 128} 129 130func (m *Metrics) SetBuildDateTime(date_time string) { 131 if date_time != "" { 132 date_time_timestamp, err := strconv.ParseInt(date_time, 10, 64) 133 if err != nil { 134 panic(err) 135 } 136 m.metrics.BuildDateTimestamp = &date_time_timestamp 137 } 138} 139 140func (m *Metrics) Serialize() (data []byte, err error) { 141 return proto.Marshal(&m.metrics) 142} 143 144// exports the output to the file at outputPath 145func (m *Metrics) Dump(outputPath string) (err error) { 146 data, err := m.Serialize() 147 if err != nil { 148 return err 149 } 150 tempPath := outputPath + ".tmp" 151 err = ioutil.WriteFile(tempPath, []byte(data), 0777) 152 if err != nil { 153 return err 154 } 155 err = os.Rename(tempPath, outputPath) 156 if err != nil { 157 return err 158 } 159 160 return nil 161} 162