| Colin Cross | b72c909 | 2020-02-10 11:23:49 -0800 | [diff] [blame] | 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 |  | 
|  | 15 | package android | 
|  | 16 |  | 
|  | 17 | import ( | 
|  | 18 | "io/ioutil" | 
|  | 19 | "runtime" | 
| MarkDacek | ff851b8 | 2022-04-21 18:33:17 +0000 | [diff] [blame] | 20 | "sort" | 
| Colin Cross | b72c909 | 2020-02-10 11:23:49 -0800 | [diff] [blame] | 21 |  | 
| Chris Parsons | 715b08f | 2022-03-22 19:23:40 -0400 | [diff] [blame] | 22 | "github.com/google/blueprint/metrics" | 
| Dan Willemsen | 4591b64 | 2021-05-24 14:24:12 -0700 | [diff] [blame] | 23 | "google.golang.org/protobuf/proto" | 
| Colin Cross | b72c909 | 2020-02-10 11:23:49 -0800 | [diff] [blame] | 24 |  | 
|  | 25 | soong_metrics_proto "android/soong/ui/metrics/metrics_proto" | 
|  | 26 | ) | 
|  | 27 |  | 
|  | 28 | var soongMetricsOnceKey = NewOnceKey("soong metrics") | 
|  | 29 |  | 
|  | 30 | type SoongMetrics struct { | 
|  | 31 | Modules  int | 
|  | 32 | Variants int | 
|  | 33 | } | 
|  | 34 |  | 
| Joe Onorato | 2e5e401 | 2022-06-07 17:16:08 -0700 | [diff] [blame] | 35 | func readSoongMetrics(config Config) (SoongMetrics, bool) { | 
|  | 36 | soongMetrics, ok := config.Peek(soongMetricsOnceKey) | 
|  | 37 | if ok { | 
|  | 38 | return soongMetrics.(SoongMetrics), true | 
|  | 39 | } else { | 
|  | 40 | return SoongMetrics{}, false | 
|  | 41 | } | 
| Colin Cross | b72c909 | 2020-02-10 11:23:49 -0800 | [diff] [blame] | 42 | } | 
|  | 43 |  | 
|  | 44 | func init() { | 
| LaMont Jones | 0c10e4d | 2023-05-16 00:58:37 +0000 | [diff] [blame] | 45 | RegisterParallelSingletonType("soong_metrics", soongMetricsSingletonFactory) | 
| Colin Cross | b72c909 | 2020-02-10 11:23:49 -0800 | [diff] [blame] | 46 | } | 
|  | 47 |  | 
|  | 48 | func soongMetricsSingletonFactory() Singleton { return soongMetricsSingleton{} } | 
|  | 49 |  | 
|  | 50 | type soongMetricsSingleton struct{} | 
|  | 51 |  | 
|  | 52 | func (soongMetricsSingleton) GenerateBuildActions(ctx SingletonContext) { | 
|  | 53 | metrics := SoongMetrics{} | 
|  | 54 | ctx.VisitAllModules(func(m Module) { | 
|  | 55 | if ctx.PrimaryModule(m) == m { | 
|  | 56 | metrics.Modules++ | 
|  | 57 | } | 
|  | 58 | metrics.Variants++ | 
|  | 59 | }) | 
|  | 60 | ctx.Config().Once(soongMetricsOnceKey, func() interface{} { | 
|  | 61 | return metrics | 
|  | 62 | }) | 
|  | 63 | } | 
|  | 64 |  | 
| Paul Duffin | 780a185 | 2022-11-05 10:17:12 +0000 | [diff] [blame] | 65 | func collectMetrics(config Config, eventHandler *metrics.EventHandler) *soong_metrics_proto.SoongBuildMetrics { | 
| Colin Cross | b72c909 | 2020-02-10 11:23:49 -0800 | [diff] [blame] | 66 | metrics := &soong_metrics_proto.SoongBuildMetrics{} | 
|  | 67 |  | 
| Joe Onorato | 2e5e401 | 2022-06-07 17:16:08 -0700 | [diff] [blame] | 68 | soongMetrics, ok := readSoongMetrics(config) | 
|  | 69 | if ok { | 
|  | 70 | metrics.Modules = proto.Uint32(uint32(soongMetrics.Modules)) | 
|  | 71 | metrics.Variants = proto.Uint32(uint32(soongMetrics.Variants)) | 
|  | 72 | } | 
| Colin Cross | b72c909 | 2020-02-10 11:23:49 -0800 | [diff] [blame] | 73 |  | 
|  | 74 | memStats := runtime.MemStats{} | 
|  | 75 | runtime.ReadMemStats(&memStats) | 
|  | 76 | metrics.MaxHeapSize = proto.Uint64(memStats.HeapSys) | 
|  | 77 | metrics.TotalAllocCount = proto.Uint64(memStats.Mallocs) | 
|  | 78 | metrics.TotalAllocSize = proto.Uint64(memStats.TotalAlloc) | 
|  | 79 |  | 
| Chris Parsons | 715b08f | 2022-03-22 19:23:40 -0400 | [diff] [blame] | 80 | for _, event := range eventHandler.CompletedEvents() { | 
|  | 81 | perfInfo := soong_metrics_proto.PerfInfo{ | 
|  | 82 | Description: proto.String(event.Id), | 
|  | 83 | Name:        proto.String("soong_build"), | 
|  | 84 | StartTime:   proto.Uint64(uint64(event.Start.UnixNano())), | 
|  | 85 | RealTime:    proto.Uint64(event.RuntimeNanoseconds()), | 
|  | 86 | } | 
|  | 87 | metrics.Events = append(metrics.Events, &perfInfo) | 
|  | 88 | } | 
| MarkDacek | ff851b8 | 2022-04-21 18:33:17 +0000 | [diff] [blame] | 89 | mixedBuildsInfo := soong_metrics_proto.MixedBuildsInfo{} | 
|  | 90 | mixedBuildEnabledModules := make([]string, 0, len(config.mixedBuildEnabledModules)) | 
|  | 91 | for module, _ := range config.mixedBuildEnabledModules { | 
|  | 92 | mixedBuildEnabledModules = append(mixedBuildEnabledModules, module) | 
|  | 93 | } | 
|  | 94 |  | 
|  | 95 | mixedBuildDisabledModules := make([]string, 0, len(config.mixedBuildDisabledModules)) | 
|  | 96 | for module, _ := range config.mixedBuildDisabledModules { | 
|  | 97 | mixedBuildDisabledModules = append(mixedBuildDisabledModules, module) | 
|  | 98 | } | 
|  | 99 | // Sorted for deterministic output. | 
|  | 100 | sort.Strings(mixedBuildEnabledModules) | 
|  | 101 | sort.Strings(mixedBuildDisabledModules) | 
|  | 102 |  | 
|  | 103 | mixedBuildsInfo.MixedBuildEnabledModules = mixedBuildEnabledModules | 
|  | 104 | mixedBuildsInfo.MixedBuildDisabledModules = mixedBuildDisabledModules | 
|  | 105 | metrics.MixedBuildsInfo = &mixedBuildsInfo | 
| Chris Parsons | 715b08f | 2022-03-22 19:23:40 -0400 | [diff] [blame] | 106 |  | 
| Colin Cross | b72c909 | 2020-02-10 11:23:49 -0800 | [diff] [blame] | 107 | return metrics | 
|  | 108 | } | 
|  | 109 |  | 
| Paul Duffin | 780a185 | 2022-11-05 10:17:12 +0000 | [diff] [blame] | 110 | func WriteMetrics(config Config, eventHandler *metrics.EventHandler, metricsFile string) error { | 
| Chris Parsons | 715b08f | 2022-03-22 19:23:40 -0400 | [diff] [blame] | 111 | metrics := collectMetrics(config, eventHandler) | 
| Colin Cross | b72c909 | 2020-02-10 11:23:49 -0800 | [diff] [blame] | 112 |  | 
|  | 113 | buf, err := proto.Marshal(metrics) | 
|  | 114 | if err != nil { | 
|  | 115 | return err | 
|  | 116 | } | 
|  | 117 | err = ioutil.WriteFile(absolutePath(metricsFile), buf, 0666) | 
|  | 118 | if err != nil { | 
|  | 119 | return err | 
|  | 120 | } | 
|  | 121 |  | 
|  | 122 | return nil | 
|  | 123 | } |