Skip to content

Commit

Permalink
Collect Prometheus Go process metrics (prebid#2101)
Browse files Browse the repository at this point in the history
  • Loading branch information
guscarreon authored Dec 9, 2021
1 parent 29239dc commit 5bb455c
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 49 deletions.
104 changes: 57 additions & 47 deletions metrics/prometheus/prometheus.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
package prometheusmetrics

import (
"fmt"
"strconv"
"time"

"github.com/prebid/prebid-server/config"
"github.com/prebid/prebid-server/metrics"
"github.com/prebid/prebid-server/openrtb_ext"
"github.com/prometheus/client_golang/prometheus"
promCollector "github.com/prometheus/client_golang/prometheus/collectors"
)

// Metrics defines the Prometheus metrics backing the MetricsEngine implementation.
type Metrics struct {
Registry *prometheus.Registry
Registerer prometheus.Registerer
Gatherer *prometheus.Registry

// General Metrics
connectionsClosed prometheus.Counter
Expand Down Expand Up @@ -133,246 +136,253 @@ func NewMetrics(cfg config.PrometheusMetrics, disabledMetrics config.DisabledMet
queuedRequestTimeBuckets := []float64{0, 1, 5, 30, 60, 120, 180, 240, 300}

metrics := Metrics{}
metrics.Registry = prometheus.NewRegistry()
reg := prometheus.NewRegistry()
metrics.metricsDisabled = disabledMetrics

metrics.connectionsClosed = newCounterWithoutLabels(cfg, metrics.Registry,
metrics.connectionsClosed = newCounterWithoutLabels(cfg, reg,
"connections_closed",
"Count of successful connections closed to Prebid Server.")

metrics.connectionsError = newCounter(cfg, metrics.Registry,
metrics.connectionsError = newCounter(cfg, reg,
"connections_error",
"Count of errors for connection open and close attempts to Prebid Server labeled by type.",
[]string{connectionErrorLabel})

metrics.connectionsOpened = newCounterWithoutLabels(cfg, metrics.Registry,
metrics.connectionsOpened = newCounterWithoutLabels(cfg, reg,
"connections_opened",
"Count of successful connections opened to Prebid Server.")

metrics.cookieSync = newCounter(cfg, metrics.Registry,
metrics.cookieSync = newCounter(cfg, reg,
"cookie_sync_requests",
"Count of cookie sync requests to Prebid Server.",
[]string{statusLabel})

metrics.setUid = newCounter(cfg, metrics.Registry,
metrics.setUid = newCounter(cfg, reg,
"setuid_requests",
"Count of set uid requests to Prebid Server.",
[]string{statusLabel})

metrics.impressions = newCounter(cfg, metrics.Registry,
metrics.impressions = newCounter(cfg, reg,
"impressions_requests",
"Count of requested impressions to Prebid Server labeled by type.",
[]string{isBannerLabel, isVideoLabel, isAudioLabel, isNativeLabel})

metrics.impressionsLegacy = newCounterWithoutLabels(cfg, metrics.Registry,
metrics.impressionsLegacy = newCounterWithoutLabels(cfg, reg,
"impressions_requests_legacy",
"Count of requested impressions to Prebid Server using the legacy endpoint.")

metrics.prebidCacheWriteTimer = newHistogramVec(cfg, metrics.Registry,
metrics.prebidCacheWriteTimer = newHistogramVec(cfg, reg,
"prebidcache_write_time_seconds",
"Seconds to write to Prebid Cache labeled by success or failure. Failure timing is limited by Prebid Server enforced timeouts.",
[]string{successLabel},
cacheWriteTimeBuckets)

metrics.requests = newCounter(cfg, metrics.Registry,
metrics.requests = newCounter(cfg, reg,
"requests",
"Count of total requests to Prebid Server labeled by type and status.",
[]string{requestTypeLabel, requestStatusLabel})

metrics.requestsTimer = newHistogramVec(cfg, metrics.Registry,
metrics.requestsTimer = newHistogramVec(cfg, reg,
"request_time_seconds",
"Seconds to resolve successful Prebid Server requests labeled by type.",
[]string{requestTypeLabel},
standardTimeBuckets)

metrics.requestsWithoutCookie = newCounter(cfg, metrics.Registry,
metrics.requestsWithoutCookie = newCounter(cfg, reg,
"requests_without_cookie",
"Count of total requests to Prebid Server without a cookie labeled by type.",
[]string{requestTypeLabel})

metrics.storedImpressionsCacheResult = newCounter(cfg, metrics.Registry,
metrics.storedImpressionsCacheResult = newCounter(cfg, reg,
"stored_impressions_cache_performance",
"Count of stored impression cache requests attempts by hits or miss.",
[]string{cacheResultLabel})

metrics.storedRequestCacheResult = newCounter(cfg, metrics.Registry,
metrics.storedRequestCacheResult = newCounter(cfg, reg,
"stored_request_cache_performance",
"Count of stored request cache requests attempts by hits or miss.",
[]string{cacheResultLabel})

metrics.accountCacheResult = newCounter(cfg, metrics.Registry,
metrics.accountCacheResult = newCounter(cfg, reg,
"account_cache_performance",
"Count of account cache lookups by hits or miss.",
[]string{cacheResultLabel})

metrics.storedAccountFetchTimer = newHistogramVec(cfg, metrics.Registry,
metrics.storedAccountFetchTimer = newHistogramVec(cfg, reg,
"stored_account_fetch_time_seconds",
"Seconds to fetch stored accounts labeled by fetch type",
[]string{storedDataFetchTypeLabel},
standardTimeBuckets)

metrics.storedAccountErrors = newCounter(cfg, metrics.Registry,
metrics.storedAccountErrors = newCounter(cfg, reg,
"stored_account_errors",
"Count of stored account errors by error type",
[]string{storedDataErrorLabel})

metrics.storedAMPFetchTimer = newHistogramVec(cfg, metrics.Registry,
metrics.storedAMPFetchTimer = newHistogramVec(cfg, reg,
"stored_amp_fetch_time_seconds",
"Seconds to fetch stored AMP requests labeled by fetch type",
[]string{storedDataFetchTypeLabel},
standardTimeBuckets)

metrics.storedAMPErrors = newCounter(cfg, metrics.Registry,
metrics.storedAMPErrors = newCounter(cfg, reg,
"stored_amp_errors",
"Count of stored AMP errors by error type",
[]string{storedDataErrorLabel})

metrics.storedCategoryFetchTimer = newHistogramVec(cfg, metrics.Registry,
metrics.storedCategoryFetchTimer = newHistogramVec(cfg, reg,
"stored_category_fetch_time_seconds",
"Seconds to fetch stored categories labeled by fetch type",
[]string{storedDataFetchTypeLabel},
standardTimeBuckets)

metrics.storedCategoryErrors = newCounter(cfg, metrics.Registry,
metrics.storedCategoryErrors = newCounter(cfg, reg,
"stored_category_errors",
"Count of stored category errors by error type",
[]string{storedDataErrorLabel})

metrics.storedRequestFetchTimer = newHistogramVec(cfg, metrics.Registry,
metrics.storedRequestFetchTimer = newHistogramVec(cfg, reg,
"stored_request_fetch_time_seconds",
"Seconds to fetch stored requests labeled by fetch type",
[]string{storedDataFetchTypeLabel},
standardTimeBuckets)

metrics.storedRequestErrors = newCounter(cfg, metrics.Registry,
metrics.storedRequestErrors = newCounter(cfg, reg,
"stored_request_errors",
"Count of stored request errors by error type",
[]string{storedDataErrorLabel})

metrics.storedVideoFetchTimer = newHistogramVec(cfg, metrics.Registry,
metrics.storedVideoFetchTimer = newHistogramVec(cfg, reg,
"stored_video_fetch_time_seconds",
"Seconds to fetch stored video labeled by fetch type",
[]string{storedDataFetchTypeLabel},
standardTimeBuckets)

metrics.storedVideoErrors = newCounter(cfg, metrics.Registry,
metrics.storedVideoErrors = newCounter(cfg, reg,
"stored_video_errors",
"Count of stored video errors by error type",
[]string{storedDataErrorLabel})

metrics.timeoutNotifications = newCounter(cfg, metrics.Registry,
metrics.timeoutNotifications = newCounter(cfg, reg,
"timeout_notification",
"Count of timeout notifications triggered, and if they were successfully sent.",
[]string{successLabel})

metrics.dnsLookupTimer = newHistogram(cfg, metrics.Registry,
metrics.dnsLookupTimer = newHistogram(cfg, reg,
"dns_lookup_time",
"Seconds to resolve DNS",
standardTimeBuckets)

metrics.tlsHandhakeTimer = newHistogram(cfg, metrics.Registry,
metrics.tlsHandhakeTimer = newHistogram(cfg, reg,
"tls_handshake_time",
"Seconds to perform TLS Handshake",
standardTimeBuckets)

metrics.privacyCCPA = newCounter(cfg, metrics.Registry,
metrics.privacyCCPA = newCounter(cfg, reg,
"privacy_ccpa",
"Count of total requests to Prebid Server where CCPA was provided by source and opt-out .",
[]string{sourceLabel, optOutLabel})

metrics.privacyCOPPA = newCounter(cfg, metrics.Registry,
metrics.privacyCOPPA = newCounter(cfg, reg,
"privacy_coppa",
"Count of total requests to Prebid Server where the COPPA flag was set by source",
[]string{sourceLabel})

metrics.privacyTCF = newCounter(cfg, metrics.Registry,
metrics.privacyTCF = newCounter(cfg, reg,
"privacy_tcf",
"Count of TCF versions for requests where GDPR was enforced by source and version.",
[]string{versionLabel, sourceLabel})

metrics.privacyLMT = newCounter(cfg, metrics.Registry,
metrics.privacyLMT = newCounter(cfg, reg,
"privacy_lmt",
"Count of total requests to Prebid Server where the LMT flag was set by source",
[]string{sourceLabel})

if !metrics.metricsDisabled.AdapterGDPRRequestBlocked {
metrics.adapterGDPRBlockedRequests = newCounter(cfg, metrics.Registry,
metrics.adapterGDPRBlockedRequests = newCounter(cfg, reg,
"adapter_gdpr_requests_blocked",
"Count of total bidder requests blocked due to unsatisfied GDPR purpose 2 legal basis",
[]string{adapterLabel})
}

metrics.adapterBids = newCounter(cfg, metrics.Registry,
metrics.adapterBids = newCounter(cfg, reg,
"adapter_bids",
"Count of bids labeled by adapter and markup delivery type (adm or nurl).",
[]string{adapterLabel, markupDeliveryLabel})

metrics.adapterErrors = newCounter(cfg, metrics.Registry,
metrics.adapterErrors = newCounter(cfg, reg,
"adapter_errors",
"Count of errors labeled by adapter and error type.",
[]string{adapterLabel, adapterErrorLabel})

metrics.adapterPanics = newCounter(cfg, metrics.Registry,
metrics.adapterPanics = newCounter(cfg, reg,
"adapter_panics",
"Count of panics labeled by adapter.",
[]string{adapterLabel})

metrics.adapterPrices = newHistogramVec(cfg, metrics.Registry,
metrics.adapterPrices = newHistogramVec(cfg, reg,
"adapter_prices",
"Monetary value of the bids labeled by adapter.",
[]string{adapterLabel},
priceBuckets)

metrics.adapterRequests = newCounter(cfg, metrics.Registry,
metrics.adapterRequests = newCounter(cfg, reg,
"adapter_requests",
"Count of requests labeled by adapter, if has a cookie, and if it resulted in bids.",
[]string{adapterLabel, cookieLabel, hasBidsLabel})

if !metrics.metricsDisabled.AdapterConnectionMetrics {
metrics.adapterCreatedConnections = newCounter(cfg, metrics.Registry,
metrics.adapterCreatedConnections = newCounter(cfg, reg,
"adapter_connection_created",
"Count that keeps track of new connections when contacting adapter bidder endpoints.",
[]string{adapterLabel})

metrics.adapterReusedConnections = newCounter(cfg, metrics.Registry,
metrics.adapterReusedConnections = newCounter(cfg, reg,
"adapter_connection_reused",
"Count that keeps track of reused connections when contacting adapter bidder endpoints.",
[]string{adapterLabel})

metrics.adapterConnectionWaitTime = newHistogramVec(cfg, metrics.Registry,
metrics.adapterConnectionWaitTime = newHistogramVec(cfg, reg,
"adapter_connection_wait",
"Seconds from when the connection was requested until it is either created or reused",
[]string{adapterLabel},
standardTimeBuckets)
}

metrics.adapterRequestsTimer = newHistogramVec(cfg, metrics.Registry,
metrics.adapterRequestsTimer = newHistogramVec(cfg, reg,
"adapter_request_time_seconds",
"Seconds to resolve each successful request labeled by adapter.",
[]string{adapterLabel},
standardTimeBuckets)

metrics.syncerRequests = newCounter(cfg, metrics.Registry,
metrics.syncerRequests = newCounter(cfg, reg,
"syncer_requests",
"Count of cookie sync requests where a syncer is a candidate to be synced labeled by syncer key and status.",
[]string{syncerLabel, statusLabel})

metrics.syncerSets = newCounter(cfg, metrics.Registry,
metrics.syncerSets = newCounter(cfg, reg,
"syncer_sets",
"Count of setuid set requests for a syncer labeled by syncer key and status.",
[]string{syncerLabel, statusLabel})

metrics.accountRequests = newCounter(cfg, metrics.Registry,
metrics.accountRequests = newCounter(cfg, reg,
"account_requests",
"Count of total requests to Prebid Server labeled by account.",
[]string{accountLabel})

metrics.requestsQueueTimer = newHistogramVec(cfg, metrics.Registry,
metrics.requestsQueueTimer = newHistogramVec(cfg, reg,
"request_queue_time",
"Seconds request was waiting in queue",
[]string{requestTypeLabel, requestStatusLabel},
queuedRequestTimeBuckets)

metrics.Gatherer = reg

metricsPrefix := fmt.Sprintf("%s_%s_", cfg.Namespace, cfg.Subsystem)

metrics.Registerer = prometheus.WrapRegistererWithPrefix(metricsPrefix, reg)
metrics.Registerer.MustRegister(promCollector.NewGoCollector())

preloadLabelValues(&metrics, syncerKeys)

return &metrics
Expand Down
2 changes: 1 addition & 1 deletion metrics/prometheus/prometheus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestMetricCountGatekeeping(t *testing.T) {
m := createMetricsForTesting()

// Gather All Metrics
metricFamilies, err := m.Registry.Gather()
metricFamilies, err := m.Gatherer.Gather()
assert.NoError(t, err, "gather metics")

// Summarize By Adapter Cardinality
Expand Down
2 changes: 1 addition & 1 deletion server/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func newPrometheusServer(cfg *config.Configuration, metrics *metricsconfig.Detai
}
return &http.Server{
Addr: cfg.Host + ":" + strconv.Itoa(cfg.Metrics.Prometheus.Port),
Handler: promhttp.HandlerFor(proMetrics.Registry, promhttp.HandlerOpts{
Handler: promhttp.HandlerFor(proMetrics.Gatherer, promhttp.HandlerOpts{
ErrorLog: loggerForPrometheus{},
MaxRequestsInFlight: 5,
Timeout: cfg.Metrics.Prometheus.Timeout(),
Expand Down

0 comments on commit 5bb455c

Please sign in to comment.