Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added support for sampling in ga and base adapter, fixed up some tests #1011

Merged
merged 6 commits into from
Apr 7, 2017
Merged
74 changes: 50 additions & 24 deletions src/adapters/analytics/AnalyticsAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ const ENDPOINT = 'endpoint';
const BUNDLE = 'bundle';

var _timedOutBidders = [];
var _sampled = true;

export default function AnalyticsAdapter({ url, analyticsType, global, handler }) {
var _queue = [];
var _eventCount = 0;
var _enableCheck = true;
var _handlers;

if (analyticsType === LIBRARY) {
loadScript(url, _emptyQueue);
Expand All @@ -35,6 +37,7 @@ export default function AnalyticsAdapter({ url, analyticsType, global, handler }
track: _track,
enqueue: _enqueue,
enableAnalytics: _enable,
disableAnalytics: _disable,
getAdapterType: () => analyticsType,
getGlobal: () => global,
getHandler: () => handler,
Expand Down Expand Up @@ -71,40 +74,63 @@ export default function AnalyticsAdapter({ url, analyticsType, global, handler }
function _enable(config) {
var _this = this;

//first send all events fired before enableAnalytics called
events.getEvents().forEach(event => {
if (!event) {
return;
}
if (typeof config === 'object' && typeof config.options === 'object') {
_sampled = typeof config.options.sampling === 'undefined' || Math.random() < parseFloat(config.options.sampling);
} else {
_sampled = true;
}

const { eventType, args } = event;

if (eventType === BID_TIMEOUT) {
_timedOutBidders = args.bidderCode;
} else {
_enqueue.call(_this, { eventType, args });
}
});
if (_sampled) {
Copy link
Member

@mkendall07 mkendall07 Mar 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edit: ignore this - I see how this work now.

//first send all events fired before enableAnalytics called
events.getEvents().forEach(event => {
if (!event) {
return;
}

const { eventType, args } = event;

if (eventType === BID_TIMEOUT) {
_timedOutBidders = args.bidderCode;
} else {
_enqueue.call(_this, { eventType, args });
}
});

//Next register event listeners to send data immediately

_handlers = {
[BID_REQUESTED]: args => this.enqueue({ eventType: BID_REQUESTED, args }),
[BID_RESPONSE]: args => this.enqueue({ eventType: BID_RESPONSE, args }),
[BID_TIMEOUT]: args => this.enqueue({ eventType: BID_TIMEOUT, args }),
[BID_WON]: args => this.enqueue({ eventType: BID_WON, args }),
[BID_ADJUSTMENT]: args => this.enqueue({ eventType: BID_ADJUSTMENT, args }),
[AUCTION_INIT]: args => {
args.config = config.options; // enableAnaltyics configuration object
this.enqueue({ eventType: AUCTION_INIT, args });
}
};

utils._each(_handlers, (handler, event) => {
events.on(event, handler);
});
} else {
utils.logMessage(`Analytics adapter for "${global}" disabled by sampling`);
}

//Next register event listeners to send data immediately

//bidRequests
events.on(BID_REQUESTED, args => this.enqueue({ eventType: BID_REQUESTED, args }));
events.on(BID_RESPONSE, args => this.enqueue({ eventType: BID_RESPONSE, args }));
events.on(BID_TIMEOUT, args => this.enqueue({ eventType: BID_TIMEOUT, args }));
events.on(BID_WON, args => this.enqueue({ eventType: BID_WON, args }));
events.on(BID_ADJUSTMENT, args => this.enqueue({ eventType: BID_ADJUSTMENT, args }));
events.on(AUCTION_INIT, args => {
args.config = config.options; // enableAnaltyics configuration object
this.enqueue({ eventType: AUCTION_INIT, args });
});

// finally set this function to return log message, prevents multiple adapter listeners
this.enableAnalytics = function _enable() {
return utils.logMessage(`Analytics adapter for "${global}" already enabled, unnecessary call to \`enableAnalytics\`.`);
};
}

function _disable() {
utils._each(_handlers, (handler, event) => {
events.off(event, handler);
});
}

function _emptyQueue() {
if (_enableCheck) {
for (var i = 0; i < _queue.length; i++) {
Expand Down
87 changes: 48 additions & 39 deletions src/adapters/analytics/ga.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ var _category = 'Prebid.js Bids';
var _eventCount = 0;
var _enableDistribution = false;
var _trackerSend = null;
var _sampled = true;

/**
* This will enable sending data to google analytics. Only call once, or duplicate data will be sent!
Expand All @@ -30,6 +31,8 @@ exports.enableAnalytics = function ({ provider, options }) {

_gaGlobal = provider || 'ga';
_trackerSend = options && options.trackerName ? options.trackerName + '.send' : 'send';
_sampled = typeof options === "undefined" || typeof options.sampling === "undefined" ||
Math.random() < parseFloat(options.sampling);

if (options && typeof options.global !== 'undefined') {
_gaGlobal = options.global;
Expand All @@ -40,53 +43,59 @@ exports.enableAnalytics = function ({ provider, options }) {

var bid = null;

//first send all events fired before enableAnalytics called
if(_sampled) {
//first send all events fired before enableAnalytics called

var existingEvents = events.getEvents();
utils._each(existingEvents, function (eventObj) {
var args = eventObj.args;
if (!eventObj) {
return;
}
var existingEvents = events.getEvents();

if (eventObj.eventType === BID_REQUESTED) {
bid = args;
sendBidRequestToGa(bid);
} else if (eventObj.eventType === BID_RESPONSE) {
//bid is 2nd args
bid = args;
sendBidResponseToGa(bid);
utils._each(existingEvents, function (eventObj) {
if (typeof eventObj !== "object") {
return;
}
var args = eventObj.args;

if (eventObj.eventType === BID_REQUESTED) {
bid = args;
sendBidRequestToGa(bid);
} else if (eventObj.eventType === BID_RESPONSE) {
//bid is 2nd args
bid = args;
sendBidResponseToGa(bid);

} else if (eventObj.eventType === BID_TIMEOUT) {
const bidderArray = args;
sendBidTimeouts(bidderArray);
} else if (eventObj.eventType === BID_WON) {
bid = args;
sendBidWonToGa(bid);
}
});

} else if (eventObj.eventType === BID_TIMEOUT) {
const bidderArray = args;
sendBidTimeouts(bidderArray);
} else if (eventObj.eventType === BID_WON) {
bid = args;
sendBidWonToGa(bid);
}
});
//Next register event listeners to send data immediately

//Next register event listeners to send data immediately
//bidRequests
events.on(BID_REQUESTED, function (bidRequestObj) {
sendBidRequestToGa(bidRequestObj);
});

//bidRequests
events.on(BID_REQUESTED, function (bidRequestObj) {
sendBidRequestToGa(bidRequestObj);
});
//bidResponses
events.on(BID_RESPONSE, function (bid) {
sendBidResponseToGa(bid);
});

//bidResponses
events.on(BID_RESPONSE, function (bid) {
sendBidResponseToGa(bid);
});
//bidTimeouts
events.on(BID_TIMEOUT, function (bidderArray) {
sendBidTimeouts(bidderArray);
});

//bidTimeouts
events.on(BID_TIMEOUT, function (bidderArray) {
sendBidTimeouts(bidderArray);
});
//wins
events.on(BID_WON, function (bid) {
sendBidWonToGa(bid);
});

//wins
events.on(BID_WON, function (bid) {
sendBidWonToGa(bid);
});
} else {
utils.logMessage("Prebid.js google analytics disabled by sampling");
}

// finally set this function to return log message, prevents multiple adapter listeners
this.enableAnalytics = function _enable() {
Expand Down
Loading