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  }