1 /*
2 * Copyright (C) 2019 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 #include "src/trace_processor/metrics/metrics.h"
18
19 #include "perfetto/base/string_utils.h"
20 #include "perfetto/metrics/android/mem_metric.pbzero.h"
21 #include "perfetto/metrics/metrics.pbzero.h"
22 #include "perfetto/protozero/scattered_heap_buffer.h"
23 #include "src/trace_processor/metrics/sql_metrics.h"
24
25 namespace perfetto {
26 namespace trace_processor {
27 namespace metrics {
28
RunMetric(sqlite3_context * ctx,int argc,sqlite3_value ** argv)29 void RunMetric(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
30 auto* tp = static_cast<TraceProcessor*>(sqlite3_user_data(ctx));
31 if (argc == 0 || sqlite3_value_type(argv[0]) != SQLITE_TEXT) {
32 sqlite3_result_error(ctx, "Invalid call to RUN_METRIC", -1);
33 return;
34 }
35
36 const char* filename =
37 reinterpret_cast<const char*>(sqlite3_value_text(argv[0]));
38 const char* sql = sql_metrics::GetBundledMetric(filename);
39 if (!sql) {
40 sqlite3_result_error(ctx, "Unknown filename provided to RUN_METRIC", -1);
41 return;
42 }
43
44 for (const auto& query : base::SplitString(sql, ";\n\n")) {
45 PERFETTO_DLOG("Executing query in RUN_METRIC: %s", query.c_str());
46
47 auto it = tp->ExecuteQuery(query);
48 if (auto opt_error = it.GetLastError()) {
49 sqlite3_result_error(ctx, "Error when running RUN_METRIC file", -1);
50 return;
51 } else if (it.Next()) {
52 sqlite3_result_error(
53 ctx, "RUN_METRIC functions should not produce any output", -1);
54 return;
55 }
56 }
57 }
58
ComputeMetrics(TraceProcessor * tp,const std::vector<std::string> & metric_names,std::vector<uint8_t> * metrics_proto)59 int ComputeMetrics(TraceProcessor* tp,
60 const std::vector<std::string>& metric_names,
61 std::vector<uint8_t>* metrics_proto) {
62 // TODO(lalitm): stop hardcoding android.mem metric and read the proto
63 // descriptor for this logic instead.
64 if (metric_names.size() != 1 || metric_names[0] != "android.mem") {
65 PERFETTO_ELOG("Only android.mem metric is currently supported");
66 return 1;
67 }
68
69 auto queries = base::SplitString(sql_metrics::kAndroidMem, ";\n\n");
70 for (const auto& query : queries) {
71 PERFETTO_DLOG("Executing query: %s", query.c_str());
72 auto prep_it = tp->ExecuteQuery(query);
73 auto prep_has_next = prep_it.Next();
74 if (auto opt_error = prep_it.GetLastError()) {
75 PERFETTO_ELOG("SQLite error: %s", opt_error->c_str());
76 return 1;
77 }
78 PERFETTO_DCHECK(!prep_has_next);
79 }
80
81 protozero::ScatteredHeapBuffer delegate;
82 protozero::ScatteredStreamWriter writer(&delegate);
83 delegate.set_writer(&writer);
84
85 protos::pbzero::TraceMetrics metrics;
86 metrics.Reset(&writer);
87
88 // TODO(lalitm): all the below is temporary hardcoded queries and proto
89 // filling to ensure that the code above works.
90 auto it = tp->ExecuteQuery("SELECT COUNT(*) from lmk_by_score;");
91 auto has_next = it.Next();
92 if (auto opt_error = it.GetLastError()) {
93 PERFETTO_ELOG("SQLite error: %s", opt_error->c_str());
94 return 1;
95 }
96 PERFETTO_CHECK(has_next);
97 PERFETTO_CHECK(it.Get(0).type == SqlValue::Type::kLong);
98
99 auto* memory = metrics.set_android_mem();
100 memory->set_system_metrics()->set_lmks()->set_total_count(
101 static_cast<int32_t>(it.Get(0).long_value));
102 metrics.Finalize();
103
104 *metrics_proto = delegate.StitchSlices();
105
106 has_next = it.Next();
107 PERFETTO_DCHECK(!has_next);
108 return 0;
109 }
110
111 } // namespace metrics
112 } // namespace trace_processor
113 } // namespace perfetto
114