blob: 11a7fc66b4fa8742e8e76354f3aa817d2a2ef94f [file] [log] [blame]
// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DNS_PROXY_METRICS_H_
#define DNS_PROXY_METRICS_H_
#include <utility>
#include <vector>
#include <metrics/metrics_library.h>
#include <metrics/timer.h>
namespace dns_proxy {
class Metrics {
public:
// This is not an UMA enum type.
enum class ProcessType {
kController,
kProxySystem,
kProxyDefault,
kProxyARC,
};
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class ProcessEvent {
kProxyLaunchSuccess = 0,
kProxyLaunchFailure = 1,
kProxyKillFailure = 2,
kProxyKilled = 3,
kProxyStopped = 4,
kProxyContinued = 5,
kProxyMissing = 6,
kCapNetBindServiceError = 7,
kPatchpanelNotInitialized = 8,
kPatchpanelNotReady = 9,
kPatchpanelReset = 10,
kPatchpanelShutdown = 11,
kPatchpanelNoNamespace = 12,
kPatchpanelNoRedirect = 13,
kShillNotReady = 14,
kShillReset = 15,
kShillShutdown = 16,
kShillSetProxyAddressRetryExceeded = 17,
kChromeFeaturesNotInitialized = 18,
kResolverListenUDPFailure = 19,
kResolverListenTCPFailure = 20,
kMaxValue = kResolverListenTCPFailure,
};
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class NameserverType {
kNone = 0,
kIPv4 = 1,
kIPv6 = 2,
kBoth = 3,
kMaxValue = kBoth,
};
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class DnsOverHttpsMode {
kUnknown = 0,
kOff = 1,
kAutomatic = 2,
kAlwaysOn = 3,
kMaxValue = kAlwaysOn,
};
// This is not an UMA enum type.
enum class QueryType {
kPlainText = 0,
kDnsOverHttps = 1,
};
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class QueryResult {
kFailure = 0,
kSuccess = 1,
kMaxValue = kSuccess,
};
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class QueryError {
kNone = 0,
kDomainNotFound = 1,
kNoData = 2,
kBadQuery = 3,
kQueryRefused = 4,
kQueryTimeout = 5,
kQueryCanceled = 6,
kConnectionRefused = 7,
kConnectionFailed = 8,
kUnsupportedProtocol = 9,
kNotImplemented = 10,
kInvalidURL = 11,
kBadHost = 12,
kTooManyRedirects = 13,
kSendError = 14,
kReceiveError = 15,
kOtherClientError = 16,
kOtherServerError = 17,
kMaxValue = kOtherServerError,
};
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class HttpError {
kNone = 0,
kAnyRedirect = 1,
kBadRequest = 2,
kPayloadTooLarge = 3,
kURITooLong = 4,
kUnsupportedMediaType = 5,
kTooManyRequests = 6,
kOtherClientError = 7,
kNotImplemented = 8,
kBadGateway = 9,
kOtherServerError = 10,
kMaxValue = kOtherServerError,
};
// Helper class for measuring time elapsed during different stages of the
// name resolution process. Accumulates stage timings for later use so that
// logging metrics do not impact the time spans with i/o overhead.
class QueryTimer {
public:
QueryTimer() = default;
QueryTimer(const QueryTimer&) = delete;
QueryTimer& operator=(const QueryTimer&) = delete;
~QueryTimer();
// Measure time elapsed reading query from client.
// This should be called first to begin the internal timer.
void StartReceive();
void StopReceive(bool success);
// Measure time elapsed spanning the entire resolution step,
// which may include multiple client calls or retries.
void StartResolve(bool is_doh = false);
void StopResolve(bool success);
// Measure time elapsed sending the reply to the client.
void StartReply();
void StopReply(bool success);
// Records all available metrics.
void Record(Metrics* metrics);
void set_metrics(Metrics* metrics);
private:
struct resolv_t_ {
bool success;
Metrics::QueryType type;
base::TimeDelta elapsed;
};
void Stop();
Metrics* metrics_{nullptr};
chromeos_metrics::Timer timer_;
std::pair<bool, base::TimeDelta> elapsed_recv_;
std::vector<resolv_t_> elapsed_resolve_;
std::pair<bool, base::TimeDelta> elapsed_reply_;
base::TimeDelta elapsed_total_;
};
Metrics() = default;
Metrics(const Metrics&) = delete;
~Metrics() = default;
Metrics& operator=(const Metrics&) = delete;
void RecordProcessEvent(ProcessType type, ProcessEvent event);
void RecordNameservers(unsigned int num_ipv4, unsigned int num_ipv6);
void RecordDnsOverHttpsMode(DnsOverHttpsMode mode);
void RecordQueryResult(QueryType type, QueryError error, int http_code = -1);
void RecordQueryDuration(const char* stage, int64_t ms, bool success = true);
void RecordQueryResolveDuration(QueryType type,
int64_t ms,
bool success = true);
private:
MetricsLibrary metrics_;
};
} // namespace dns_proxy
#endif // DNS_PROXY_METRICS_H_