metrics

package
v4.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 26, 2024 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Index

Constants

View Source
const (
	WsDisconnectionReasonConsumer = "consumer-disconnect"
	WsDisconnectionReasonProvider = "provider-disconnect"
	WsDisconnectionReasonUser     = "user-disconnect"
)
View Source
const (
	AvailabilityLabel = "availability"
	SyncLabel         = "sync/freshness"
	LatencyLabel      = "latency"
)
View Source
const (
	MetricsListenFlagName    = "metrics-listen-address"
	AddApiMethodCallsMetrics = "add-api-method-metrics"
	RelayServerFlagName      = "relay-server-address"
	DisabledFlagOption       = "disabled"
)
View Source
const (
	RefererHeaderKey   = "Referer"
	OriginHeaderKey    = "Origin"
	UserAgentHeaderKey = "User-Agent"
)

Variables

View Source
var (
	OptimizerQosServerPushInterval     time.Duration
	OptimizerQosServerSamplingInterval time.Duration
)
View Source
var ReturnMaskedErrors = "false"

Functions

func SetVersionInner

func SetVersionInner(protocolVersionMetric *prometheus.GaugeVec, version string)

Types

type AggregatedMetric

type AggregatedMetric struct {
	TotalLatency uint64
	RelaysCount  int64
	SuccessCount int64
	TotalCu      uint64
	TimeStamp    time.Time
}

type ConflictContainer

type ConflictContainer struct {
	Request pairingtypes.RelayRequest `json:"request"`
	Reply   pairingtypes.RelayReply   `json:"reply"`
}

type ConflictRequest

type ConflictRequest struct {
	Name      string              `json:"name"`
	Conflicts []ConflictContainer `json:"conflicts"`
}

func (ConflictRequest) String

func (rr ConflictRequest) String() string

type ConsumerMetricsManager

type ConsumerMetricsManager struct {
	LatestBlockMetric   *prometheus.GaugeVec
	LatestProviderRelay *prometheus.GaugeVec
	// contains filtered or unexported fields
}

func (*ConsumerMetricsManager) ResetSessionRelatedMetrics

func (pme *ConsumerMetricsManager) ResetSessionRelatedMetrics()

func (*ConsumerMetricsManager) SetBlock

func (pme *ConsumerMetricsManager) SetBlock(block int64)

func (*ConsumerMetricsManager) SetDuplicatedWsSubscriptionRequestMetric

func (pme *ConsumerMetricsManager) SetDuplicatedWsSubscriptionRequestMetric(chainId string, apiInterface string)

func (*ConsumerMetricsManager) SetFailedWsSubscriptionRequestMetric

func (pme *ConsumerMetricsManager) SetFailedWsSubscriptionRequestMetric(chainId string, apiInterface string)

func (*ConsumerMetricsManager) SetNodeErrorAttemptMetric

func (pme *ConsumerMetricsManager) SetNodeErrorAttemptMetric(chainId string, apiInterface string)

func (*ConsumerMetricsManager) SetNodeErrorRecoveredSuccessfullyMetric

func (pme *ConsumerMetricsManager) SetNodeErrorRecoveredSuccessfullyMetric(chainId string, apiInterface string, attempt string)

func (*ConsumerMetricsManager) SetQOSMetrics

func (pme *ConsumerMetricsManager) SetQOSMetrics(chainId string, apiInterface string, providerAddress string, qos *pairingtypes.QualityOfServiceReport, qosExcellence *pairingtypes.QualityOfServiceReport, latestBlock int64, relays uint64, relayLatency time.Duration, sessionSuccessful bool)

func (*ConsumerMetricsManager) SetRelayMetrics

func (pme *ConsumerMetricsManager) SetRelayMetrics(relayMetric *RelayMetrics, err error)

func (*ConsumerMetricsManager) SetRelayNodeErrorMetric

func (pme *ConsumerMetricsManager) SetRelayNodeErrorMetric(chainId string, apiInterface string)

func (*ConsumerMetricsManager) SetRelayProcessingLatencyAfterProvider

func (pme *ConsumerMetricsManager) SetRelayProcessingLatencyAfterProvider(latency time.Duration, chainId string, apiInterface string)

func (*ConsumerMetricsManager) SetRelayProcessingLatencyBeforeProvider

