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/internal/map_builder_context_interface.h"
|
||||||
#include "cartographer/cloud/proto/map_builder_service.pb.h"
|
#include "cartographer/cloud/proto/map_builder_service.pb.h"
|
||||||
#include "cartographer/mapping/local_slam_result_data.h"
|
#include "cartographer/mapping/local_slam_result_data.h"
|
||||||
|
#include "cartographer/metrics/counter.h"
|
||||||
#include "cartographer/sensor/internal/dispatchable.h"
|
#include "cartographer/sensor/internal/dispatchable.h"
|
||||||
#include "cartographer/sensor/timed_point_cloud_data.h"
|
#include "cartographer/sensor/timed_point_cloud_data.h"
|
||||||
#include "google/protobuf/empty.pb.h"
|
#include "google/protobuf/empty.pb.h"
|
||||||
|
@ -29,6 +30,10 @@ namespace cartographer {
|
||||||
namespace cloud {
|
namespace cloud {
|
||||||
namespace handlers {
|
namespace handlers {
|
||||||
|
|
||||||
|
metrics::Family<metrics::Counter>*
|
||||||
|
AddSensorDataBatchHandler::counter_metrics_family_ =
|
||||||
|
metrics::Family<metrics::Counter>::Null();
|
||||||
|
|
||||||
void AddSensorDataBatchHandler::OnRequest(
|
void AddSensorDataBatchHandler::OnRequest(
|
||||||
const proto::AddSensorDataBatchRequest& request) {
|
const proto::AddSensorDataBatchRequest& request) {
|
||||||
for (const proto::SensorData& sensor_data : request.sensor_data()) {
|
for (const proto::SensorData& sensor_data : request.sensor_data()) {
|
||||||
|
@ -42,6 +47,9 @@ void AddSensorDataBatchHandler::OnRequest(
|
||||||
Finish(::grpc::Status(::grpc::NOT_FOUND, "Unknown trajectory"));
|
Finish(::grpc::Status(::grpc::NOT_FOUND, "Unknown trajectory"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ClientMetrics* const metrics =
|
||||||
|
GetOrCreateClientMetrics(sensor_data.sensor_metadata().client_id(),
|
||||||
|
sensor_data.sensor_metadata().trajectory_id());
|
||||||
switch (sensor_data.sensor_data_case()) {
|
switch (sensor_data.sensor_data_case()) {
|
||||||
case proto::SensorData::kOdometryData:
|
case proto::SensorData::kOdometryData:
|
||||||
GetUnsynchronizedContext<MapBuilderContextInterface>()
|
GetUnsynchronizedContext<MapBuilderContextInterface>()
|
||||||
|
@ -50,6 +58,7 @@ void AddSensorDataBatchHandler::OnRequest(
|
||||||
sensor::MakeDispatchable(
|
sensor::MakeDispatchable(
|
||||||
sensor_data.sensor_metadata().sensor_id(),
|
sensor_data.sensor_metadata().sensor_id(),
|
||||||
sensor::FromProto(sensor_data.odometry_data())));
|
sensor::FromProto(sensor_data.odometry_data())));
|
||||||
|
metrics->odometry_sensor_counter->Increment();
|
||||||
break;
|
break;
|
||||||
case proto::SensorData::kImuData:
|
case proto::SensorData::kImuData:
|
||||||
GetUnsynchronizedContext<MapBuilderContextInterface>()
|
GetUnsynchronizedContext<MapBuilderContextInterface>()
|
||||||
|
@ -57,6 +66,7 @@ void AddSensorDataBatchHandler::OnRequest(
|
||||||
sensor::MakeDispatchable(
|
sensor::MakeDispatchable(
|
||||||
sensor_data.sensor_metadata().sensor_id(),
|
sensor_data.sensor_metadata().sensor_id(),
|
||||||
sensor::FromProto(sensor_data.imu_data())));
|
sensor::FromProto(sensor_data.imu_data())));
|
||||||
|
metrics->imu_sensor_counter->Increment();
|
||||||
break;
|
break;
|
||||||
case proto::SensorData::kTimedPointCloudData:
|
case proto::SensorData::kTimedPointCloudData:
|
||||||
GetUnsynchronizedContext<MapBuilderContextInterface>()
|
GetUnsynchronizedContext<MapBuilderContextInterface>()
|
||||||
|
@ -65,6 +75,7 @@ void AddSensorDataBatchHandler::OnRequest(
|
||||||
sensor::MakeDispatchable(
|
sensor::MakeDispatchable(
|
||||||
sensor_data.sensor_metadata().sensor_id(),
|
sensor_data.sensor_metadata().sensor_id(),
|
||||||
sensor::FromProto(sensor_data.timed_point_cloud_data())));
|
sensor::FromProto(sensor_data.timed_point_cloud_data())));
|
||||||
|
metrics->timed_point_cloud_counter->Increment();
|
||||||
break;
|
break;
|
||||||
case proto::SensorData::kFixedFramePoseData:
|
case proto::SensorData::kFixedFramePoseData:
|
||||||
GetUnsynchronizedContext<MapBuilderContextInterface>()
|
GetUnsynchronizedContext<MapBuilderContextInterface>()
|
||||||
|
@ -73,6 +84,7 @@ void AddSensorDataBatchHandler::OnRequest(
|
||||||
sensor::MakeDispatchable(
|
sensor::MakeDispatchable(
|
||||||
sensor_data.sensor_metadata().sensor_id(),
|
sensor_data.sensor_metadata().sensor_id(),
|
||||||
sensor::FromProto(sensor_data.fixed_frame_pose_data())));
|
sensor::FromProto(sensor_data.fixed_frame_pose_data())));
|
||||||
|
metrics->fixed_frame_pose_counter->Increment();
|
||||||
break;
|
break;
|
||||||
case proto::SensorData::kLandmarkData:
|
case proto::SensorData::kLandmarkData:
|
||||||
GetUnsynchronizedContext<MapBuilderContextInterface>()
|
GetUnsynchronizedContext<MapBuilderContextInterface>()
|
||||||
|
@ -81,12 +93,14 @@ void AddSensorDataBatchHandler::OnRequest(
|
||||||
sensor::MakeDispatchable(
|
sensor::MakeDispatchable(
|
||||||
sensor_data.sensor_metadata().sensor_id(),
|
sensor_data.sensor_metadata().sensor_id(),
|
||||||
sensor::FromProto(sensor_data.landmark_data())));
|
sensor::FromProto(sensor_data.landmark_data())));
|
||||||
|
metrics->landmark_counter->Increment();
|
||||||
break;
|
break;
|
||||||
case proto::SensorData::kLocalSlamResultData:
|
case proto::SensorData::kLocalSlamResultData:
|
||||||
GetContext<MapBuilderContextInterface>()->EnqueueLocalSlamResultData(
|
GetContext<MapBuilderContextInterface>()->EnqueueLocalSlamResultData(
|
||||||
sensor_data.sensor_metadata().trajectory_id(),
|
sensor_data.sensor_metadata().trajectory_id(),
|
||||||
sensor_data.sensor_metadata().sensor_id(),
|
sensor_data.sensor_metadata().sensor_id(),
|
||||||
sensor_data.local_slam_result_data());
|
sensor_data.local_slam_result_data());
|
||||||
|
metrics->local_slam_result_counter->Increment();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG(FATAL) << "Unknown sensor data type: "
|
LOG(FATAL) << "Unknown sensor data type: "
|
||||||
|
@ -96,6 +110,54 @@ void AddSensorDataBatchHandler::OnRequest(
|
||||||
Send(absl::make_unique<google::protobuf::Empty>());
|
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 handlers
|
||||||
} // namespace cloud
|
} // namespace cloud
|
||||||
} // namespace cartographer
|
} // namespace cartographer
|
||||||
|
|
|
@ -17,8 +17,13 @@
|
||||||
#ifndef CARTOGRAPHER_CLOUD_INTERNAL_HANDLERS_ADD_SENSOR_DATA_BATCH_HANDLER_H
|
#ifndef CARTOGRAPHER_CLOUD_INTERNAL_HANDLERS_ADD_SENSOR_DATA_BATCH_HANDLER_H
|
||||||
#define 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 "async_grpc/rpc_handler.h"
|
||||||
#include "cartographer/cloud/proto/map_builder_service.pb.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"
|
#include "google/protobuf/empty.pb.h"
|
||||||
|
|
||||||
namespace cartographer {
|
namespace cartographer {
|
||||||
|
@ -34,6 +39,28 @@ class AddSensorDataBatchHandler
|
||||||
: public async_grpc::RpcHandler<AddSensorDataBatchSignature> {
|
: public async_grpc::RpcHandler<AddSensorDataBatchSignature> {
|
||||||
public:
|
public:
|
||||||
void OnRequest(const proto::AddSensorDataBatchRequest& request) override;
|
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
|
} // namespace handlers
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "cartographer/cloud/metrics/prometheus/family_factory.h"
|
#include "cartographer/cloud/metrics/prometheus/family_factory.h"
|
||||||
|
|
||||||
#include "absl/memory/memory.h"
|
#include "absl/memory/memory.h"
|
||||||
|
@ -30,6 +32,23 @@ namespace {
|
||||||
|
|
||||||
using BucketBoundaries = ::cartographer::metrics::Histogram::BucketBoundaries;
|
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 {
|
class Counter : public ::cartographer::metrics::Counter {
|
||||||
public:
|
public:
|
||||||
explicit Counter(::prometheus::Counter* prometheus)
|
explicit Counter(::prometheus::Counter* prometheus)
|
||||||
|
@ -51,15 +70,14 @@ class CounterFamily
|
||||||
|
|
||||||
Counter* Add(const std::map<std::string, std::string>& labels) override {
|
Counter* Add(const std::map<std::string, std::string>& labels) override {
|
||||||
::prometheus::Counter* counter = &prometheus_->Add(labels);
|
::prometheus::Counter* counter = &prometheus_->Add(labels);
|
||||||
auto wrapper = absl::make_unique<Counter>(counter);
|
return GetOrCreateWrapper<>(counter, &wrappers_, &wrappers_mutex_);
|
||||||
auto* ptr = wrapper.get();
|
|
||||||
wrappers_.emplace_back(std::move(wrapper));
|
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
::prometheus::Family<::prometheus::Counter>* prometheus_;
|
::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 {
|
class Gauge : public ::cartographer::metrics::Gauge {
|
||||||
|
@ -84,15 +102,13 @@ class GaugeFamily
|
||||||
|
|
||||||
Gauge* Add(const std::map<std::string, std::string>& labels) override {
|
Gauge* Add(const std::map<std::string, std::string>& labels) override {
|
||||||
::prometheus::Gauge* gauge = &prometheus_->Add(labels);
|
::prometheus::Gauge* gauge = &prometheus_->Add(labels);
|
||||||
auto wrapper = absl::make_unique<Gauge>(gauge);
|
return GetOrCreateWrapper<>(gauge, &wrappers_, &wrappers_mutex_);
|
||||||
auto* ptr = wrapper.get();
|
|
||||||
wrappers_.emplace_back(std::move(wrapper));
|
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
::prometheus::Family<::prometheus::Gauge>* prometheus_;
|
::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 {
|
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 {
|
Histogram* Add(const std::map<std::string, std::string>& labels) override {
|
||||||
::prometheus::Histogram* histogram = &prometheus_->Add(labels, boundaries_);
|
::prometheus::Histogram* histogram = &prometheus_->Add(labels, boundaries_);
|
||||||
auto wrapper = absl::make_unique<Histogram>(histogram);
|
return GetOrCreateWrapper<>(histogram, &wrappers_, &wrappers_mutex_);
|
||||||
auto* ptr = wrapper.get();
|
|
||||||
wrappers_.emplace_back(std::move(wrapper));
|
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
::prometheus::Family<::prometheus::Histogram>* prometheus_;
|
::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_;
|
const BucketBoundaries boundaries_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -27,14 +27,31 @@
|
||||||
namespace cartographer {
|
namespace cartographer {
|
||||||
namespace metrics {
|
namespace metrics {
|
||||||
|
|
||||||
|
template <typename MetricType>
|
||||||
|
class NullFamily;
|
||||||
|
|
||||||
template <typename MetricType>
|
template <typename MetricType>
|
||||||
class Family {
|
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 ~Family() = default;
|
||||||
|
|
||||||
virtual MetricType* Add(const std::map<std::string, std::string>& labels) = 0;
|
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 {
|
class FamilyFactory {
|
||||||
public:
|
public:
|
||||||
virtual ~FamilyFactory() = default;
|
virtual ~FamilyFactory() = default;
|
||||||
|
|
Loading…
Reference in New Issue