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