| // Copyright 2021 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #pragma once |
| |
| #include "histogram.hpp" |
| |
| #include <systemd/sd-bus.h> |
| |
| #include <atomic> |
| #include <map> |
| #include <mutex> |
| #include <string> |
| #include <vector> |
| |
| enum DBusTopSortField |
| { |
| // DBus Message properties |
| kSender, |
| kDestination, |
| kInterface, |
| kPath, |
| kMember, |
| kSenderPID, |
| kSenderCMD, |
| // Computed metrics |
| kMsgPerSec, |
| kAverageLatency, |
| }; |
| |
| const std::string FieldNames[] = {"Sender", "Destination", "Interface", |
| "Path", "Member", "Sender PID", |
| "Sender CMD", "Msg/s", "Avg Latency"}; |
| const int FieldPreferredWidths[] = {18, 20, 12, 10, 10, 10, 25, 8, 12}; |
| bool DBusTopSortFieldIsNumeric(DBusTopSortField field); |
| |
| struct DBusTopComputedMetrics |
| { |
| DBusTopComputedMetrics() |
| { |
| num_signals = 0; |
| num_errors = 0; |
| num_method_returns = 0; |
| num_method_calls = 0; |
| total_latency_usec = 0; |
| } |
| int num_method_returns = 0; |
| int num_errors = 0; |
| int num_signals = 0; |
| int num_method_calls; |
| uint64_t total_latency_usec; |
| }; |
| |
| class DBusTopStatistics |
| { |
| public: |
| int num_messages_; |
| int num_mc_, num_mr_, num_sig_, num_error_; |
| float seconds_since_last_sample_; |
| std::vector<DBusTopSortField> fields_; |
| std::map<std::vector<std::string>, DBusTopComputedMetrics> stats_; |
| DBusTopStatistics() : |
| num_messages_(0), num_mc_(0), num_mr_(0), num_sig_(0), num_error_(0), |
| seconds_since_last_sample_(0) |
| { |
| fields_ = {kSender, kDestination, kSenderPID, kSenderCMD}; |
| stats_.clear(); |
| } |
| |
| std::vector<DBusTopSortField> GetFields() |
| { |
| return fields_; |
| } |
| |
| std::vector<std::string> GetFieldNames() |
| { |
| const int N = fields_.size(); |
| std::vector<std::string> ret(N); |
| for (int i = 0; i < static_cast<int>(fields_.size()); i++) |
| { |
| ret[i] = FieldNames[static_cast<int>(fields_[i])]; |
| } |
| return ret; |
| } |
| |
| std::vector<int> GetFieldPreferredWidths() |
| { |
| const int N = fields_.size(); |
| std::vector<int> ret(N); |
| for (int i = 0; i < static_cast<int>(fields_.size()); i++) |
| { |
| ret[i] = FieldPreferredWidths[static_cast<int>(fields_[i])]; |
| } |
| return ret; |
| } |
| |
| void Reset() |
| { |
| num_messages_ = 0; |
| num_mc_ = 0; |
| num_mr_ = 0; |
| num_sig_ = 0; |
| num_error_ = 0; |
| stats_.clear(); |
| } |
| |
| void SetSortFieldsAndReset(const std::vector<DBusTopSortField>& f) |
| { |
| num_messages_ = 0; |
| num_mc_ = 0; |
| num_mr_ = 0; |
| num_sig_ = 0; |
| num_error_ = 0; |
| stats_.clear(); |
| fields_ = f; |
| } |
| |
| void Assign(DBusTopStatistics* out) |
| { |
| out->num_messages_ = this->num_messages_; |
| out->num_mc_ = this->num_mc_; |
| out->num_mr_ = this->num_mr_; |
| out->num_sig_ = this->num_sig_; |
| out->num_error_ = this->num_error_; |
| out->seconds_since_last_sample_ = this->seconds_since_last_sample_; |
| out->fields_ = this->fields_; |
| out->stats_ = this->stats_; |
| } |
| |
| void OnNewDBusMessage(const char* sender, const char* destination, |
| const char* interface, const char* path, |
| const char* message, const char type, |
| sd_bus_message* m); |
| std::string CheckAndFixNullString(const char* x) |
| { |
| if (x == nullptr) |
| return "(null)"; |
| else |
| return std::string(x); |
| } |
| |
| std::map<std::vector<std::string>, DBusTopComputedMetrics> StatsSnapshot() |
| { |
| std::map<std::vector<std::string>, DBusTopComputedMetrics> ret; |
| ret = stats_; |
| return ret; |
| } |
| |
| private: |
| std::mutex mtx_; |
| }; |
| |
| int GetSummaryIntervalInMillises(); |
| // Monitor sensor details-related DBus method calls/replies |
| // typedef void (*SetDBusTopConnection)(const char* conn); |
| namespace dbus_top_analyzer |
| { |
| void Process(); |
| void Finish(); |
| typedef void (*DBusTopStatisticsCallback)(DBusTopStatistics*, |
| Histogram<float>*); |
| void SetDBusTopStatisticsCallback(DBusTopStatisticsCallback cb); |
| void AnalyzerThread(); |
| // Methods for sending Object Mapper queries |
| void ListAllSensors(); |
| } // namespace dbus_top_analyzer |