func (pme *ConsumerMetricsManager) SetRelayProcessingLatencyBeforeProvider(latency time.Duration, chainId string, apiInterface string)

func (*ConsumerMetricsManager) SetRelaySentByNewBatchTickerMetric

func (pme *ConsumerMetricsManager) SetRelaySentByNewBatchTickerMetric(chainId string, apiInterface string)

func (*ConsumerMetricsManager) SetRelaySentToProviderMetric

func (pme *ConsumerMetricsManager) SetRelaySentToProviderMetric(chainId string, apiInterface string)

func (*ConsumerMetricsManager) SetVersion

func (pme *ConsumerMetricsManager) SetVersion(version string)

func (*ConsumerMetricsManager) SetVirtualEpoch

func (pme *ConsumerMetricsManager) SetVirtualEpoch(virtualEpoch uint64)

func (*ConsumerMetricsManager) SetWebSocketConnectionActive

func (pme *ConsumerMetricsManager) SetWebSocketConnectionActive(chainId string, apiInterface string, add bool)

func (*ConsumerMetricsManager) SetWsSubscriptioDisconnectRequestMetric

func (pme *ConsumerMetricsManager) SetWsSubscriptioDisconnectRequestMetric(chainId string, apiInterface string, disconnectReason string)

func (*ConsumerMetricsManager) SetWsSubscriptionRequestMetric

func (pme *ConsumerMetricsManager) SetWsSubscriptionRequestMetric(chainId string, apiInterface string)

func (*ConsumerMetricsManager) UpdateHealthCheckStatus

func (pme *ConsumerMetricsManager) UpdateHealthCheckStatus(status bool)

type ConsumerMetricsManagerOptions

type ConsumerMetricsManagerOptions struct {
	NetworkAddress             string
	AddMethodsApiGauge         bool
	EnableQoSListener          bool
	ConsumerOptimizerQoSClient *ConsumerOptimizerQoSClient
}

type ConsumerOptimizerQoSClient

type ConsumerOptimizerQoSClient struct {
	// contains filtered or unexported fields
}

func NewConsumerOptimizerQoSClient

func NewConsumerOptimizerQoSClient(endpointAddress string, interval ...time.Duration) *ConsumerOptimizerQoSClient

func (*ConsumerOptimizerQoSClient) GetReportsToSend added in v4.1.3

func (coqc *ConsumerOptimizerQoSClient) GetReportsToSend() []OptimizerQoSReportToSend

func (*ConsumerOptimizerQoSClient) RegisterOptimizer

func (coqc *ConsumerOptimizerQoSClient) RegisterOptimizer(optimizer OptimizerInf, chainId string)

func (*ConsumerOptimizerQoSClient) SetNodeErrorToProvider

func (coqc *ConsumerOptimizerQoSClient) SetNodeErrorToProvider(providerAddress string, chainId string)

func (*ConsumerOptimizerQoSClient) SetRelaySentToProvider

func (coqc *ConsumerOptimizerQoSClient) SetRelaySentToProvider(providerAddress string, chainId string)

func (*ConsumerOptimizerQoSClient) SetReportsToSend added in v4.1.3

func (coqc *ConsumerOptimizerQoSClient) SetReportsToSend(reports []OptimizerQoSReportToSend)

func (*ConsumerOptimizerQoSClient) StartOptimizersQoSReportsCollecting

func (coqc *ConsumerOptimizerQoSClient) StartOptimizersQoSReportsCollecting(ctx context.Context, samplingInterval time.Duration)

func (*ConsumerOptimizerQoSClient) UpdatePairingListStake

func (coqc *ConsumerOptimizerQoSClient) UpdatePairingListStake(stakeMap map[string]int64, chainId string, epoch uint64)

type ConsumerReferrerClient

type ConsumerReferrerClient struct {
	*QueueSender
}

func NewConsumerReferrerClient

func NewConsumerReferrerClient(endpointAddress string, interval ...time.Duration) *ConsumerReferrerClient

func (*ConsumerReferrerClient) AppendReferrer

func (cuc *ConsumerReferrerClient) AppendReferrer(referrer ReferrerRequest)

type ConsumerRelayServerClient

type ConsumerRelayServerClient struct {
	// contains filtered or unexported fields
}

func NewConsumerRelayServerClient

