sapling/eden/fs/telemetry/RequestMetricsScope.h
Katie Mancini 48804631f7 expose number pending fuse requests
Summary:
This sets up the counters that will allow us to expose the number
of pending FUSE requests in Eden top.

As D20846826 mentions adding metrics for FUSE request gives
visibility into fuse requests and overall health of eden.

This provides more insight beyond the metrics for live FUSE requests
since it shows the kernels view of FUSE requests. Looking at the difference
between the number of pending and live request, can identify issues
that arise at the interface between eden and FUSE and monitor how
quickly fuse workers are processing requests.

**note**: this is only for linux since macos has no equivalent to
`/sys/fs/fuse/connections`

Reviewed By: chadaustin

Differential Revision: D21074489

fbshipit-source-id: c0951f0dfd4fa764be28d8686d08cd0dd807db37
2020-04-28 13:28:01 -07:00

113 lines
3.4 KiB
C++

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
#pragma once
#include <list>
#include <memory>
#include <string>
#include <folly/String.h>
#include <folly/Synchronized.h>
#include <folly/stop_watch.h>
namespace facebook {
namespace eden {
/**
* Represents a request tracked in a RequestMetricsScope::RequestWatchList.
* To track a request a RequestMetricsScope object should be in scope for the
* duration of the request.
*
* The scope inserts a watch into the given list on construction and removes
* that watch on destruction.
*/
class RequestMetricsScope {
public:
using RequestWatchList = std::list<folly::stop_watch<>>;
using LockedRequestWatchList = folly::Synchronized<RequestWatchList>;
using DefaultRequestDuration =
std::chrono::steady_clock::steady_clock::duration;
RequestMetricsScope(LockedRequestWatchList* pendingRequestWatches);
RequestMetricsScope();
RequestMetricsScope(RequestMetricsScope&&) noexcept;
RequestMetricsScope& operator=(RequestMetricsScope&&);
RequestMetricsScope(const RequestMetricsScope&) = delete;
RequestMetricsScope& operator=(const RequestMetricsScope&) = delete;
~RequestMetricsScope();
/**
* Metrics to calculated for any type of request tracked with
* RequestMetricsScope
*/
enum RequestMetric {
// number of requests
COUNT,
// duration of the longest current import
MAX_DURATION_US,
};
constexpr static std::array<RequestMetric, 2> requestMetrics{
RequestMetric::COUNT,
RequestMetric::MAX_DURATION_US};
static folly::StringPiece stringOfRequestMetric(RequestMetric metric);
/**
* stages of requests that are tracked, these represent where an request is in
* the process (for example an request could be queued or live)
*/
enum RequestStage {
// represents any request that has been requested but not yet completed
// (request in this stage could be in the queue, live, or in the case of
// hg store imports fetching from cache
PENDING,
// represents request that are currently being executed (in the case of
// hg imports, only those fetching data, this does not include those reading
// from cache)
LIVE,
};
constexpr static std::array<RequestStage, 2> requestStages{
RequestStage::PENDING,
RequestStage::LIVE};
static folly::StringPiece stringOfHgImportStage(RequestStage stage);
static folly::StringPiece stringOfFuseRequestStage(RequestStage stage);
/**
* combine the values of the counters in a way that makes sense
* for the `metric` being calculated
*/
static size_t aggregateMetricCounters(
RequestMetricsScope::RequestMetric metric,
std::vector<size_t>& counters);
/**
* calculates the `metric` from the `watches` which track
* the duration of all of a certain type of request
*/
static size_t getMetricFromWatches(
RequestMetric metric,
const LockedRequestWatchList& watches);
/**
* finds the watch in `watches` for which the time that has elapsed
* is the greatest and returns the duration of time that has elapsed
*/
static DefaultRequestDuration getMaxDuration(
const LockedRequestWatchList& watches);
private:
LockedRequestWatchList* pendingRequestWatches_;
RequestWatchList::iterator requestWatch_;
}; // namespace eden
} // namespace eden
} // namespace facebook