blob: 2284c7f7957a8c8f619eb12070d2d9e6b0c2ba05 [file] [log] [blame]
// 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