1// Copyright 2020 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 android 16 17import ( 18 "io/ioutil" 19 "runtime" 20 21 "github.com/google/blueprint/metrics" 22 "google.golang.org/protobuf/proto" 23 24 soong_metrics_proto "android/soong/ui/metrics/metrics_proto" 25) 26 27var soongMetricsOnceKey = NewOnceKey("soong metrics") 28 29type SoongMetrics struct { 30 Modules int 31 Variants int 32} 33 34func ReadSoongMetrics(config Config) SoongMetrics { 35 return config.Get(soongMetricsOnceKey).(SoongMetrics) 36} 37 38func init() { 39 RegisterSingletonType("soong_metrics", soongMetricsSingletonFactory) 40} 41 42func soongMetricsSingletonFactory() Singleton { return soongMetricsSingleton{} } 43 44type soongMetricsSingleton struct{} 45 46func (soongMetricsSingleton) GenerateBuildActions(ctx SingletonContext) { 47 metrics := SoongMetrics{} 48 ctx.VisitAllModules(func(m Module) { 49 if ctx.PrimaryModule(m) == m { 50 metrics.Modules++ 51 } 52 metrics.Variants++ 53 }) 54 ctx.Config().Once(soongMetricsOnceKey, func() interface{} { 55 return metrics 56 }) 57} 58 59func collectMetrics(config Config, eventHandler metrics.EventHandler) *soong_metrics_proto.SoongBuildMetrics { 60 metrics := &soong_metrics_proto.SoongBuildMetrics{} 61 62 soongMetrics := ReadSoongMetrics(config) 63 metrics.Modules = proto.Uint32(uint32(soongMetrics.Modules)) 64 metrics.Variants = proto.Uint32(uint32(soongMetrics.Variants)) 65 66 memStats := runtime.MemStats{} 67 runtime.ReadMemStats(&memStats) 68 metrics.MaxHeapSize = proto.Uint64(memStats.HeapSys) 69 metrics.TotalAllocCount = proto.Uint64(memStats.Mallocs) 70 metrics.TotalAllocSize = proto.Uint64(memStats.TotalAlloc) 71 72 for _, event := range eventHandler.CompletedEvents() { 73 perfInfo := soong_metrics_proto.PerfInfo{ 74 Description: proto.String(event.Id), 75 Name: proto.String("soong_build"), 76 StartTime: proto.Uint64(uint64(event.Start.UnixNano())), 77 RealTime: proto.Uint64(event.RuntimeNanoseconds()), 78 } 79 metrics.Events = append(metrics.Events, &perfInfo) 80 } 81 82 return metrics 83} 84 85func WriteMetrics(config Config, eventHandler metrics.EventHandler, metricsFile string) error { 86 metrics := collectMetrics(config, eventHandler) 87 88 buf, err := proto.Marshal(metrics) 89 if err != nil { 90 return err 91 } 92 err = ioutil.WriteFile(absolutePath(metricsFile), buf, 0666) 93 if err != nil { 94 return err 95 } 96 97 return nil 98} 99