Analytics Tags (aka ‘aTags’) are a log mechanism provided by PBS-core to allow modules to inform analytics adapters about what happened in the request. Use of the Analytics Tag structure is completely optional. It’s meant to be used when there are application or reporting reasons for sharing module results. See the Prebid Server module overview for background information.
This document defines a convention aimed at allowing module developers to create consistent aTags that can be easily read by analytics adapters.
The general idea is that aTags are a list of module-specific “activities” that have these attributes:
Here’s an example from the ORTB2 Blocking module:
[{
// scenario: response from bidderA blocked on badv for imp=1
activities: [{
name: "enforce-blocking",
status: "success", // no errors from the module
results: [{
status: "success-block",
values: { // these are module-specific details about the result
"attributes": ["badv"],
"adomain": ["bad.com"]
},
appliedto: {
"bidder": "bidderA",
impids: ["1"]
}
},{
status: "success-allow",
// no details needed when the response isn't blocked
appliedto: {
"bidder": "bidderA",
"impids": ["2","3","4"]
}
}]
}]
The following table contains the field conventions.
aTag Attr | Required? | Description | Type |
---|---|---|---|
activities | yes | One or more activities carried out by the module. | array of objects |
activities .name | yes | Name of the activity. Must be documented and unique within the module. | string |
activities .status | yes | Did the module operate successfully? Values are “error” or “success”. | string |
activities. results | no | Service-dependent details for what the service actually did. | array of objects |
activities. results. status | no | Detailed status for this specific action. Values: “error”, “success-allow”, “success-block”, “success-modify” | string |
activities. results. values | no | service-specific details | object |
activities. results .appliedto | no | Which object(s) the service examined or modified. | object |
activities. results. appliedto. impids | no | The service examined these specific impression objects or bid responses corresponding to imp objects | array of strings |
activities. results. appliedto. bidders | no | The service examined these specific bidders within the request or response. | array of strings |
activities. results. appliedto. bidder | no | The service examined this specific bidder (singular) within the request or response. | string |
activities. results. appliedto. request | no | The service examined the entire openrtb request object. This is in case the module updated something not adunit-specific. | boolean |
activities. results. appliedto. response | no | The service examined the entire openrtb response object. This is in case the module updated something not adunit-specific. | boolean |
aTags are for reporting. Start by considering what the module’s doing that consumers might want to display. Each processing stage the module operates in may be reported as a separate activity, or perhaps everything the module does is lumped as one activity.
Once the activities are defined, determine what reportable metric would be useful. Examples:
Case study: for the ORTB2 Blocking module, the requirement was to be able to report on what percentage of responses from each bidder were being thrown away due to blocking rules. This could have been done by defining a separate ‘activity’ for each of the 4 types of enforcement, but it was decided to just have one kind of activity (‘enforce-blocking’) and get the specific details as part of the ‘value’. There was no requirement to report on the outbound part of what the module does, so no aTags are created for that part of the functionality.
Once you know what reports are desired, figure out which activity ‘results’ are needed to generate those numbers.
For the ORTB2 Blocking module, the numbers needed are how often a given bidder has a response compared to how often their responses are rejected. So overall the block rate is: successBlock divided by (successBlock + successAllow).
Be sure to detail the results in your module documentation so that analytics adapters are aware of what they can look for.
Let them know:
values
If you’re an analytics adapter, you will be given the entire PBS ‘invocation context’, which contains a wealth of information about the auction.
In short, to get analytics tags, you’ll need to parse this data structure:
hookid.modulecode
is relevant for your analytics, grab analyticstags
Here’s an example of the data structured as JSON, though the details of the actual object will differ in PBS-Java and PBS-Go.
"stages": [
{
"stage": "raw-auction-request",
"outcomes": [
{
"entity": "bidrequest",
"executiontimemillis": 246,
"groups": [
{
"executiontimemillis": 190,
"invocationresults": [
{
"hookid": {
"modulecode": "MODULE1",
"hookimplcode": "HOOK_A"
},
"executiontimemillis": 123,
"status": "success",
"action": "update",
"debugmessages": [
"debug message"
],
"analyticstags": {
"activities": [
{
"name": "device-id",
"status": "success",
"results": [
{
"status": "success",
"values": {
"some-field": "some-value"
},
"appliedto": {
"impids": [ "impId1" ]
}
}
]
}
]
}
},
{
"hookid": {
"modulecode": "MODULE1",
"hookimplcode": "HOOK_B"
},
"status": "success",
"message": "inventory has no value",
"action": "reject"
}
]
}
]
}
]
},
{
"stage": "bidder-request",
"outcomes": [
{
"entity": "pubmatic", // entity is biddercode for some stages
"executiontimemillis": 246,
"groups": [
"invocationresults": {
"hookid": { ... }
"analyticstags": [{
...
]
}
]
},
{
"entity": "adform",
"executiontimemillis": 246,
"groups": [...]
}
]
}
]
See the implementation guide for your platform for specific syntax.
PBS-Java only
The use cases for server-side and client-side analytics are different:
This feature allows all relevant data passed to the client from Prebid Server so that client-side analytics can be the one to log the results. To allow the sharing of these details, there are two conditions:
analytics.allow-client-details: true
ext.prebid.analytics.options.enableclientdetails: true
If both are true, then any and all PBS analytics tags will be copied to the response field ext.prebid.analytics.tags.
The “pb-ortb-blocking” module at the “processed auction” stage adds the following Analytics Tags (from the ORTB2 blocking module)
[{
"activities": [{
"name": "enforce-blocking",
"status": "success",
"results": [{
"status": "success-block",
"values": {
"attributes": ["badv"],
"adomain": ["bad.com"]
},
"appliedto": {
"bidder": "bidderA",
"impids": ["1"]
}
},{
"status": "success-allow",
"appliedto": {
"bidder": "bidderA",
"impids": ["2","3","4"]
}
}]
}]
Also, the "vendorA-brand-safety" module at the "all processed bid responses" stage adds these aTags:
```json
[{
"activities": [{
"name": "brand-safety",
"status": "success",
"results": [{
"status": "success-allow",
"appliedto": {
"bidder": "bidderA",
"impids": ["1,","2","3","4"]
}
}]
}]
The resulting response with the request ext.prebid.analytics.options.enableclientdetails: true and config analytics.options.enableclientdetails:true would be:
// this is actually a nested object - but aggregated for readablility
"ext.prebid.analytics.tags": [{
"stage": "processed-auction-request",
"module": "pb-ortb-blocking",
"analyticstags": [{
"activities": [{
"name": "enforce-blocking",
"status": "success",
"results": [{
"status": "success-block",
"values": {
"attributes": ["badv"],
"adomain": ["bad.com"]
},
"appliedto": {
"bidder": "bidderA",
"impids": ["1"]
}
},{
"status": "success-allow",
"appliedto": {
"bidder": "bidderA",
"impids": ["2","3","4"]
}
}]
}]
},{
"stage": "all-processed-bid-responses",
"module": "vendorA-brand-safety",
"analyticstags": [{
"activities": [{
"name": "brand-safety",
"status": "success",
"results": [{
"status": "success-allow",
"appliedto": {
"bidder": "bidderA",
"impids": ["1,","2","3","4"]
}
}]
}]
It’s up to the client-side analytics adapters to be able to parse the module-specific contents of the aTags.