github.com/prebid/prebid-server/v2@v2.18.0/metrics/config/metrics.go (about) 1 package config 2 3 import ( 4 "time" 5 6 "github.com/prebid/prebid-server/v2/config" 7 "github.com/prebid/prebid-server/v2/metrics" 8 prometheusmetrics "github.com/prebid/prebid-server/v2/metrics/prometheus" 9 "github.com/prebid/prebid-server/v2/openrtb_ext" 10 gometrics "github.com/rcrowley/go-metrics" 11 influxdb "github.com/vrischmann/go-metrics-influxdb" 12 ) 13 14 // NewMetricsEngine reads the configuration and returns the appropriate metrics engine 15 // for this instance. 16 func NewMetricsEngine(cfg *config.Configuration, adapterList []openrtb_ext.BidderName, syncerKeys []string, moduleStageNames map[string][]string) *DetailedMetricsEngine { 17 // Create a list of metrics engines to use. 18 // Capacity of 2, as unlikely to have more than 2 metrics backends, and in the case 19 // of 1 we won't use the list so it will be garbage collected. 20 engineList := make(MultiMetricsEngine, 0, 2) 21 returnEngine := DetailedMetricsEngine{} 22 23 if cfg.Metrics.Influxdb.Host != "" { 24 // Currently use go-metrics as the metrics piece for influx 25 returnEngine.GoMetrics = metrics.NewMetrics(gometrics.NewPrefixedRegistry("prebidserver."), adapterList, cfg.Metrics.Disabled, syncerKeys, moduleStageNames) 26 engineList = append(engineList, returnEngine.GoMetrics) 27 28 // Set up the Influx logger 29 go influxdb.InfluxDB( 30 returnEngine.GoMetrics.MetricsRegistry, // metrics registry 31 time.Second*time.Duration(cfg.Metrics.Influxdb.MetricSendInterval), // Configurable interval 32 cfg.Metrics.Influxdb.Host, // the InfluxDB url 33 cfg.Metrics.Influxdb.Database, // your InfluxDB database 34 cfg.Metrics.Influxdb.Measurement, // your measurement 35 cfg.Metrics.Influxdb.Username, // your InfluxDB user 36 cfg.Metrics.Influxdb.Password, // your InfluxDB password, 37 cfg.Metrics.Influxdb.AlignTimestamps, // align timestamps 38 ) 39 // Influx is not added to the engine list as goMetrics takes care of it already. 40 } 41 if cfg.Metrics.Prometheus.Port != 0 { 42 // Set up the Prometheus metrics. 43 returnEngine.PrometheusMetrics = prometheusmetrics.NewMetrics(cfg.Metrics.Prometheus, cfg.Metrics.Disabled, syncerKeys, moduleStageNames) 44 engineList = append(engineList, returnEngine.PrometheusMetrics) 45 } 46 47 // Now return the proper metrics engine 48 if len(engineList) > 1 { 49 returnEngine.MetricsEngine = &engineList 50 } else if len(engineList) == 1 { 51 returnEngine.MetricsEngine = engineList[0] 52 } else { 53 returnEngine.MetricsEngine = &NilMetricsEngine{} 54 } 55 56 return &returnEngine 57 } 58 59 // DetailedMetricsEngine is a MultiMetricsEngine that preserves links to underlying metrics engines. 60 type DetailedMetricsEngine struct { 61 metrics.MetricsEngine 62 GoMetrics *metrics.Metrics 63 PrometheusMetrics *prometheusmetrics.Metrics 64 } 65 66 // MultiMetricsEngine logs metrics to multiple metrics databases The can be useful in transitioning 67 // an instance from one engine to another, you can run both in parallel to verify stats match up. 68 type MultiMetricsEngine []metrics.MetricsEngine 69 70 // RecordRequest across all engines 71 func (me *MultiMetricsEngine) RecordRequest(labels metrics.Labels) { 72 for _, thisME := range *me { 73 thisME.RecordRequest(labels) 74 } 75 } 76 77 func (me *MultiMetricsEngine) RecordConnectionAccept(success bool) { 78 for _, thisME := range *me { 79 thisME.RecordConnectionAccept(success) 80 } 81 } 82 83 func (me *MultiMetricsEngine) RecordTMaxTimeout() { 84 for _, thisME := range *me { 85 thisME.RecordTMaxTimeout() 86 } 87 } 88 89 func (me *MultiMetricsEngine) RecordConnectionClose(success bool) { 90 for _, thisME := range *me { 91 thisME.RecordConnectionClose(success) 92 } 93 } 94 95 // RecordsImps records imps with imp types across all metric engines 96 func (me *MultiMetricsEngine) RecordImps(implabels metrics.ImpLabels) { 97 for _, thisME := range *me { 98 thisME.RecordImps(implabels) 99 } 100 } 101 102 // RecordRequestTime across all engines 103 func (me *MultiMetricsEngine) RecordRequestTime(labels metrics.Labels, length time.Duration) { 104 for _, thisME := range *me { 105 thisME.RecordRequestTime(labels, length) 106 } 107 } 108 109 // RecordStoredDataFetchTime across all engines 110 func (me *MultiMetricsEngine) RecordStoredDataFetchTime(labels metrics.StoredDataLabels, length time.Duration) { 111 for _, thisME := range *me { 112 thisME.RecordStoredDataFetchTime(labels, length) 113 } 114 } 115 116 // RecordStoredDataError across all engines 117 func (me *MultiMetricsEngine) RecordStoredDataError(labels metrics.StoredDataLabels) { 118 for _, thisME := range *me { 119 thisME.RecordStoredDataError(labels) 120 } 121 } 122 123 // RecordAdapterPanic across all engines 124 func (me *MultiMetricsEngine) RecordAdapterPanic(labels metrics.AdapterLabels) { 125 for _, thisME := range *me { 126 thisME.RecordAdapterPanic(labels) 127 } 128 } 129 130 // RecordAdapterRequest across all engines 131 func (me *MultiMetricsEngine) RecordAdapterRequest(labels metrics.AdapterLabels) { 132 for _, thisME := range *me { 133 thisME.RecordAdapterRequest(labels) 134 } 135 } 136 137 // Keeps track of created and reused connections to adapter bidders and the time from the 138 // connection request, to the connection creation, or reuse from the pool across all engines 139 func (me *MultiMetricsEngine) RecordAdapterConnections(bidderName openrtb_ext.BidderName, connWasReused bool, connWaitTime time.Duration) { 140 for _, thisME := range *me { 141 thisME.RecordAdapterConnections(bidderName, connWasReused, connWaitTime) 142 } 143 } 144 145 // Times the DNS resolution process 146 func (me *MultiMetricsEngine) RecordDNSTime(dnsLookupTime time.Duration) { 147 for _, thisME := range *me { 148 thisME.RecordDNSTime(dnsLookupTime) 149 } 150 } 151 152 func (me *MultiMetricsEngine) RecordTLSHandshakeTime(tlsHandshakeTime time.Duration) { 153 for _, thisME := range *me { 154 thisME.RecordTLSHandshakeTime(tlsHandshakeTime) 155 } 156 } 157 158 func (me *MultiMetricsEngine) RecordBidderServerResponseTime(bidderServerResponseTime time.Duration) { 159 for _, thisME := range *me { 160 thisME.RecordBidderServerResponseTime(bidderServerResponseTime) 161 } 162 } 163 164 // RecordAdapterBidReceived across all engines 165 func (me *MultiMetricsEngine) RecordAdapterBidReceived(labels metrics.AdapterLabels, bidType openrtb_ext.BidType, hasAdm bool) { 166 for _, thisME := range *me { 167 thisME.RecordAdapterBidReceived(labels, bidType, hasAdm) 168 } 169 } 170 171 // RecordAdapterPrice across all engines 172 func (me *MultiMetricsEngine) RecordAdapterPrice(labels metrics.AdapterLabels, cpm float64) { 173 for _, thisME := range *me { 174 thisME.RecordAdapterPrice(labels, cpm) 175 } 176 } 177 178 // RecordAdapterTime across all engines 179 func (me *MultiMetricsEngine) RecordAdapterTime(labels metrics.AdapterLabels, length time.Duration) { 180 for _, thisME := range *me { 181 thisME.RecordAdapterTime(labels, length) 182 } 183 } 184 185 // RecordOverheadTime across all engines 186 func (me *MultiMetricsEngine) RecordOverheadTime(overhead metrics.OverheadType, length time.Duration) { 187 for _, thisME := range *me { 188 thisME.RecordOverheadTime(overhead, length) 189 } 190 } 191 192 // RecordCookieSync across all engines 193 func (me *MultiMetricsEngine) RecordCookieSync(status metrics.CookieSyncStatus) { 194 for _, thisME := range *me { 195 thisME.RecordCookieSync(status) 196 } 197 } 198 199 // RecordSyncerRequest across all engines 200 func (me *MultiMetricsEngine) RecordSyncerRequest(key string, status metrics.SyncerCookieSyncStatus) { 201 for _, thisME := range *me { 202 thisME.RecordSyncerRequest(key, status) 203 } 204 } 205 206 // RecordSetUid across all engines 207 func (me *MultiMetricsEngine) RecordSetUid(status metrics.SetUidStatus) { 208 for _, thisME := range *me { 209 thisME.RecordSetUid(status) 210 } 211 } 212 213 // RecordSyncerSet across all engines 214 func (me *MultiMetricsEngine) RecordSyncerSet(key string, status metrics.SyncerSetUidStatus) { 215 for _, thisME := range *me { 216 thisME.RecordSyncerSet(key, status) 217 } 218 } 219 220 // RecordStoredReqCacheResult across all engines 221 func (me *MultiMetricsEngine) RecordStoredReqCacheResult(cacheResult metrics.CacheResult, inc int) { 222 for _, thisME := range *me { 223 thisME.RecordStoredReqCacheResult(cacheResult, inc) 224 } 225 } 226 227 // RecordStoredImpCacheResult across all engines 228 func (me *MultiMetricsEngine) RecordStoredImpCacheResult(cacheResult metrics.CacheResult, inc int) { 229 for _, thisME := range *me { 230 thisME.RecordStoredImpCacheResult(cacheResult, inc) 231 } 232 } 233 234 // RecordAccountCacheResult across all engines 235 func (me *MultiMetricsEngine) RecordAccountCacheResult(cacheResult metrics.CacheResult, inc int) { 236 for _, thisME := range *me { 237 thisME.RecordAccountCacheResult(cacheResult, inc) 238 } 239 } 240 241 // RecordPrebidCacheRequestTime across all engines 242 func (me *MultiMetricsEngine) RecordPrebidCacheRequestTime(success bool, length time.Duration) { 243 for _, thisME := range *me { 244 thisME.RecordPrebidCacheRequestTime(success, length) 245 } 246 } 247 248 // RecordRequestQueueTime across all engines 249 func (me *MultiMetricsEngine) RecordRequestQueueTime(success bool, requestType metrics.RequestType, length time.Duration) { 250 for _, thisME := range *me { 251 thisME.RecordRequestQueueTime(success, requestType, length) 252 } 253 } 254 255 // RecordTimeoutNotice across all engines 256 func (me *MultiMetricsEngine) RecordTimeoutNotice(success bool) { 257 for _, thisME := range *me { 258 thisME.RecordTimeoutNotice(success) 259 } 260 } 261 262 // RecordRequestPrivacy across all engines 263 func (me *MultiMetricsEngine) RecordRequestPrivacy(privacy metrics.PrivacyLabels) { 264 for _, thisME := range *me { 265 thisME.RecordRequestPrivacy(privacy) 266 } 267 } 268 269 // RecordAdapterBuyerUIDScrubbed across all engines 270 func (me *MultiMetricsEngine) RecordAdapterBuyerUIDScrubbed(adapter openrtb_ext.BidderName) { 271 for _, thisME := range *me { 272 thisME.RecordAdapterBuyerUIDScrubbed(adapter) 273 } 274 } 275 276 // RecordAdapterGDPRRequestBlocked across all engines 277 func (me *MultiMetricsEngine) RecordAdapterGDPRRequestBlocked(adapter openrtb_ext.BidderName) { 278 for _, thisME := range *me { 279 thisME.RecordAdapterGDPRRequestBlocked(adapter) 280 } 281 } 282 283 // RecordDebugRequest across all engines 284 func (me *MultiMetricsEngine) RecordDebugRequest(debugEnabled bool, pubId string) { 285 for _, thisME := range *me { 286 thisME.RecordDebugRequest(debugEnabled, pubId) 287 } 288 } 289 290 func (me *MultiMetricsEngine) RecordStoredResponse(pubId string) { 291 for _, thisME := range *me { 292 thisME.RecordStoredResponse(pubId) 293 } 294 } 295 296 func (me *MultiMetricsEngine) RecordAdsCertReq(success bool) { 297 for _, thisME := range *me { 298 thisME.RecordAdsCertReq(success) 299 } 300 } 301 302 func (me *MultiMetricsEngine) RecordAdsCertSignTime(adsCertSignTime time.Duration) { 303 for _, thisME := range *me { 304 thisME.RecordAdsCertSignTime(adsCertSignTime) 305 } 306 } 307 308 func (me *MultiMetricsEngine) RecordBidValidationCreativeSizeError(adapter openrtb_ext.BidderName, account string) { 309 for _, thisME := range *me { 310 thisME.RecordBidValidationCreativeSizeError(adapter, account) 311 } 312 } 313 314 func (me *MultiMetricsEngine) RecordBidValidationCreativeSizeWarn(adapter openrtb_ext.BidderName, account string) { 315 for _, thisME := range *me { 316 thisME.RecordBidValidationCreativeSizeWarn(adapter, account) 317 } 318 } 319 320 func (me *MultiMetricsEngine) RecordBidValidationSecureMarkupError(adapter openrtb_ext.BidderName, account string) { 321 for _, thisME := range *me { 322 thisME.RecordBidValidationSecureMarkupError(adapter, account) 323 } 324 } 325 326 func (me *MultiMetricsEngine) RecordBidValidationSecureMarkupWarn(adapter openrtb_ext.BidderName, account string) { 327 for _, thisME := range *me { 328 thisME.RecordBidValidationSecureMarkupWarn(adapter, account) 329 } 330 } 331 332 func (me *MultiMetricsEngine) RecordModuleCalled(labels metrics.ModuleLabels, duration time.Duration) { 333 for _, thisME := range *me { 334 thisME.RecordModuleCalled(labels, duration) 335 } 336 } 337 338 func (me *MultiMetricsEngine) RecordModuleFailed(labels metrics.ModuleLabels) { 339 for _, thisME := range *me { 340 thisME.RecordModuleFailed(labels) 341 } 342 } 343 344 func (me *MultiMetricsEngine) RecordModuleSuccessNooped(labels metrics.ModuleLabels) { 345 for _, thisME := range *me { 346 thisME.RecordModuleSuccessNooped(labels) 347 } 348 } 349 350 func (me *MultiMetricsEngine) RecordModuleSuccessUpdated(labels metrics.ModuleLabels) { 351 for _, thisME := range *me { 352 thisME.RecordModuleSuccessUpdated(labels) 353 } 354 } 355 356 func (me *MultiMetricsEngine) RecordModuleSuccessRejected(labels metrics.ModuleLabels) { 357 for _, thisME := range *me { 358 thisME.RecordModuleSuccessRejected(labels) 359 } 360 } 361 362 func (me *MultiMetricsEngine) RecordModuleExecutionError(labels metrics.ModuleLabels) { 363 for _, thisME := range *me { 364 thisME.RecordModuleExecutionError(labels) 365 } 366 } 367 368 func (me *MultiMetricsEngine) RecordModuleTimeout(labels metrics.ModuleLabels) { 369 for _, thisME := range *me { 370 thisME.RecordModuleTimeout(labels) 371 } 372 } 373 374 // NilMetricsEngine implements the MetricsEngine interface where no metrics are actually captured. This is 375 // used if no metric backend is configured and also for tests. 376 type NilMetricsEngine struct{} 377 378 // RecordRequest as a noop 379 func (me *NilMetricsEngine) RecordRequest(labels metrics.Labels) { 380 } 381 382 // RecordConnectionAccept as a noop 383 func (me *NilMetricsEngine) RecordConnectionAccept(success bool) { 384 } 385 386 // RecordTMaxTimeout as a noop 387 func (me *NilMetricsEngine) RecordTMaxTimeout() { 388 } 389 390 // RecordConnectionClose as a noop 391 func (me *NilMetricsEngine) RecordConnectionClose(success bool) { 392 } 393 394 // RecordImps as a noop 395 func (me *NilMetricsEngine) RecordImps(implabels metrics.ImpLabels) { 396 } 397 398 // RecordRequestTime as a noop 399 func (me *NilMetricsEngine) RecordRequestTime(labels metrics.Labels, length time.Duration) { 400 } 401 402 // RecordStoredDataFetchTime as a noop 403 func (me *NilMetricsEngine) RecordStoredDataFetchTime(labels metrics.StoredDataLabels, length time.Duration) { 404 } 405 406 // RecordStoredDataError as a noop 407 func (me *NilMetricsEngine) RecordStoredDataError(labels metrics.StoredDataLabels) { 408 } 409 410 // RecordAdapterPanic as a noop 411 func (me *NilMetricsEngine) RecordAdapterPanic(labels metrics.AdapterLabels) { 412 } 413 414 // RecordAdapterRequest as a noop 415 func (me *NilMetricsEngine) RecordAdapterRequest(labels metrics.AdapterLabels) { 416 } 417 418 // RecordAdapterConnections as a noop 419 func (me *NilMetricsEngine) RecordAdapterConnections(bidderName openrtb_ext.BidderName, connWasReused bool, connWaitTime time.Duration) { 420 } 421 422 // RecordDNSTime as a noop 423 func (me *NilMetricsEngine) RecordDNSTime(dnsLookupTime time.Duration) { 424 } 425 426 // RecordTLSHandshakeTime as a noop 427 func (me *NilMetricsEngine) RecordTLSHandshakeTime(tlsHandshakeTime time.Duration) { 428 } 429 430 // RecordBidderServerResponseTime as a noop 431 func (me *NilMetricsEngine) RecordBidderServerResponseTime(bidderServerResponseTime time.Duration) { 432 } 433 434 // RecordAdapterBidReceived as a noop 435 func (me *NilMetricsEngine) RecordAdapterBidReceived(labels metrics.AdapterLabels, bidType openrtb_ext.BidType, hasAdm bool) { 436 } 437 438 // RecordAdapterPrice as a noop 439 func (me *NilMetricsEngine) RecordAdapterPrice(labels metrics.AdapterLabels, cpm float64) { 440 } 441 442 // RecordAdapterTime as a noop 443 func (me *NilMetricsEngine) RecordAdapterTime(labels metrics.AdapterLabels, length time.Duration) { 444 } 445 446 // RecordOverheadTime as a noop 447 func (me *NilMetricsEngine) RecordOverheadTime(overhead metrics.OverheadType, length time.Duration) { 448 } 449 450 // RecordCookieSync as a noop 451 func (me *NilMetricsEngine) RecordCookieSync(status metrics.CookieSyncStatus) { 452 } 453 454 // RecordSyncerRequest as a noop 455 func (me *NilMetricsEngine) RecordSyncerRequest(key string, status metrics.SyncerCookieSyncStatus) { 456 } 457 458 // RecordSetUid as a noop 459 func (me *NilMetricsEngine) RecordSetUid(status metrics.SetUidStatus) { 460 } 461 462 // RecordSyncerSet as a noop 463 func (me *NilMetricsEngine) RecordSyncerSet(key string, status metrics.SyncerSetUidStatus) { 464 } 465 466 // RecordStoredReqCacheResult as a noop 467 func (me *NilMetricsEngine) RecordStoredReqCacheResult(cacheResult metrics.CacheResult, inc int) { 468 } 469 470 // RecordStoredImpCacheResult as a noop 471 func (me *NilMetricsEngine) RecordStoredImpCacheResult(cacheResult metrics.CacheResult, inc int) { 472 } 473 474 // RecordAccountCacheResult as a noop 475 func (me *NilMetricsEngine) RecordAccountCacheResult(cacheResult metrics.CacheResult, inc int) { 476 } 477 478 // RecordPrebidCacheRequestTime as a noop 479 func (me *NilMetricsEngine) RecordPrebidCacheRequestTime(success bool, length time.Duration) { 480 } 481 482 // RecordRequestQueueTime as a noop 483 func (me *NilMetricsEngine) RecordRequestQueueTime(success bool, requestType metrics.RequestType, length time.Duration) { 484 } 485 486 // RecordTimeoutNotice as a noop 487 func (me *NilMetricsEngine) RecordTimeoutNotice(success bool) { 488 } 489 490 // RecordRequestPrivacy as a noop 491 func (me *NilMetricsEngine) RecordRequestPrivacy(privacy metrics.PrivacyLabels) { 492 } 493 494 // RecordAdapterBuyerUIDScrubbed as a noop 495 func (me *NilMetricsEngine) RecordAdapterBuyerUIDScrubbed(adapter openrtb_ext.BidderName) { 496 } 497 498 // RecordAdapterGDPRRequestBlocked as a noop 499 func (me *NilMetricsEngine) RecordAdapterGDPRRequestBlocked(adapter openrtb_ext.BidderName) { 500 } 501 502 // RecordDebugRequest as a noop 503 func (me *NilMetricsEngine) RecordDebugRequest(debugEnabled bool, pubId string) { 504 } 505 506 func (me *NilMetricsEngine) RecordStoredResponse(pubId string) { 507 } 508 509 func (me *NilMetricsEngine) RecordAdsCertReq(success bool) { 510 511 } 512 513 func (me *NilMetricsEngine) RecordAdsCertSignTime(adsCertSignTime time.Duration) { 514 515 } 516 517 func (me *NilMetricsEngine) RecordBidValidationCreativeSizeError(adapter openrtb_ext.BidderName, account string) { 518 } 519 520 func (me *NilMetricsEngine) RecordBidValidationCreativeSizeWarn(adapter openrtb_ext.BidderName, account string) { 521 } 522 523 func (me *NilMetricsEngine) RecordBidValidationSecureMarkupError(adapter openrtb_ext.BidderName, account string) { 524 } 525 526 func (me *NilMetricsEngine) RecordBidValidationSecureMarkupWarn(adapter openrtb_ext.BidderName, account string) { 527 } 528 529 func (me *NilMetricsEngine) RecordModuleCalled(labels metrics.ModuleLabels, duration time.Duration) { 530 } 531 532 func (me *NilMetricsEngine) RecordModuleFailed(labels metrics.ModuleLabels) { 533 } 534 535 func (me *NilMetricsEngine) RecordModuleSuccessNooped(labels metrics.ModuleLabels) { 536 } 537 538 func (me *NilMetricsEngine) RecordModuleSuccessUpdated(labels metrics.ModuleLabels) { 539 } 540 541 func (me *NilMetricsEngine) RecordModuleSuccessRejected(labels metrics.ModuleLabels) { 542 } 543 544 func (me *NilMetricsEngine) RecordModuleExecutionError(labels metrics.ModuleLabels) { 545 } 546 547 func (me *NilMetricsEngine) RecordModuleTimeout(labels metrics.ModuleLabels) { 548 }