func NewConsumerRelayServerClient(endPointAddress string) *ConsumerRelayServerClient

func (*ConsumerRelayServerClient) SetRelayMetrics

func (cuc *ConsumerRelayServerClient) SetRelayMetrics(relayMetric *RelayMetrics)

type ConsumerReportsClient

type ConsumerReportsClient struct {
	*QueueSender
}

func NewConsumerReportsClient

func NewConsumerReportsClient(endpointAddress string, interval ...time.Duration) *ConsumerReportsClient

func (*ConsumerReportsClient) AppendConflict

func (cuc *ConsumerReportsClient) AppendConflict(report ConflictRequest)

func (*ConsumerReportsClient) AppendReport

func (cuc *ConsumerReportsClient) AppendReport(report ReportsRequest)

type HealthCheckUpdatable

type HealthCheckUpdatable interface {
	UpdateHealthCheckStatus(status bool)
}

type HealthMetrics

type HealthMetrics struct {
	// contains filtered or unexported fields
}

func NewHealthMetrics

func NewHealthMetrics(networkAddress string) *HealthMetrics

func (*HealthMetrics) SetAlertResults

func (pme *HealthMetrics) SetAlertResults(label string, fails uint64, unhealthy uint64, healthy uint64)

func (*HealthMetrics) SetFailedRun

func (pme *HealthMetrics) SetFailedRun(label string)

func (*HealthMetrics) SetLatestBlockData

func (pme *HealthMetrics) SetLatestBlockData(label string, data map[string]uint64)

func (*HealthMetrics) SetSuccess

func (pme *HealthMetrics) SetSuccess(label string)

type LatencyTracker

type LatencyTracker struct {
	AverageLatency time.Duration // in nano seconds (time.Since result)
	TotalRequests  int
}

func (*LatencyTracker) AddLatency

func (lt *LatencyTracker) AddLatency(latency time.Duration)

type MetricService

type MetricService struct {
	AggregatedMetricMap *map[string]map[string]map[string]map[RelaySource]map[string]*AggregatedMetric
	MetricsChannel      chan RelayMetrics
	ReportUrl           string
	ReportAuthorization string
}

func NewMetricService

func NewMetricService() *MetricService

func (*MetricService) SendData

func (m *MetricService) SendData(data RelayMetrics)

func (*MetricService) SendEachProjectMetricData

func (m *MetricService) SendEachProjectMetricData()

type OptimizerInf

type OptimizerInf interface {
	CalculateQoSScoresForMetrics(allAddresses []string, ignoredProviders map[string]struct{}, cu uint64, requestedBlock int64) []*OptimizerQoSReport
}

type OptimizerQoSReport

type OptimizerQoSReport struct {
	ProviderAddress   string
	SyncScore         float64
	AvailabilityScore float64
	LatencyScore      float64
	GenericScore      float64
	EntryIndex        int
}

type OptimizerQoSReportToSend added in v4.1.3

type OptimizerQoSReportToSend struct {
	Timestamp         time.Time `json:"timestamp"`
	SyncScore         float64   `json:"sync_score"`
	AvailabilityScore float64   `json:"availability_score"`
	LatencyScore      float64   `json:"latency_score"`
	GenericScore      float64   `json:"generic_score"`
	ProviderAddress   string    `json:"provider"`
	ConsumerOrigin    string    `json:"consumer"`
	ChainId           string    `json:"chain_id"`
	NodeErrorRate     float64   `json:"node_error_rate"`
	Epoch             uint64    `json:"epoch"`
	ProviderStake     int64     `json:"provider_stake"`
	EntryIndex        int       `json:"entry_index"`
}

func (OptimizerQoSReportToSend) String added in v4.1.3

func (oqosr OptimizerQoSReportToSend) String() string

type ProviderMetrics

type ProviderMetrics struct {
	// contains filtered or unexported fields
}

func NewProviderMetrics

func NewProviderMetrics(specID, apiInterface string, totalCUServicedMetric *prometheus.CounterVec,
	totalCUPaidMetric *prometheus.CounterVec,
	totalRelaysServicedMetric *prometheus.CounterVec,
	totalErroredMetric *prometheus.CounterVec,
	consumerQoSMetric *prometheus.GaugeVec,
	loadRateMetric *prometheus.GaugeVec,
) *ProviderMetrics

