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