github.com/prebid/prebid-server@v0.275.0/metrics/config/metrics.go (about) 1 package config 2 3 import ( 4 "time" 5 6 "github.com/prebid/prebid-server/config" 7 "github.com/prebid/prebid-server/metrics" 8 prometheusmetrics "github.com/prebid/prebid-server/metrics/prometheus" 9 "github.com/prebid/prebid-server/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 // RecordAdapterGDPRRequestBlocked across all engines 270 func (me *MultiMetricsEngine) RecordAdapterGDPRRequestBlocked(adapter openrtb_ext.BidderName) { 271 for _, thisME := range *me { 272 thisME.RecordAdapterGDPRRequestBlocked(adapter) 273 } 274 } 275 276 // RecordDebugRequest across all engines 277 func (me *MultiMetricsEngine) RecordDebugRequest(debugEnabled bool, pubId string) { 278 for _, thisME := range *me { 279 thisME.RecordDebugRequest(debugEnabled, pubId) 280 } 281 } 282 283 func (me *MultiMetricsEngine) RecordStoredResponse(pubId string) { 284 for _, thisME := range *me { 285 thisME.RecordStoredResponse(pubId) 286 } 287 } 288 289 func (me *MultiMetricsEngine) RecordAdsCertReq(success bool) { 290 for _, thisME := range *me { 291 thisME.RecordAdsCertReq(success) 292 } 293 } 294 295 func (me *MultiMetricsEngine) RecordAdsCertSignTime(adsCertSignTime time.Duration) { 296 for _, thisME := range *me { 297 thisME.RecordAdsCertSignTime(adsCertSignTime) 298 } 299 } 300 301 func (me *MultiMetricsEngine) RecordBidValidationCreativeSizeError(adapter openrtb_ext.BidderName, account string) { 302 for _, thisME := range *me { 303 thisME.RecordBidValidationCreativeSizeError(adapter, account) 304 } 305 } 306 307 func (me *MultiMetricsEngine) RecordBidValidationCreativeSizeWarn(adapter openrtb_ext.BidderName, account string) { 308 for _, thisME := range *me { 309 thisME.RecordBidValidationCreativeSizeWarn(adapter, account) 310 } 311 } 312 313 func (me *MultiMetricsEngine) RecordBidValidationSecureMarkupError(adapter openrtb_ext.BidderName, account string) { 314 for _, thisME := range *me { 315 thisME.RecordBidValidationSecureMarkupError(adapter, account) 316 } 317 } 318 319 func (me *MultiMetricsEngine) RecordBidValidationSecureMarkupWarn(adapter openrtb_ext.BidderName, account string) { 320 for _, thisME := range *me { 321 thisME.RecordBidValidationSecureMarkupWarn(adapter, account) 322 } 323 } 324 325 func (me *MultiMetricsEngine) RecordAccountGDPRPurposeWarning(account string, purposeName string) { 326 for _, thisME := range *me { 327 thisME.RecordAccountGDPRPurposeWarning(account, purposeName) 328 } 329 } 330 func (me *MultiMetricsEngine) RecordAccountGDPRChannelEnabledWarning(account string) { 331 for _, thisME := range *me { 332 thisME.RecordAccountGDPRChannelEnabledWarning(account) 333 } 334 } 335 func (me *MultiMetricsEngine) RecordAccountCCPAChannelEnabledWarning(account string) { 336 for _, thisME := range *me { 337 thisME.RecordAccountCCPAChannelEnabledWarning(account) 338 } 339 } 340 func (me *MultiMetricsEngine) RecordAccountUpgradeStatus(account string) { 341 for _, thisME := range *me { 342 thisME.RecordAccountUpgradeStatus(account) 343 } 344 } 345 346 func (me *MultiMetricsEngine) RecordModuleCalled(labels metrics.ModuleLabels, duration time.Duration) { 347 for _, thisME := range *me { 348 thisME.RecordModuleCalled(labels, duration) 349 } 350 } 351 352 func (me *MultiMetricsEngine) RecordModuleFailed(labels metrics.ModuleLabels) { 353 for _, thisME := range *me { 354 thisME.RecordModuleFailed(labels) 355 } 356 } 357 358 func (me *MultiMetricsEngine) RecordModuleSuccessNooped(labels metrics.ModuleLabels) { 359 for _, thisME := range *me { 360 thisME.RecordModuleSuccessNooped(labels) 361 } 362 } 363 364 func (me *MultiMetricsEngine) RecordModuleSuccessUpdated(labels metrics.ModuleLabels) { 365 for _, thisME := range *me { 366 thisME.RecordModuleSuccessUpdated(labels) 367 } 368 } 369 370 func (me *MultiMetricsEngine) RecordModuleSuccessRejected(labels metrics.ModuleLabels) { 371 for _, thisME := range *me { 372 thisME.RecordModuleSuccessRejected(labels) 373 } 374 } 375 376 func (me *MultiMetricsEngine) RecordModuleExecutionError(labels metrics.ModuleLabels) { 377 for _, thisME := range *me { 378 thisME.RecordModuleExecutionError(labels) 379 } 380 } 381 382 func (me *MultiMetricsEngine) RecordModuleTimeout(labels metrics.ModuleLabels) { 383 for _, thisME := range *me { 384 thisME.RecordModuleTimeout(labels) 385 } 386 } 387 388 // NilMetricsEngine implements the MetricsEngine interface where no metrics are actually captured. This is 389 // used if no metric backend is configured and also for tests. 390 type NilMetricsEngine struct{} 391 392 // RecordRequest as a noop 393 func (me *NilMetricsEngine) RecordRequest(labels metrics.Labels) { 394 } 395 396 // RecordConnectionAccept as a noop 397 func (me *NilMetricsEngine) RecordConnectionAccept(success bool) { 398 } 399 400 // RecordTMaxTimeout as a noop 401 func (me *NilMetricsEngine) RecordTMaxTimeout() { 402 } 403 404 // RecordConnectionClose as a noop 405 func (me *NilMetricsEngine) RecordConnectionClose(success bool) { 406 } 407 408 // RecordImps as a noop 409 func (me *NilMetricsEngine) RecordImps(implabels metrics.ImpLabels) { 410 } 411 412 // RecordRequestTime as a noop 413 func (me *NilMetricsEngine) RecordRequestTime(labels metrics.Labels, length time.Duration) { 414 } 415 416 // RecordStoredDataFetchTime as a noop 417 func (me *NilMetricsEngine) RecordStoredDataFetchTime(labels metrics.StoredDataLabels, length time.Duration) { 418 } 419 420 // RecordStoredDataError as a noop 421 func (me *NilMetricsEngine) RecordStoredDataError(labels metrics.StoredDataLabels) { 422 } 423 424 // RecordAdapterPanic as a noop 425 func (me *NilMetricsEngine) RecordAdapterPanic(labels metrics.AdapterLabels) { 426 } 427 428 // RecordAdapterRequest as a noop 429 func (me *NilMetricsEngine) RecordAdapterRequest(labels metrics.AdapterLabels) { 430 } 431 432 // RecordAdapterConnections as a noop 433 func (me *NilMetricsEngine) RecordAdapterConnections(bidderName openrtb_ext.BidderName, connWasReused bool, connWaitTime time.Duration) { 434 } 435 436 // RecordDNSTime as a noop 437 func (me *NilMetricsEngine) RecordDNSTime(dnsLookupTime time.Duration) { 438 } 439 440 // RecordTLSHandshakeTime as a noop 441 func (me *NilMetricsEngine) RecordTLSHandshakeTime(tlsHandshakeTime time.Duration) { 442 } 443 444 // RecordBidderServerResponseTime as a noop 445 func (me *NilMetricsEngine) RecordBidderServerResponseTime(bidderServerResponseTime time.Duration) { 446 } 447 448 // RecordAdapterBidReceived as a noop 449 func (me *NilMetricsEngine) RecordAdapterBidReceived(labels metrics.AdapterLabels, bidType openrtb_ext.BidType, hasAdm bool) { 450 } 451 452 // RecordAdapterPrice as a noop 453 func (me *NilMetricsEngine) RecordAdapterPrice(labels metrics.AdapterLabels, cpm float64) { 454 } 455 456 // RecordAdapterTime as a noop 457 func (me *NilMetricsEngine) RecordAdapterTime(labels metrics.AdapterLabels, length time.Duration) { 458 } 459 460 // RecordOverheadTime as a noop 461 func (me *NilMetricsEngine) RecordOverheadTime(overhead metrics.OverheadType, length time.Duration) { 462 } 463 464 // RecordCookieSync as a noop 465 func (me *NilMetricsEngine) RecordCookieSync(status metrics.CookieSyncStatus) { 466 } 467 468 // RecordSyncerRequest as a noop 469 func (me *NilMetricsEngine) RecordSyncerRequest(key string, status metrics.SyncerCookieSyncStatus) { 470 } 471 472 // RecordSetUid as a noop 473 func (me *NilMetricsEngine) RecordSetUid(status metrics.SetUidStatus) { 474 } 475 476 // RecordSyncerSet as a noop 477 func (me *NilMetricsEngine) RecordSyncerSet(key string, status metrics.SyncerSetUidStatus) { 478 } 479 480 // RecordStoredReqCacheResult as a noop 481 func (me *NilMetricsEngine) RecordStoredReqCacheResult(cacheResult metrics.CacheResult, inc int) { 482 } 483 484 // RecordStoredImpCacheResult as a noop 485 func (me *NilMetricsEngine) RecordStoredImpCacheResult(cacheResult metrics.CacheResult, inc int) { 486 } 487 488 // RecordAccountCacheResult as a noop 489 func (me *NilMetricsEngine) RecordAccountCacheResult(cacheResult metrics.CacheResult, inc int) { 490 } 491 492 // RecordPrebidCacheRequestTime as a noop 493 func (me *NilMetricsEngine) RecordPrebidCacheRequestTime(success bool, length time.Duration) { 494 } 495 496 // RecordRequestQueueTime as a noop 497 func (me *NilMetricsEngine) RecordRequestQueueTime(success bool, requestType metrics.RequestType, length time.Duration) { 498 } 499 500 // RecordTimeoutNotice as a noop 501 func (me *NilMetricsEngine) RecordTimeoutNotice(success bool) { 502 } 503 504 // RecordRequestPrivacy as a noop 505 func (me *NilMetricsEngine) RecordRequestPrivacy(privacy metrics.PrivacyLabels) { 506 } 507 508 // RecordAdapterGDPRRequestBlocked as a noop 509 func (me *NilMetricsEngine) RecordAdapterGDPRRequestBlocked(adapter openrtb_ext.BidderName) { 510 } 511 512 // RecordDebugRequest as a noop 513 func (me *NilMetricsEngine) RecordDebugRequest(debugEnabled bool, pubId string) { 514 } 515 516 func (me *NilMetricsEngine) RecordStoredResponse(pubId string) { 517 } 518 519 func (me *NilMetricsEngine) RecordAdsCertReq(success bool) { 520 521 } 522 523 func (me *NilMetricsEngine) RecordAdsCertSignTime(adsCertSignTime time.Duration) { 524 525 } 526 527 func (me *NilMetricsEngine) RecordBidValidationCreativeSizeError(adapter openrtb_ext.BidderName, account string) { 528 } 529 530 func (me *NilMetricsEngine) RecordBidValidationCreativeSizeWarn(adapter openrtb_ext.BidderName, account string) { 531 } 532 533 func (me *NilMetricsEngine) RecordBidValidationSecureMarkupError(adapter openrtb_ext.BidderName, account string) { 534 } 535 536 func (me *NilMetricsEngine) RecordBidValidationSecureMarkupWarn(adapter openrtb_ext.BidderName, account string) { 537 } 538 539 func (me *NilMetricsEngine) RecordAccountGDPRPurposeWarning(account string, purposeName string) { 540 } 541 542 func (me *NilMetricsEngine) RecordAccountGDPRChannelEnabledWarning(account string) { 543 } 544 545 func (me *NilMetricsEngine) RecordAccountCCPAChannelEnabledWarning(account string) { 546 } 547 548 func (me *NilMetricsEngine) RecordAccountUpgradeStatus(account string) { 549 } 550 551 func (me *NilMetricsEngine) RecordModuleCalled(labels metrics.ModuleLabels, duration time.Duration) { 552 } 553 554 func (me *NilMetricsEngine) RecordModuleFailed(labels metrics.ModuleLabels) { 555 } 556 557 func (me *NilMetricsEngine) RecordModuleSuccessNooped(labels metrics.ModuleLabels) { 558 } 559 560 func (me *NilMetricsEngine) RecordModuleSuccessUpdated(labels metrics.ModuleLabels) { 561 } 562 563 func (me *NilMetricsEngine) RecordModuleSuccessRejected(labels metrics.ModuleLabels) { 564 } 565 566 func (me *NilMetricsEngine) RecordModuleExecutionError(labels metrics.ModuleLabels) { 567 } 568 569 func (me *NilMetricsEngine) RecordModuleTimeout(labels metrics.ModuleLabels) { 570 }