blob: 3d41a1d6cb7e9c76545fb61a416b7aff53cfa517 [file] [log] [blame]
Colin Crossb72c9092020-02-10 11:23:49 -08001// 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"
MarkDacekff851b82022-04-21 18:33:17 +000020 "sort"
Colin Crossb72c9092020-02-10 11:23:49 -080021
Chris Parsons715b08f2022-03-22 19:23:40 -040022 "github.com/google/blueprint/metrics"
Dan Willemsen4591b642021-05-24 14:24:12 -070023 "google.golang.org/protobuf/proto"
Colin Crossb72c9092020-02-10 11:23:49 -080024
25 soong_metrics_proto "android/soong/ui/metrics/metrics_proto"
26)
27
28var soongMetricsOnceKey = NewOnceKey("soong metrics")
29
30type SoongMetrics struct {
31 Modules int
32 Variants int
33}
34
Joe Onorato2e5e4012022-06-07 17:16:08 -070035func 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 Crossb72c9092020-02-10 11:23:49 -080042}
43
44func init() {
45 RegisterSingletonType("soong_metrics", soongMetricsSingletonFactory)
46}
47
48func soongMetricsSingletonFactory() Singleton { return soongMetricsSingleton{} }
49
50type soongMetricsSingleton struct{}
51
52func (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 Duffin780a1852022-11-05 10:17:12 +000065func collectMetrics(config Config, eventHandler *metrics.EventHandler) *soong_metrics_proto.SoongBuildMetrics {
Colin Crossb72c9092020-02-10 11:23:49 -080066 metrics := &soong_metrics_proto.SoongBuildMetrics{}
67
Joe Onorato2e5e4012022-06-07 17:16:08 -070068 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 Crossb72c9092020-02-10 11:23:49 -080073
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 Parsons715b08f2022-03-22 19:23:40 -040080 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 }
MarkDacekff851b82022-04-21 18:33:17 +000089 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 Parsons715b08f2022-03-22 19:23:40 -0400106
Colin Crossb72c9092020-02-10 11:23:49 -0800107 return metrics
108}
109
Paul Duffin780a1852022-11-05 10:17:12 +0000110func WriteMetrics(config Config, eventHandler *metrics.EventHandler, metricsFile string) error {
Chris Parsons715b08f2022-03-22 19:23:40 -0400111 metrics := collectMetrics(config, eventHandler)
Colin Crossb72c9092020-02-10 11:23:49 -0800112
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}