Add metric counters to track sensor data in the AddSensorDataBatchHandler class (#1338)
Adds additional metrics to track incoming sensor and local slam result data in Prometheus.master
parent
a3c9e9f1ca
commit
537b2d6762
|
@ -21,6 +21,7 @@
|
|||
#include "cartographer/cloud/internal/map_builder_context_interface.h"
|
||||
#include "cartographer/cloud/proto/map_builder_service.pb.h"
|
||||
#include "cartographer/mapping/local_slam_result_data.h"
|
||||
#include "cartographer/metrics/counter.h"
|
||||
#include "cartographer/sensor/internal/dispatchable.h"
|
||||
#include "cartographer/sensor/timed_point_cloud_data.h"
|
||||
#include "google/protobuf/empty.pb.h"
|
||||
|
@ -29,6 +30,10 @@ namespace cartographer {
|
|||
namespace cloud {
|
||||
namespace handlers {
|
||||
|
||||
metrics::Family<metrics::Counter>*
|
||||
AddSensorDataBatchHandler::counter_metrics_family_ =
|
||||
metrics::Family<metrics::Counter>::Null();
|
||||
|
||||
void AddSensorDataBatchHandler::OnRequest(
|
||||
const proto::AddSensorDataBatchRequest& request) {
|
||||
for (const proto::SensorData& sensor_data : request.sensor_data()) {
|
||||
|
@ -42,6 +47,9 @@ void AddSensorDataBatchHandler::OnRequest(
|
|||
Finish(::grpc::Status(::grpc::NOT_FOUND, "Unknown trajectory"));
|
||||
return;
|
||||
}
|
||||
ClientMetrics* const metrics =
|
||||
GetOrCreateClientMetrics(sensor_data.sensor_metadata().client_id(),
|
||||
sensor_data.sensor_metadata().trajectory_id());
|
||||
switch (sensor_data.sensor_data_case()) {
|
||||
case proto::SensorData::kOdometryData:
|
||||
GetUnsynchronizedContext<MapBuilderContextInterface>()
|
||||
|
@ -50,6 +58,7 @@ void AddSensorDataBatchHandler::OnRequest(
|
|||
sensor::MakeDispatchable(
|
||||
sensor_data.sensor_metadata().sensor_id(),
|
||||
sensor::FromProto(sensor_data.odometry_data())));
|
||||
metrics->odometry_sensor_counter->Increment();
|
||||
break;
|
||||
case proto::SensorData::kImuData:
|
||||
GetUnsynchronizedContext<MapBuilderContextInterface>()
|
||||
|
@ -57,6 +66,7 @@ void AddSensorDataBatchHandler::OnRequest(
|
|||
sensor::MakeDispatchable(
|
||||
sensor_data.sensor_metadata().sensor_id(),
|
||||
sensor::FromProto(sensor_data.imu_data())));
|
||||
metrics->imu_sensor_counter->Increment();
|
||||
break;
|
||||
case proto::SensorData::kTimedPointCloudData:
|
||||
GetUnsynchronizedContext<MapBuilderContextInterface>()
|
||||
|
@ -65,6 +75,7 @@ void AddSensorDataBatchHandler::OnRequest(
|
|||
sensor::MakeDispatchable(
|
||||
sensor_data.sensor_metadata().sensor_id(),
|
||||
sensor::FromProto(sensor_data.timed_point_cloud_data())));
|
||||
metrics->timed_point_cloud_counter->Increment();
|
||||
break;
|
||||
case proto::SensorData::kFixedFramePoseData:
|
||||
GetUnsynchronizedContext<MapBuilderContextInterface>()
|
||||
|
@ -73,6 +84,7 @@ void AddSensorDataBatchHandler::OnRequest(
|
|||
sensor::MakeDispatchable(
|
||||
sensor_data.sensor_metadata().sensor_id(),
|
||||
sensor::FromProto(sensor_data.fixed_frame_pose_data())));
|
||||
metrics->fixed_frame_pose_counter->Increment();
|
||||
break;
|
||||
case proto::SensorData::kLandmarkData:
|
||||
GetUnsynchronizedContext<MapBuilderContextInterface>()
|
||||
|
@ -81,12 +93,14 @@ void AddSensorDataBatchHandler::OnRequest(
|
|||
sensor::MakeDispatchable(
|
||||
sensor_data.sensor_metadata().sensor_id(),
|
||||
sensor::FromProto(sensor_data.landmark_data())));
|
||||
metrics->landmark_counter->Increment();
|
||||
break;
|
||||
case proto::SensorData::kLocalSlamResultData:
|
||||
GetContext<MapBuilderContextInterface>()->EnqueueLocalSlamResultData(
|
||||
sensor_data.sensor_metadata().trajectory_id(),
|
||||
sensor_data.sensor_metadata().sensor_id(),
|
||||
sensor_data.local_slam_result_data());
|
||||
metrics->local_slam_result_counter->Increment();
|
||||
break;
|
||||
default:
|
||||
LOG(FATAL) << "Unknown sensor data type: "
|
||||
|
@ -96,6 +110,54 @@ void AddSensorDataBatchHandler::OnRequest(
|
|||
Send(absl::make_unique<google::protobuf::Empty>());
|
||||
}
|
||||
|
||||
void AddSensorDataBatchHandler::RegisterMetrics(
|
||||
metrics::FamilyFactory* family_factory) {
|
||||
counter_metrics_family_ = family_factory->NewCounterFamily(
|
||||
"cartographer_sensor_data_total", "Sensor data received");
|
||||
}
|
||||
|
||||
AddSensorDataBatchHandler::ClientMetrics*
|
||||
AddSensorDataBatchHandler::GetOrCreateClientMetrics(
|
||||
const std::string& client_id, int trajectory_id) {
|
||||
const std::string map_key = client_id + std::to_string(trajectory_id);
|
||||
auto client_metric_map_itr = client_metric_map_.find(map_key);
|
||||
if (client_metric_map_itr != client_metric_map_.end()) {
|
||||
return client_metric_map_itr->second.get();
|
||||
}
|
||||
|
||||
LOG(INFO) << "Create metrics handler for client: " << client_id;
|
||||
auto new_metrics = absl::make_unique<ClientMetrics>();
|
||||
new_metrics->odometry_sensor_counter = counter_metrics_family_->Add(
|
||||
{{"client_id", client_id},
|
||||
{"trajectory_id", std::to_string(trajectory_id)},
|
||||
{"sensor", "odometry"}});
|
||||
new_metrics->imu_sensor_counter = counter_metrics_family_->Add(
|
||||
{{"client_id", client_id},
|
||||
{"trajectory_id", std::to_string(trajectory_id)},
|
||||
{"sensor", "imu"}});
|
||||
new_metrics->fixed_frame_pose_counter = counter_metrics_family_->Add(
|
||||
{{"client_id", client_id},
|
||||
{"trajectory_id", std::to_string(trajectory_id)},
|
||||
{"sensor", "fixed_frame_pose"}});
|
||||
new_metrics->landmark_counter = counter_metrics_family_->Add(
|
||||
{{"client_id", client_id},
|
||||
{"trajectory_id", std::to_string(trajectory_id)},
|
||||
{"sensor", "landmark"}});
|
||||
new_metrics->local_slam_result_counter = counter_metrics_family_->Add(
|
||||
{{"client_id", client_id},
|
||||
{"trajectory_id", std::to_string(trajectory_id)},
|
||||
{"sensor", "local_slam_result"}});
|
||||
new_metrics->timed_point_cloud_counter = counter_metrics_family_->Add(
|
||||
{{"client_id", client_id},
|
||||
{"trajectory_id", std::to_string(trajectory_id)},
|
||||
{"sensor", "timed_point_cloud"}});
|
||||
|
||||
// Obtain pointer before ownership is transferred.
|
||||
auto* new_metrics_ptr = new_metrics.get();
|
||||
client_metric_map_[map_key] = std::move(new_metrics);
|
||||
return new_metrics_ptr;
|
||||
}
|
||||
|
||||
} // namespace handlers
|
||||
} // namespace cloud
|
||||
} // namespace cartographer
|
||||
|
|
|
@ -17,8 +17,13 @@
|
|||
#ifndef CARTOGRAPHER_CLOUD_INTERNAL_HANDLERS_ADD_SENSOR_DATA_BATCH_HANDLER_H
|
||||
#define CARTOGRAPHER_CLOUD_INTERNAL_HANDLERS_ADD_SENSOR_DATA_BATCH_HANDLER_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "async_grpc/rpc_handler.h"
|
||||
#include "cartographer/cloud/proto/map_builder_service.pb.h"
|
||||
#include "cartographer/metrics/counter.h"
|
||||
#include "cartographer/metrics/family_factory.h"
|
||||
#include "google/protobuf/empty.pb.h"
|
||||
|
||||
namespace cartographer {
|
||||
|
@ -34,6 +39,28 @@ class AddSensorDataBatchHandler
|
|||
: public async_grpc::RpcHandler<AddSensorDataBatchSignature> {
|
||||
public:
|
||||
void OnRequest(const proto::AddSensorDataBatchRequest& request) override;
|
||||
|
||||
static void RegisterMetrics(metrics::FamilyFactory* family_factory);
|
||||
|
||||
private:
|
||||
struct ClientMetrics {
|
||||
metrics::Counter* odometry_sensor_counter;
|
||||
metrics::Counter* imu_sensor_counter;
|
||||
metrics::Counter* timed_point_cloud_counter;
|
||||
metrics::Counter* fixed_frame_pose_counter;
|
||||
metrics::Counter* landmark_counter;
|
||||
metrics::Counter* local_slam_result_counter;
|
||||
};
|
||||
|
||||
ClientMetrics* GetOrCreateClientMetrics(const std::string& client_id,
|
||||
int trajectory_id);
|
||||
|
||||
static cartographer::metrics::Family<metrics::Counter>*
|
||||
counter_metrics_family_;
|
||||
|
||||
// Holds individual metrics for each client.
|
||||
std::unordered_map<std::string, std::unique_ptr<ClientMetrics>>
|
||||
client_metric_map_;
|
||||
};
|
||||
|
||||
} // namespace handlers
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "cartographer/cloud/metrics/prometheus/family_factory.h"
|
||||
|
||||
#include "absl/memory/memory.h"
|
||||
|
@ -30,6 +32,23 @@ namespace {
|
|||
|
||||
using BucketBoundaries = ::cartographer::metrics::Histogram::BucketBoundaries;
|
||||
|
||||
// Creates or looks up already existing objects from a wrapper map.
|
||||
template <typename WrapperMap,
|
||||
typename ObjectPtr = typename WrapperMap::key_type,
|
||||
typename Wrapper = typename WrapperMap::mapped_type::element_type>
|
||||
Wrapper* GetOrCreateWrapper(ObjectPtr object_ptr, WrapperMap* wrapper_map,
|
||||
std::mutex* wrapper_mutex) {
|
||||
std::lock_guard<std::mutex> lock(*wrapper_mutex);
|
||||
auto wrappers_itr = wrapper_map->find(object_ptr);
|
||||
if (wrappers_itr == wrapper_map->end()) {
|
||||
auto wrapper = absl::make_unique<Wrapper>(object_ptr);
|
||||
auto* ptr = wrapper.get();
|
||||
(*wrapper_map)[object_ptr] = std::unique_ptr<Wrapper>(std::move(wrapper));
|
||||
return ptr;
|
||||
}
|
||||
return wrappers_itr->second.get();
|
||||
}
|
||||
|
||||
class Counter : public ::cartographer::metrics::Counter {
|
||||
public:
|
||||
explicit Counter(::prometheus::Counter* prometheus)
|
||||
|
@ -51,15 +70,14 @@ class CounterFamily
|
|||
|
||||
Counter* Add(const std::map<std::string, std::string>& labels) override {
|
||||
::prometheus::Counter* counter = &prometheus_->Add(labels);
|
||||
auto wrapper = absl::make_unique<Counter>(counter);
|
||||
auto* ptr = wrapper.get();
|
||||
wrappers_.emplace_back(std::move(wrapper));
|
||||
return ptr;
|
||||
return GetOrCreateWrapper<>(counter, &wrappers_, &wrappers_mutex_);
|
||||
}
|
||||
|
||||
private:
|
||||
::prometheus::Family<::prometheus::Counter>* prometheus_;
|
||||
std::vector<std::unique_ptr<Counter>> wrappers_;
|
||||
std::mutex wrappers_mutex_;
|
||||
std::unordered_map<::prometheus::Counter*, std::unique_ptr<Counter>>
|
||||
wrappers_;
|
||||
};
|
||||
|
||||
class Gauge : public ::cartographer::metrics::Gauge {
|
||||
|
@ -84,15 +102,13 @@ class GaugeFamily
|
|||
|
||||
Gauge* Add(const std::map<std::string, std::string>& labels) override {
|
||||
::prometheus::Gauge* gauge = &prometheus_->Add(labels);
|
||||
auto wrapper = absl::make_unique<Gauge>(gauge);
|
||||
auto* ptr = wrapper.get();
|
||||
wrappers_.emplace_back(std::move(wrapper));
|
||||
return ptr;
|
||||
return GetOrCreateWrapper<>(gauge, &wrappers_, &wrappers_mutex_);
|
||||
}
|
||||
|
||||
private:
|
||||
::prometheus::Family<::prometheus::Gauge>* prometheus_;
|
||||
std::vector<std::unique_ptr<Gauge>> wrappers_;
|
||||
std::mutex wrappers_mutex_;
|
||||
std::unordered_map<::prometheus::Gauge*, std::unique_ptr<Gauge>> wrappers_;
|
||||
};
|
||||
|
||||
class Histogram : public ::cartographer::metrics::Histogram {
|
||||
|
@ -115,15 +131,14 @@ class HistogramFamily : public ::cartographer::metrics::Family<
|
|||
|
||||
Histogram* Add(const std::map<std::string, std::string>& labels) override {
|
||||
::prometheus::Histogram* histogram = &prometheus_->Add(labels, boundaries_);
|
||||
auto wrapper = absl::make_unique<Histogram>(histogram);
|
||||
auto* ptr = wrapper.get();
|
||||
wrappers_.emplace_back(std::move(wrapper));
|
||||
return ptr;
|
||||
return GetOrCreateWrapper<>(histogram, &wrappers_, &wrappers_mutex_);
|
||||
}
|
||||
|
||||
private:
|
||||
::prometheus::Family<::prometheus::Histogram>* prometheus_;
|
||||
std::vector<std::unique_ptr<Histogram>> wrappers_;
|
||||
std::mutex wrappers_mutex_;
|
||||
std::unordered_map<::prometheus::Histogram*, std::unique_ptr<Histogram>>
|
||||
wrappers_;
|
||||
const BucketBoundaries boundaries_;
|
||||
};
|
||||
|
||||
|
|
|
@ -27,14 +27,31 @@
|
|||
namespace cartographer {
|
||||
namespace metrics {
|
||||
|
||||
template <typename MetricType>
|
||||
class NullFamily;
|
||||
|
||||
template <typename MetricType>
|
||||
class Family {
|
||||
public:
|
||||
public: // Family instance that does nothing. Safe for use in static
|
||||
// initializers.
|
||||
static Family<MetricType>* Null() {
|
||||
static NullFamily<MetricType> null_family;
|
||||
return &null_family;
|
||||
}
|
||||
|
||||
virtual ~Family() = default;
|
||||
|
||||
virtual MetricType* Add(const std::map<std::string, std::string>& labels) = 0;
|
||||
};
|
||||
|
||||
template <typename MetricType>
|
||||
class NullFamily : public Family<MetricType> {
|
||||
public:
|
||||
MetricType* Add(const std::map<std::string, std::string>& labels) override {
|
||||
return MetricType::Null();
|
||||
}
|
||||
};
|
||||
|
||||
class FamilyFactory {
|
||||
public:
|
||||
virtual ~FamilyFactory() = default;
|
||||
|
|
Loading…
Reference in New Issue