Skip to content

Commit

Permalink
Introduce hard-fail mode switchers and update metrics gathering
Browse files Browse the repository at this point in the history
  • Loading branch information
zxPhoenix committed Feb 4, 2025
1 parent 9ac31e3 commit 3119f39
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 47 deletions.
4 changes: 4 additions & 0 deletions docs/config-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,10 @@ Preconfigured application settings can be obtained from multiple data sources co

Warning! Application will not start in case of no one data source is defined and you'll get an exception in logs.

For requests validation mode available next options:
- `settings.fail-on-unknown-bidders` - fail with validation error or just make warning for unknown bidders.
- `settings.fail-on-disabled-bidders` - fail with validation error or just make warning for disabled bidders.

For filesystem data source available next options:
- `settings.filesystem.settings-filename` - location of file settings.
- `settings.filesystem.stored-requests-dir` - directory with stored requests.
Expand Down
4 changes: 4 additions & 0 deletions docs/metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ where `[DATASOURCE]` is a data source name, `DEFAULT_DS` by defaul.
- `imps_video` - number of video impressions
- `imps_native` - number of native impressions
- `imps_audio` - number of audio impressions
- `disabled_bidder` - number of disabled bidders received within requests
- `unknown_bidder` - number of unknown bidders received within requests
- `requests.(ok|badinput|err|networkerr|blocklisted_account|blocklisted_app).(openrtb2-web|openrtb-app|amp|legacy)` - number of requests broken down by status and type
- `bidder-cardinality.<cardinality>.requests` - number of requests targeting `<cardinality>` of bidders
- `connection_accept_errors` - number of errors occurred while establishing HTTP connection
Expand Down Expand Up @@ -92,6 +94,8 @@ Following metrics are collected and submitted if account is configured with `det
- `account.<account-id>.requests.type.(openrtb2-web,openrtb-app,amp,legacy)` - number of requests received from account with `<account-id>` broken down by type of incoming request
- `account.<account-id>.debug_requests` - number of requests received from account with `<account-id>` broken down by type of incoming request (when debug mode is enabled)
- `account.<account-id>.requests.rejected` - number of rejected requests caused by incorrect `accountId`
- `account.<account-id>.requests.disabled_bidder` - number of disabled bidders received within requests from account with `<account-id>`
- `account.<account-id>.requests.unknown_bidder` - number of unknown bidder names received within requests from account with `<account-id>`
- `account.<account-id>.adapter.<bidder-name>.request_time` - timer tracking how long did it take to make a request to `<bidder-name>` when incoming request was from `<account-id>`
- `account.<account-id>.adapter.<bidder-name>.bids_received` - number of bids received from `<bidder-name>` when incoming request was from `<account-id>`
- `account.<account-id>.adapter.<bidder-name>.requests.(gotbids|nobid)` - number of requests made to `<bidder-name>` broken down by result status when incoming request was from `<account-id>`
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/org/prebid/server/metric/Metrics.java
Original file line number Diff line number Diff line change
Expand Up @@ -336,19 +336,19 @@ public void updateAdapterRequestErrorMetric(String bidder, MetricName errorMetri
forAdapter(bidder).request().incCounter(errorMetric);
}

public void updateAdapterRequestDisabledBidderMetric(String bidder, Account account) {
forAdapter(bidder).request().incCounter(MetricName.disabled_bidder);
public void updateDisabledBidderMetric(Account account) {
incCounter(MetricName.disabled_bidder);
if (accountMetricsVerbosityResolver.forAccount(account)
.isAtLeast(AccountMetricsVerbosityLevel.detailed)) {
forAccount(account.getId()).adapter().forAdapter(bidder).request().incCounter(MetricName.disabled_bidder);
forAccount(account.getId()).requests().incCounter(MetricName.disabled_bidder);
}
}

public void updateAdapterRequestUnknownBidderMetric(String bidder, Account account) {
forAdapter(bidder).request().incCounter(MetricName.unknown_bidder);
public void updateUnknownBidderMetric(Account account) {
incCounter(MetricName.unknown_bidder);
if (accountMetricsVerbosityResolver.forAccount(account)
.isAtLeast(AccountMetricsVerbosityLevel.detailed)) {
forAccount(account.getId()).adapter().forAdapter(bidder).request().incCounter(MetricName.unknown_bidder);
forAccount(account.getId()).requests().incCounter(MetricName.unknown_bidder);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1033,15 +1033,19 @@ RequestValidator requestValidator(
Metrics metrics,
JacksonMapper mapper,
@Value("${logging.sampling-rate:0.01}") double logSamplingRate,
@Value("${auction.strict-app-site-dooh:false}") boolean enabledStrictAppSiteDoohValidation) {
@Value("${auction.strict-app-site-dooh:false}") boolean enabledStrictAppSiteDoohValidation,
@Value("${settings.fail-on-disabled-bidders}") boolean failOnDisabledBidders,
@Value("${settings.fail-on-unknown-bidders}") boolean failOnUnknownBidders) {

return new RequestValidator(
bidderCatalog,
impValidator,
metrics,
mapper,
logSamplingRate,
enabledStrictAppSiteDoohValidation);
enabledStrictAppSiteDoohValidation,
failOnDisabledBidders,
failOnUnknownBidders);
}

@Bean
Expand Down
32 changes: 25 additions & 7 deletions src/main/java/org/prebid/server/validation/RequestValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ public class RequestValidator {
private final JacksonMapper mapper;
private final double logSamplingRate;
private final boolean enabledStrictAppSiteDoohValidation;
private final boolean failOnDisabledBidders;
private final boolean failOnUnknownBidders;

/**
* Constructs a RequestValidator that will use the BidderParamValidator passed in order to validate all critical
Expand All @@ -84,14 +86,18 @@ public RequestValidator(BidderCatalog bidderCatalog,
ImpValidator impValidator, Metrics metrics,
JacksonMapper mapper,
double logSamplingRate,
boolean enabledStrictAppSiteDoohValidation) {
boolean enabledStrictAppSiteDoohValidation,
boolean failOnDisabledBidders,
boolean failOnUnknownBidders) {

this.bidderCatalog = Objects.requireNonNull(bidderCatalog);
this.impValidator = Objects.requireNonNull(impValidator);
this.metrics = Objects.requireNonNull(metrics);
this.mapper = Objects.requireNonNull(mapper);
this.logSamplingRate = logSamplingRate;
this.enabledStrictAppSiteDoohValidation = enabledStrictAppSiteDoohValidation;
this.failOnDisabledBidders = failOnDisabledBidders;
this.failOnUnknownBidders = failOnUnknownBidders;
}

/**
Expand Down Expand Up @@ -514,13 +520,25 @@ private void validateAliases(Map<String, String> aliases, List<String> warnings,
final String alias = aliasToBidder.getKey();
final String coreBidder = aliasToBidder.getValue();
if (!bidderCatalog.isValidName(coreBidder)) {
warnings.add(
"request.ext.prebid.aliases.%s refers to unknown bidder: %s".formatted(alias, coreBidder));
metrics.updateAdapterRequestUnknownBidderMetric(coreBidder, account);
metrics.updateUnknownBidderMetric(account);

final String message = String.format("request.ext.prebid.aliases.%s refers to unknown bidder: %s",
alias, coreBidder);
if (failOnUnknownBidders) {
throw new ValidationException(message);
} else {
warnings.add(message);
}
} else if (!bidderCatalog.isActive(coreBidder)) {
warnings.add(
"request.ext.prebid.aliases.%s refers to disabled bidder: %s".formatted(alias, coreBidder));
metrics.updateAdapterRequestDisabledBidderMetric(coreBidder, account);
metrics.updateDisabledBidderMetric(account);

final String message = String.format("request.ext.prebid.aliases.%s refers to disabled bidder: %s",
alias, coreBidder);
if (failOnDisabledBidders) {
throw new ValidationException(message);
} else {
warnings.add(message);
}
}

if (alias.equals(coreBidder)) {
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ currency-converter:
settings:
generate-storedrequest-bidrequest-id: false
enforce-valid-account: false
fail-on-unknown-bidders: true
fail-on-disabled-bidders: true
database:
pool-size: 20
idle-connection-timeout: 300
Expand Down
48 changes: 23 additions & 25 deletions src/test/java/org/prebid/server/metric/MetricsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class MetricsTest {
private static final String RUBICON = "rubicon";
private static final String CONVERSANT = "conversant";
private static final String ACCOUNT_ID = "accountId";
private static final String ACCOUNT_ID_1 = "accountId1";
private static final String ANALYTIC_CODE = "analyticCode";

private MetricRegistry metricRegistry;
Expand Down Expand Up @@ -615,37 +616,34 @@ public void updateAdapterBidMetricsShouldUpdateMetrics() {
}

@Test
public void updateAdapterRequestUnknownBidderMetricsShouldIncrementMetrics() {
public void updateUnknownBidderMetricsShouldIncrementMetrics() {
// when
metrics.updateAdapterRequestUnknownBidderMetric(RUBICON, Account.empty(ACCOUNT_ID));
metrics.updateAdapterRequestUnknownBidderMetric(CONVERSANT, Account.empty(ACCOUNT_ID));
metrics.updateAdapterRequestUnknownBidderMetric(CONVERSANT, Account.empty(ACCOUNT_ID));
metrics.updateUnknownBidderMetric(Account.empty(ACCOUNT_ID));
metrics.updateUnknownBidderMetric(Account.empty(ACCOUNT_ID));
metrics.updateUnknownBidderMetric(Account.empty(ACCOUNT_ID_1));

// then
assertThat(metricRegistry.counter("adapter.rubicon.requests.unknown_bidder").getCount()).isOne();
assertThat(metricRegistry.counter("unknown_bidder").getCount()).isEqualTo(3);
assertThat(metricRegistry.counter(
"account.accountId.adapter.rubicon.requests.unknown_bidder").getCount()).isOne();
"account.accountId.requests.unknown_bidder").getCount()).isEqualTo(2);
assertThat(metricRegistry.counter(
"adapter.conversant.requests.unknown_bidder").getCount()).isEqualTo(2);
assertThat(metricRegistry.counter(
"account.accountId.adapter.conversant.requests.unknown_bidder").getCount()).isEqualTo(2);
"account.accountId1.requests.unknown_bidder").getCount()).isEqualTo(1);
}

@Test
public void updateAdapterRequestDisabledBidderMetricsShouldIncrementMetrics() {
public void updateDisabledBidderMetricsShouldIncrementMetrics() {
// when
metrics.updateAdapterRequestDisabledBidderMetric(RUBICON, Account.empty(ACCOUNT_ID));
metrics.updateAdapterRequestDisabledBidderMetric(CONVERSANT, Account.empty(ACCOUNT_ID));
metrics.updateAdapterRequestDisabledBidderMetric(CONVERSANT, Account.empty(ACCOUNT_ID));
metrics.updateDisabledBidderMetric(Account.empty(ACCOUNT_ID));
metrics.updateDisabledBidderMetric(Account.empty(ACCOUNT_ID));
metrics.updateDisabledBidderMetric(Account.empty(ACCOUNT_ID_1));

// then
assertThat(metricRegistry.counter("adapter.rubicon.requests.disabled_bidder").getCount()).isOne();
assertThat(metricRegistry.counter(
"account.accountId.adapter.rubicon.requests.disabled_bidder").getCount()).isOne();
"disabled_bidder").getCount()).isEqualTo(3);
assertThat(metricRegistry.counter(
"adapter.conversant.requests.disabled_bidder").getCount()).isEqualTo(2);
"account.accountId.requests.disabled_bidder").getCount()).isEqualTo(2);
assertThat(metricRegistry.counter(
"account.accountId.adapter.conversant.requests.disabled_bidder").getCount()).isEqualTo(2);
"account.accountId1.requests.disabled_bidder").getCount()).isEqualTo(1);
}

@Test
Expand Down Expand Up @@ -999,8 +997,8 @@ public void shouldNotUpdateAccountMetricsIfVerbosityIsNone() {
metrics.updateAdapterRequestNobidMetrics(RUBICON, Account.empty(ACCOUNT_ID));
metrics.updateAdapterRequestGotbidsMetrics(RUBICON, Account.empty(ACCOUNT_ID));
metrics.updateAdapterBidMetrics(RUBICON, Account.empty(ACCOUNT_ID), 1234L, true, "banner");
metrics.updateAdapterRequestDisabledBidderMetric(RUBICON, Account.empty(ACCOUNT_ID));
metrics.updateAdapterRequestUnknownBidderMetric(RUBICON, Account.empty(ACCOUNT_ID));
metrics.updateDisabledBidderMetric(Account.empty(ACCOUNT_ID));
metrics.updateUnknownBidderMetric(Account.empty(ACCOUNT_ID));

// then
assertThat(metricRegistry.counter("account.accountId.requests").getCount()).isZero();
Expand Down Expand Up @@ -1030,8 +1028,8 @@ public void shouldUpdateAccountRequestsMetricOnlyIfVerbosityIsBasic() {
metrics.updateAdapterRequestNobidMetrics(RUBICON, Account.empty(ACCOUNT_ID));
metrics.updateAdapterRequestGotbidsMetrics(RUBICON, Account.empty(ACCOUNT_ID));
metrics.updateAdapterBidMetrics(RUBICON, Account.empty(ACCOUNT_ID), 1234L, true, "banner");
metrics.updateAdapterRequestDisabledBidderMetric(RUBICON, Account.empty(ACCOUNT_ID));
metrics.updateAdapterRequestUnknownBidderMetric(RUBICON, Account.empty(ACCOUNT_ID));
metrics.updateDisabledBidderMetric(Account.empty(ACCOUNT_ID));
metrics.updateUnknownBidderMetric(Account.empty(ACCOUNT_ID));

// then
assertThat(metricRegistry.counter("account.accountId.requests").getCount()).isOne();
Expand Down Expand Up @@ -1061,8 +1059,8 @@ public void shouldUpdateAccountRequestsMetricOnlyIfVerbosityIsDetailed() {
metrics.updateAdapterRequestNobidMetrics(RUBICON, Account.empty(ACCOUNT_ID));
metrics.updateAdapterRequestGotbidsMetrics(RUBICON, Account.empty(ACCOUNT_ID));
metrics.updateAdapterBidMetrics(RUBICON, Account.empty(ACCOUNT_ID), 1234L, true, "banner");
metrics.updateAdapterRequestDisabledBidderMetric(RUBICON, Account.empty(ACCOUNT_ID));
metrics.updateAdapterRequestUnknownBidderMetric(RUBICON, Account.empty(ACCOUNT_ID));
metrics.updateDisabledBidderMetric(Account.empty(ACCOUNT_ID));
metrics.updateUnknownBidderMetric(Account.empty(ACCOUNT_ID));

// then
assertThat(metricRegistry.counter("account.accountId.requests").getCount()).isOne();
Expand All @@ -1079,9 +1077,9 @@ public void shouldUpdateAccountRequestsMetricOnlyIfVerbosityIsDetailed() {
assertThat(metricRegistry.counter("account.accountId.adapter.rubicon.bids_received").getCount())
.isEqualTo(1);
assertThat(metricRegistry.counter(
"account.accountId.adapter.rubicon.requests.unknown_bidder").getCount()).isEqualTo(1);
"unknown_bidder").getCount()).isEqualTo(1);
assertThat(metricRegistry.counter(
"account.accountId.adapter.rubicon.requests.disabled_bidder").getCount()).isEqualTo(1);
"account.accountId.requests.disabled_bidder").getCount()).isEqualTo(1);
}

@Test
Expand Down
Loading

0 comments on commit 3119f39

Please sign in to comment.