func (*ProviderMetrics) AddError

func (pm *ProviderMetrics) AddError()

func (*ProviderMetrics) AddPayment

func (pm *ProviderMetrics) AddPayment(cu uint64)

func (*ProviderMetrics) AddRelay

func (pm *ProviderMetrics) AddRelay(consumerAddress string, cu uint64, qos *pairingtypes.QualityOfServiceReport)

func (*ProviderMetrics) SetLoadRate added in v4.1.0

func (pm *ProviderMetrics) SetLoadRate(loadRate float64)

type ProviderMetricsManager

type ProviderMetricsManager struct {
	// contains filtered or unexported fields
}

func NewProviderMetricsManager

func NewProviderMetricsManager(networkAddress string) *ProviderMetricsManager

func (*ProviderMetricsManager) AddPayment

func (pme *ProviderMetricsManager) AddPayment(specID string, cu uint64)

func (*ProviderMetricsManager) AddProviderMetrics

func (pme *ProviderMetricsManager) AddProviderMetrics(specID, apiInterface string) *ProviderMetrics

func (*ProviderMetricsManager) RegisterRelaysMonitor

func (pme *ProviderMetricsManager) RegisterRelaysMonitor(chainID, apiInterface string, relaysMonitor *RelaysMonitor)

func (*ProviderMetricsManager) SetBlock

func (pme *ProviderMetricsManager) SetBlock(latestLavaBlock int64)

func (*ProviderMetricsManager) SetDisabledChain

func (pme *ProviderMetricsManager) SetDisabledChain(specID string, apInterface string)

func (*ProviderMetricsManager) SetEnabledChain

func (pme *ProviderMetricsManager) SetEnabledChain(specID string, apInterface string)

func (*ProviderMetricsManager) SetFrozenStatus added in v4.1.0

func (pme *ProviderMetricsManager) SetFrozenStatus(chain string, frozen bool)

func (*ProviderMetricsManager) SetJailStatus added in v4.1.0

func (pme *ProviderMetricsManager) SetJailStatus(chain string, jailed bool)

func (*ProviderMetricsManager) SetJailedCount added in v4.1.0

func (pme *ProviderMetricsManager) SetJailedCount(chain string, jailedCount uint64)

func (*ProviderMetricsManager) SetLatestBlock

func (pme *ProviderMetricsManager) SetLatestBlock(specID string, block uint64)

func (*ProviderMetricsManager) SetLatestBlockFetchError

func (pme *ProviderMetricsManager) SetLatestBlockFetchError(specID string)

func (*ProviderMetricsManager) SetLatestBlockFetchSuccess

func (pme *ProviderMetricsManager) SetLatestBlockFetchSuccess(specID string)

func (*ProviderMetricsManager) SetSpecificBlockFetchError

func (pme *ProviderMetricsManager) SetSpecificBlockFetchError(specID string)

func (*ProviderMetricsManager) SetSpecificBlockFetchSuccess

func (pme *ProviderMetricsManager) SetSpecificBlockFetchSuccess(specID string)

func (*ProviderMetricsManager) SetVersion

func (pme *ProviderMetricsManager) SetVersion(version string)

func (*ProviderMetricsManager) SetVirtualEpoch

func (pme *ProviderMetricsManager) SetVirtualEpoch(virtualEpoch uint64)

func (*ProviderMetricsManager) UpdateHealthCheckStatus

func (pme *ProviderMetricsManager) UpdateHealthCheckStatus(status bool)

type QueueSender

type QueueSender struct {
	// contains filtered or unexported fields
}

func NewQueueSender

func NewQueueSender(endpointAddress string, name string, aggregationFunction func([]fmt.Stringer) []fmt.Stringer, interval ...time.Duration) *QueueSender

type RPCConsumerLogs

type RPCConsumerLogs struct {
	MetricService   *MetricService
	StoreMetricData bool
	// contains filtered or unexported fields
}

func NewRPCConsumerLogs

func NewRPCConsumerLogs(consumerMetricsManager *ConsumerMetricsManager, consumerRelayServerClient *ConsumerRelayServerClient, consumerOptimizerQoSClient *ConsumerOptimizerQoSClient) (*RPCConsumerLogs, error)

func (*RPCConsumerLogs) AddMetricForGrpc

