blob: 463bad75fa7db656be92f5a485bd38cc00a03168 [file] [log] [blame]
Adedeji Adebisi684ec912021-07-22 18:07:52 +00001// Copyright 2021 Google LLC
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#pragma once
16
17#include "histogram.hpp"
18
19#include <systemd/sd-bus.h>
20
21#include <atomic>
22#include <map>
23#include <mutex>
24#include <string>
25#include <vector>
26
Sui Chen8c5208f2023-04-21 14:10:05 -070027class DBusConnectionSnapshot;
28class SensorSnapshot;
29
Adedeji Adebisi684ec912021-07-22 18:07:52 +000030enum DBusTopSortField
31{
32 // DBus Message properties
33 kSender,
34 kDestination,
35 kInterface,
36 kPath,
37 kMember,
38 kSenderPID,
39 kSenderCMD,
40 // Computed metrics
41 kMsgPerSec,
42 kAverageLatency,
43};
44
45const std::string FieldNames[] = {"Sender", "Destination", "Interface",
46 "Path", "Member", "Sender PID",
47 "Sender CMD", "Msg/s", "Avg Latency"};
48const int FieldPreferredWidths[] = {18, 20, 12, 10, 10, 10, 25, 8, 12};
49bool DBusTopSortFieldIsNumeric(DBusTopSortField field);
50
51struct DBusTopComputedMetrics
52{
53 DBusTopComputedMetrics()
54 {
55 num_signals = 0;
56 num_errors = 0;
57 num_method_returns = 0;
58 num_method_calls = 0;
59 total_latency_usec = 0;
60 }
61 int num_method_returns = 0;
62 int num_errors = 0;
63 int num_signals = 0;
64 int num_method_calls;
65 uint64_t total_latency_usec;
66};
67
68class DBusTopStatistics
69{
70 public:
71 int num_messages_;
72 int num_mc_, num_mr_, num_sig_, num_error_;
73 float seconds_since_last_sample_;
74 std::vector<DBusTopSortField> fields_;
75 std::map<std::vector<std::string>, DBusTopComputedMetrics> stats_;
76 DBusTopStatistics() :
77 num_messages_(0), num_mc_(0), num_mr_(0), num_sig_(0), num_error_(0),
78 seconds_since_last_sample_(0)
79 {
80 fields_ = {kSender, kDestination, kSenderPID, kSenderCMD};
81 stats_.clear();
82 }
83
84 std::vector<DBusTopSortField> GetFields()
85 {
86 return fields_;
87 }
88
89 std::vector<std::string> GetFieldNames()
90 {
91 const int N = fields_.size();
92 std::vector<std::string> ret(N);
93 for (int i = 0; i < static_cast<int>(fields_.size()); i++)
94 {
95 ret[i] = FieldNames[static_cast<int>(fields_[i])];
96 }
97 return ret;
98 }
99
100 std::vector<int> GetFieldPreferredWidths()
101 {
102 const int N = fields_.size();
103 std::vector<int> ret(N);
104 for (int i = 0; i < static_cast<int>(fields_.size()); i++)
105 {
106 ret[i] = FieldPreferredWidths[static_cast<int>(fields_[i])];
107 }
108 return ret;
109 }
110
111 void Reset()
112 {
113 num_messages_ = 0;
114 num_mc_ = 0;
115 num_mr_ = 0;
116 num_sig_ = 0;
117 num_error_ = 0;
118 stats_.clear();
119 }
kuiyingdfb0cd92023-03-14 11:43:23 +0800120
Adedeji Adebisi684ec912021-07-22 18:07:52 +0000121 void SetSortFieldsAndReset(const std::vector<DBusTopSortField>& f)
122 {
123 num_messages_ = 0;
124 num_mc_ = 0;
125 num_mr_ = 0;
126 num_sig_ = 0;
127 num_error_ = 0;
128 stats_.clear();
129 fields_ = f;
130 }
131
132 void Assign(DBusTopStatistics* out)
133 {
134 out->num_messages_ = this->num_messages_;
135 out->num_mc_ = this->num_mc_;
136 out->num_mr_ = this->num_mr_;
137 out->num_sig_ = this->num_sig_;
138 out->num_error_ = this->num_error_;
139 out->seconds_since_last_sample_ = this->seconds_since_last_sample_;
140 out->fields_ = this->fields_;
141 out->stats_ = this->stats_;
142 }
143
144 void OnNewDBusMessage(const char* sender, const char* destination,
145 const char* interface, const char* path,
146 const char* message, const char type,
147 sd_bus_message* m);
148 std::string CheckAndFixNullString(const char* x)
149 {
150 if (x == nullptr)
151 return "(null)";
152 else
153 return std::string(x);
154 }
155
156 std::map<std::vector<std::string>, DBusTopComputedMetrics> StatsSnapshot()
157 {
158 std::map<std::vector<std::string>, DBusTopComputedMetrics> ret;
159 ret = stats_;
160 return ret;
161 }
162
163 private:
164 std::mutex mtx_;
165};
166
167int GetSummaryIntervalInMillises();
168// Monitor sensor details-related DBus method calls/replies
169// typedef void (*SetDBusTopConnection)(const char* conn);
170namespace dbus_top_analyzer
171{
kuiyingdfb0cd92023-03-14 11:43:23 +0800172void Process();
173void Finish();
174typedef void (*DBusTopStatisticsCallback)(DBusTopStatistics*,
175 Histogram<float>*);
176void SetDBusTopStatisticsCallback(DBusTopStatisticsCallback cb);
177void AnalyzerThread();
178// Methods for sending Object Mapper queries
Sui Chen8c5208f2023-04-21 14:10:05 -0700179void ListAllSensors(sd_bus*, DBusConnectionSnapshot**, SensorSnapshot**);
Adedeji Adebisi684ec912021-07-22 18:07:52 +0000180} // namespace dbus_top_analyzer