xref: /aosp_15_r20/art/odrefresh/odr_metrics.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2021 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_ODREFRESH_ODR_METRICS_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_ODREFRESH_ODR_METRICS_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include <chrono>
21*795d594fSAndroid Build Coastguard Worker #include <cstdint>
22*795d594fSAndroid Build Coastguard Worker #include <iosfwd>
23*795d594fSAndroid Build Coastguard Worker #include <optional>
24*795d594fSAndroid Build Coastguard Worker #include <string>
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
27*795d594fSAndroid Build Coastguard Worker #include "exec_utils.h"
28*795d594fSAndroid Build Coastguard Worker #include "odr_metrics_record.h"
29*795d594fSAndroid Build Coastguard Worker 
30*795d594fSAndroid Build Coastguard Worker namespace art {
31*795d594fSAndroid Build Coastguard Worker namespace odrefresh {
32*795d594fSAndroid Build Coastguard Worker 
33*795d594fSAndroid Build Coastguard Worker class OdrMetrics final {
34*795d594fSAndroid Build Coastguard Worker  public:
35*795d594fSAndroid Build Coastguard Worker   // Enumeration used to track the latest stage reached running odrefresh.
36*795d594fSAndroid Build Coastguard Worker   //
37*795d594fSAndroid Build Coastguard Worker   // These values mirror those in OdrefreshReported::Stage in
38*795d594fSAndroid Build Coastguard Worker   // frameworks/proto_logging/atoms/art/odrefresh_extension_atoms.proto.
39*795d594fSAndroid Build Coastguard Worker   // NB There are gaps between the values in case an additional stages are introduced.
40*795d594fSAndroid Build Coastguard Worker   enum class Stage : uint8_t {
41*795d594fSAndroid Build Coastguard Worker     kUnknown = 0,
42*795d594fSAndroid Build Coastguard Worker     kCheck = 10,
43*795d594fSAndroid Build Coastguard Worker     kPreparation = 20,
44*795d594fSAndroid Build Coastguard Worker     kPrimaryBootClasspath = 30,
45*795d594fSAndroid Build Coastguard Worker     kSecondaryBootClasspath = 40,
46*795d594fSAndroid Build Coastguard Worker     kSystemServerClasspath = 50,
47*795d594fSAndroid Build Coastguard Worker     kComplete = 60,
48*795d594fSAndroid Build Coastguard Worker   };
49*795d594fSAndroid Build Coastguard Worker 
50*795d594fSAndroid Build Coastguard Worker   // Enumeration describing the overall status, processing stops on the first error discovered.
51*795d594fSAndroid Build Coastguard Worker   //
52*795d594fSAndroid Build Coastguard Worker   // These values mirror those in OdrefreshReported::Status in
53*795d594fSAndroid Build Coastguard Worker   // frameworks/proto_logging/atoms/art/odrefresh_extension_atoms.proto.
54*795d594fSAndroid Build Coastguard Worker   enum class Status : uint8_t {
55*795d594fSAndroid Build Coastguard Worker     kUnknown = 0,
56*795d594fSAndroid Build Coastguard Worker     kOK = 1,
57*795d594fSAndroid Build Coastguard Worker     kNoSpace = 2,
58*795d594fSAndroid Build Coastguard Worker     kIoError = 3,
59*795d594fSAndroid Build Coastguard Worker     kDex2OatError = 4,
60*795d594fSAndroid Build Coastguard Worker     // Value 5 was kTimeLimitExceeded, but has been removed in favour of
61*795d594fSAndroid Build Coastguard Worker     // reporting the exit code for Dex2Oat (set to ExecResult::kTimedOut)
62*795d594fSAndroid Build Coastguard Worker     kStagingFailed = 6,
63*795d594fSAndroid Build Coastguard Worker     kInstallFailed = 7,
64*795d594fSAndroid Build Coastguard Worker     // Failed to access the dalvik-cache directory due to lack of permission.
65*795d594fSAndroid Build Coastguard Worker     kDalvikCachePermissionDenied = 8,
66*795d594fSAndroid Build Coastguard Worker   };
67*795d594fSAndroid Build Coastguard Worker 
68*795d594fSAndroid Build Coastguard Worker   // Enumeration describing the cause of compilation (if any) in odrefresh.
69*795d594fSAndroid Build Coastguard Worker   //
70*795d594fSAndroid Build Coastguard Worker   // These values mirror those in OdrefreshReported::Trigger in
71*795d594fSAndroid Build Coastguard Worker   // frameworks/proto_logging/atoms/art/odrefresh_extension_atoms.proto.
72*795d594fSAndroid Build Coastguard Worker   enum class Trigger : uint8_t {
73*795d594fSAndroid Build Coastguard Worker     kUnknown = 0,
74*795d594fSAndroid Build Coastguard Worker     kApexVersionMismatch = 1,
75*795d594fSAndroid Build Coastguard Worker     kDexFilesChanged = 2,
76*795d594fSAndroid Build Coastguard Worker     kMissingArtifacts = 3,
77*795d594fSAndroid Build Coastguard Worker   };
78*795d594fSAndroid Build Coastguard Worker 
79*795d594fSAndroid Build Coastguard Worker   // Enumeration describing the type of boot classpath compilation in odrefresh.
80*795d594fSAndroid Build Coastguard Worker   //
81*795d594fSAndroid Build Coastguard Worker   // These values mirror those in OdrefreshReported::BcpCompilationType in
82*795d594fSAndroid Build Coastguard Worker   // frameworks/proto_logging/atoms/art/odrefresh_extension_atoms.proto.
83*795d594fSAndroid Build Coastguard Worker   enum class BcpCompilationType : uint8_t {
84*795d594fSAndroid Build Coastguard Worker     kUnknown = 0,
85*795d594fSAndroid Build Coastguard Worker     // Compiles for both the primary boot image and the mainline extension.
86*795d594fSAndroid Build Coastguard Worker     kPrimaryAndMainline = 1,
87*795d594fSAndroid Build Coastguard Worker     // Only compiles for the mainline extension.
88*795d594fSAndroid Build Coastguard Worker     kMainline = 2,
89*795d594fSAndroid Build Coastguard Worker   };
90*795d594fSAndroid Build Coastguard Worker 
91*795d594fSAndroid Build Coastguard Worker   explicit OdrMetrics(const std::string& cache_directory,
92*795d594fSAndroid Build Coastguard Worker                       const std::string& metrics_file = kOdrefreshMetricsFile);
93*795d594fSAndroid Build Coastguard Worker   ~OdrMetrics();
94*795d594fSAndroid Build Coastguard Worker 
95*795d594fSAndroid Build Coastguard Worker   // Enables/disables metrics writing.
SetEnabled(bool value)96*795d594fSAndroid Build Coastguard Worker   void SetEnabled(bool value) { enabled_ = value; }
97*795d594fSAndroid Build Coastguard Worker 
98*795d594fSAndroid Build Coastguard Worker   // Gets the ART APEX that metrics are being collected on behalf of.
GetArtApexVersion()99*795d594fSAndroid Build Coastguard Worker   int64_t GetArtApexVersion() const { return art_apex_version_; }
100*795d594fSAndroid Build Coastguard Worker 
101*795d594fSAndroid Build Coastguard Worker   // Sets the ART APEX that metrics are being collected on behalf of.
SetArtApexVersion(int64_t version)102*795d594fSAndroid Build Coastguard Worker   void SetArtApexVersion(int64_t version) { art_apex_version_ = version; }
103*795d594fSAndroid Build Coastguard Worker 
104*795d594fSAndroid Build Coastguard Worker   // Gets the ART APEX last update time in milliseconds.
GetArtApexLastUpdateMillis()105*795d594fSAndroid Build Coastguard Worker   int64_t GetArtApexLastUpdateMillis() const { return art_apex_last_update_millis_; }
106*795d594fSAndroid Build Coastguard Worker 
107*795d594fSAndroid Build Coastguard Worker   // Sets the ART APEX last update time in milliseconds.
SetArtApexLastUpdateMillis(int64_t last_update_millis)108*795d594fSAndroid Build Coastguard Worker   void SetArtApexLastUpdateMillis(int64_t last_update_millis) {
109*795d594fSAndroid Build Coastguard Worker     art_apex_last_update_millis_ = last_update_millis;
110*795d594fSAndroid Build Coastguard Worker   }
111*795d594fSAndroid Build Coastguard Worker 
112*795d594fSAndroid Build Coastguard Worker   // Gets the trigger for metrics collection. The trigger is the reason why odrefresh considers
113*795d594fSAndroid Build Coastguard Worker   // compilation necessary.
GetTrigger()114*795d594fSAndroid Build Coastguard Worker   Trigger GetTrigger() const { return trigger_; }
115*795d594fSAndroid Build Coastguard Worker 
116*795d594fSAndroid Build Coastguard Worker   // Sets the trigger for metrics collection. The trigger is the reason why odrefresh considers
117*795d594fSAndroid Build Coastguard Worker   // compilation necessary. Only call this method if compilation is necessary as the presence
118*795d594fSAndroid Build Coastguard Worker   // of a trigger means we will try to record and upload metrics.
SetTrigger(const Trigger trigger)119*795d594fSAndroid Build Coastguard Worker   void SetTrigger(const Trigger trigger) { trigger_ = trigger; }
120*795d594fSAndroid Build Coastguard Worker 
121*795d594fSAndroid Build Coastguard Worker   // Sets the execution status of the current odrefresh processing stage.
SetStatus(const Status status)122*795d594fSAndroid Build Coastguard Worker   void SetStatus(const Status status) { status_ = status; }
123*795d594fSAndroid Build Coastguard Worker 
124*795d594fSAndroid Build Coastguard Worker   // Sets the current odrefresh processing stage.
SetStage(Stage stage)125*795d594fSAndroid Build Coastguard Worker   void SetStage(Stage stage) { stage_ = stage; }
126*795d594fSAndroid Build Coastguard Worker 
127*795d594fSAndroid Build Coastguard Worker   // Sets the result of the current dex2oat invocation.
128*795d594fSAndroid Build Coastguard Worker   void SetDex2OatResult(Stage stage,
129*795d594fSAndroid Build Coastguard Worker                         int64_t compilation_time,
130*795d594fSAndroid Build Coastguard Worker                         const std::optional<ExecResult>& dex2oat_result);
131*795d594fSAndroid Build Coastguard Worker 
132*795d594fSAndroid Build Coastguard Worker   // Sets the BCP compilation type.
133*795d594fSAndroid Build Coastguard Worker   void SetBcpCompilationType(Stage stage, BcpCompilationType type);
134*795d594fSAndroid Build Coastguard Worker 
135*795d594fSAndroid Build Coastguard Worker   // Captures the current free space as the end free space.
136*795d594fSAndroid Build Coastguard Worker   void CaptureSpaceFreeEnd();
137*795d594fSAndroid Build Coastguard Worker 
138*795d594fSAndroid Build Coastguard Worker   // Records metrics into an OdrMetricsRecord.
139*795d594fSAndroid Build Coastguard Worker   OdrMetricsRecord ToRecord() const;
140*795d594fSAndroid Build Coastguard Worker 
141*795d594fSAndroid Build Coastguard Worker  private:
142*795d594fSAndroid Build Coastguard Worker   OdrMetrics(const OdrMetrics&) = delete;
143*795d594fSAndroid Build Coastguard Worker   OdrMetrics operator=(const OdrMetrics&) = delete;
144*795d594fSAndroid Build Coastguard Worker 
145*795d594fSAndroid Build Coastguard Worker   static int32_t GetFreeSpaceMiB(const std::string& path);
146*795d594fSAndroid Build Coastguard Worker   static void WriteToFile(const std::string& path, const OdrMetrics* metrics);
147*795d594fSAndroid Build Coastguard Worker 
148*795d594fSAndroid Build Coastguard Worker   static OdrMetricsRecord::Dex2OatExecResult
149*795d594fSAndroid Build Coastguard Worker   ConvertExecResult(const std::optional<ExecResult>& result);
150*795d594fSAndroid Build Coastguard Worker 
151*795d594fSAndroid Build Coastguard Worker   const std::string cache_directory_;
152*795d594fSAndroid Build Coastguard Worker   const std::string metrics_file_;
153*795d594fSAndroid Build Coastguard Worker 
154*795d594fSAndroid Build Coastguard Worker   bool enabled_ = false;
155*795d594fSAndroid Build Coastguard Worker 
156*795d594fSAndroid Build Coastguard Worker   int64_t art_apex_version_ = 0;
157*795d594fSAndroid Build Coastguard Worker   int64_t art_apex_last_update_millis_ = 0;
158*795d594fSAndroid Build Coastguard Worker   Trigger trigger_ = Trigger::kUnknown;
159*795d594fSAndroid Build Coastguard Worker   Stage stage_ = Stage::kUnknown;
160*795d594fSAndroid Build Coastguard Worker   Status status_ = Status::kUnknown;
161*795d594fSAndroid Build Coastguard Worker 
162*795d594fSAndroid Build Coastguard Worker   int32_t cache_space_free_start_mib_ = 0;
163*795d594fSAndroid Build Coastguard Worker   int32_t cache_space_free_end_mib_ = 0;
164*795d594fSAndroid Build Coastguard Worker 
165*795d594fSAndroid Build Coastguard Worker   // The total time spent on compiling primary BCP.
166*795d594fSAndroid Build Coastguard Worker   int32_t primary_bcp_compilation_millis_ = 0;
167*795d594fSAndroid Build Coastguard Worker 
168*795d594fSAndroid Build Coastguard Worker   // The result of the dex2oat invocation for compiling primary BCP, or `std::nullopt` if dex2oat is
169*795d594fSAndroid Build Coastguard Worker   // not invoked.
170*795d594fSAndroid Build Coastguard Worker   std::optional<ExecResult> primary_bcp_dex2oat_result_;
171*795d594fSAndroid Build Coastguard Worker 
172*795d594fSAndroid Build Coastguard Worker   BcpCompilationType primary_bcp_compilation_type_ = BcpCompilationType::kUnknown;
173*795d594fSAndroid Build Coastguard Worker 
174*795d594fSAndroid Build Coastguard Worker   // The total time spent on compiling secondary BCP.
175*795d594fSAndroid Build Coastguard Worker   int32_t secondary_bcp_compilation_millis_ = 0;
176*795d594fSAndroid Build Coastguard Worker 
177*795d594fSAndroid Build Coastguard Worker   // The result of the dex2oat invocation for compiling secondary BCP, or `std::nullopt` if dex2oat
178*795d594fSAndroid Build Coastguard Worker   // is not invoked.
179*795d594fSAndroid Build Coastguard Worker   std::optional<ExecResult> secondary_bcp_dex2oat_result_;
180*795d594fSAndroid Build Coastguard Worker 
181*795d594fSAndroid Build Coastguard Worker   BcpCompilationType secondary_bcp_compilation_type_ = BcpCompilationType::kUnknown;
182*795d594fSAndroid Build Coastguard Worker 
183*795d594fSAndroid Build Coastguard Worker   // The total time spent on compiling system server.
184*795d594fSAndroid Build Coastguard Worker   int32_t system_server_compilation_millis_ = 0;
185*795d594fSAndroid Build Coastguard Worker 
186*795d594fSAndroid Build Coastguard Worker   // The result of the last dex2oat invocation for compiling system server, or `std::nullopt` if
187*795d594fSAndroid Build Coastguard Worker   // dex2oat is not invoked.
188*795d594fSAndroid Build Coastguard Worker   std::optional<ExecResult> system_server_dex2oat_result_;
189*795d594fSAndroid Build Coastguard Worker };
190*795d594fSAndroid Build Coastguard Worker 
191*795d594fSAndroid Build Coastguard Worker // Generated ostream operators.
192*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, OdrMetrics::Status status);
193*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, OdrMetrics::Stage stage);
194*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, OdrMetrics::Trigger trigger);
195*795d594fSAndroid Build Coastguard Worker 
196*795d594fSAndroid Build Coastguard Worker }  // namespace odrefresh
197*795d594fSAndroid Build Coastguard Worker }  // namespace art
198*795d594fSAndroid Build Coastguard Worker 
199*795d594fSAndroid Build Coastguard Worker #endif  // ART_ODREFRESH_ODR_METRICS_H_
200