func (rpccl *RPCConsumerLogs) AddMetricForGrpc(data *RelayMetrics, err error, metadataValues *metadata.MD)

func (*RPCConsumerLogs) AddMetricForHttp

func (rpccl *RPCConsumerLogs) AddMetricForHttp(data *RelayMetrics, err error, headers map[string][]string)

func (*RPCConsumerLogs) AddMetricForProcessingLatencyAfterProvider

func (rpccl *RPCConsumerLogs) AddMetricForProcessingLatencyAfterProvider(analytics *RelayMetrics, chainId string, apiInterface string)

func (*RPCConsumerLogs) AddMetricForProcessingLatencyBeforeProvider

func (rpccl *RPCConsumerLogs) AddMetricForProcessingLatencyBeforeProvider(analytics *RelayMetrics, chainId string, apiInterface string)

AddMetricForProcessingLatencyBeforeProvider adds a time calculation metric for the consumer's processing time before sending a relay to a provider it returns whether the latency was added or not

func (*RPCConsumerLogs) AddMetricForWebSocket

func (rpccl *RPCConsumerLogs) AddMetricForWebSocket(data *RelayMetrics, err error, c *websocket.Conn)

func (*RPCConsumerLogs) AnalyzeWebSocketErrorAndGetFormattedMessage

func (rpccl *RPCConsumerLogs) AnalyzeWebSocketErrorAndGetFormattedMessage(webSocketAddr string, err error, msgSeed string, msg []byte, rpcType string, timeTaken time.Duration) []byte

Websocket healthy disconnections throw "websocket: close 1005 (no status)" error, We don't want to alert error monitoring for that purpses.

func (*RPCConsumerLogs) GetMessageSeed

func (rpccl *RPCConsumerLogs) GetMessageSeed() string

func (*RPCConsumerLogs) GetUniqueGuidResponseForError

func (rpccl *RPCConsumerLogs) GetUniqueGuidResponseForError(responseError error, msgSeed string) string

Input will be masked with a random GUID if returnMaskedErrors is set to true

func (*RPCConsumerLogs) LogRequestAndResponse

func (rpccl *RPCConsumerLogs) LogRequestAndResponse(module string, hasError bool, method, path, req, resp, msgSeed string, timeTaken time.Duration, err error)

func (*RPCConsumerLogs) LogStartTransaction

func (rpccl *RPCConsumerLogs) LogStartTransaction(name string) func()

func (*RPCConsumerLogs) LogTestMode

func (rpccl *RPCConsumerLogs) LogTestMode(fiberCtx *fiber.Ctx)

func (*RPCConsumerLogs) SendMetrics

func (rpccl *RPCConsumerLogs) SendMetrics(data *RelayMetrics, err error, origin string)

func (*RPCConsumerLogs) SetNodeErrorAttemptMetric

func (rpccl *RPCConsumerLogs) SetNodeErrorAttemptMetric(chainId string, apiInterface string)

func (*RPCConsumerLogs) SetNodeErrorRecoveredSuccessfullyMetric

func (rpccl *RPCConsumerLogs) SetNodeErrorRecoveredSuccessfullyMetric(chainId string, apiInterface string, attempt string)

func (*RPCConsumerLogs) SetRelayNodeErrorMetric

func (rpccl *RPCConsumerLogs) SetRelayNodeErrorMetric(providerAddress, chainId, apiInterface string)

func (*RPCConsumerLogs) SetRelaySentByNewBatchTickerMetric

func (rpccl *RPCConsumerLogs) SetRelaySentByNewBatchTickerMetric(chainId string, apiInterface string)

func (*RPCConsumerLogs) SetRelaySentToProviderMetric

func (rpccl *RPCConsumerLogs) SetRelaySentToProviderMetric(providerAddress, chainId, apiInterface string)

func (*RPCConsumerLogs) SetWebSocketConnectionActive

func (rpccl *RPCConsumerLogs) SetWebSocketConnectionActive(chainId string, apiInterface string, add bool)

type ReferrerRequest

type ReferrerRequest struct {
	ReferrerId string `json:"referer-id"`
	Name       string `json:"name"`
	Count      uint64 `json:"count"`
	ChainId    string `json:"chain-id"`
	Msg        string `json:"msg"`
	Referer    string `json:"http-referer"`
	Origin     string `json:"origin"`
	UserAgent  string `json:"user-agent"`
	UserIp     string `json:"user-ip"`
}

func NewReferrerRequest

func NewReferrerRequest(referrerId string, chainId string, msg string, referer string, origin string, userAgent string, userIp string) ReferrerRequest

func (ReferrerRequest) String

func (rr ReferrerRequest) String() string

type ReferrerSender

type ReferrerSender interface {
	AppendReferrer(referrer ReferrerRequest)
}

type RelayAnalyticsDTO

type RelayAnalyticsDTO struct {
	ProjectHash  string
	Timestamp    string
	ChainID      string
	APIType      string
	Latency      uint64
	SuccessCount int64
	RelayCounts  int64
	TotalCu      uint64
	Source       RelaySource
	Origin       string
}

type RelayMetrics

type RelayMetrics struct {
	ProjectHash                        string
	Timestamp                          time.Time
	ChainID                            string
	APIType                            string
	Latency                            int64
	Success                            bool
	ComputeUnits                       uint64
	Source                             RelaySource
	Origin                             string
	ApiMethod                          string
	ProcessingTimestamp                time.Time
	MeasureAfterProviderProcessingTime bool // we measure processing time only on first relay success so we use this to indicate that the after provider measurement should occur (not true for all code flows)
}

func NewRelayAnalytics

func NewRelayAnalytics(projectHash, chainId, apiType string) *RelayMetrics

func (*RelayMetrics) SetProcessingTimestampAfterRelay

func (rm *RelayMetrics) SetProcessingTimestampAfterRelay(timestamp time.Time)

func (*RelayMetrics) SetProcessingTimestampBeforeRelay

func (rm *RelayMetrics) SetProcessingTimestampBeforeRelay(timestamp time.Time)

type RelaySource

type RelaySource int
const (
	SdkSource RelaySource = iota + 1
	GatewaySource
	BadgesSource
)

type RelaysMonitor

type RelaysMonitor struct {
	// contains filtered or unexported fields
}

func NewRelaysMonitor

func NewRelaysMonitor(interval time.Duration, chainID, apiInterface string) *RelaysMonitor

func (*RelaysMonitor) IsHealthy

func (sem *RelaysMonitor) IsHealthy() bool

func (*RelaysMonitor) LogRelay

func (sem *RelaysMonitor) LogRelay()

func (*RelaysMonitor) SetRelaySender

func (sem *RelaysMonitor) SetRelaySender(relaySender func() (bool, error))

func (*RelaysMonitor) Start

func (sem *RelaysMonitor) Start(ctx context.Context)

type RelaysMonitorAggregator

type RelaysMonitorAggregator struct {
	// contains filtered or unexported fields
}

func NewRelaysMonitorAggregator

func NewRelaysMonitorAggregator(interval time.Duration, rpcConsumerLogs HealthCheckUpdatable) *RelaysMonitorAggregator

func (*RelaysMonitorAggregator) RegisterRelaysMonitor

func (rma *RelaysMonitorAggregator) RegisterRelaysMonitor(rpcEndpointKey string, relaysMonitor *RelaysMonitor)

func (*RelaysMonitorAggregator) StartMonitoring

func (rma *RelaysMonitorAggregator) StartMonitoring(ctx context.Context)

type Reporter

type Reporter interface {
	AppendReport(report ReportsRequest)
	AppendConflict(report ConflictRequest)
}

type ReportsRequest

type ReportsRequest struct {
	Name     string `json:"name"`
	Errors   string `json:"errors"`
	Provider string `json:"provider"`
	SpecId   string `json:"spec_id"`
}

func NewReportsRequest

func NewReportsRequest(provider string, errors []error, specId string) ReportsRequest

func (ReportsRequest) String

func (rr ReportsRequest) String() string

type UpdateMetricsRequest

type UpdateMetricsRequest struct {
	RecordDate      string `json:"RecordDate"`
	Hash            string `json:"Hash"`
	Chain           string `json:"Chain"`
	ApiType         string `json:"ApiType"`
	RelaysInc       uint64 `json:"RelaysInc"`
	CuInc           int    `json:"CuInc"`
	LatencyToAdd    uint64 `json:"LatencyToAdd"`
	LatencyAvgCount int    `json:"LatencyAvgCount"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL