From 5a13b23016ee6eb1487d49f21b301ac93548de93 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Tue, 6 Mar 2018 09:02:42 -0800 Subject: [PATCH 1/4] split ga timing events into lbrynet and end-to-end --- helpers/googleAnalytics.js | 32 +++++++++++++++----------------- helpers/lbryApi.js | 20 ++++++++++++++++---- routes/api-routes.js | 13 ++++--------- 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/helpers/googleAnalytics.js b/helpers/googleAnalytics.js index 49079376..250ad617 100644 --- a/helpers/googleAnalytics.js +++ b/helpers/googleAnalytics.js @@ -1,7 +1,6 @@ const logger = require('winston'); const ua = require('universal-analytics'); -const config = require('../config/speechConfig.js'); -const googleApiKey = config.analytics.googleId; +const { analytics : { googleId }, site: { name: siteName } } = require('../config/speechConfig.js'); function createServeEventParams (headers, ip, originalUrl) { return { @@ -13,21 +12,19 @@ function createServeEventParams (headers, ip, originalUrl) { }; }; -function createPublishTimingEventParams (label, startTime, endTime, ip, headers) { +function createPublishTimingEventParams (category, variable, label, startTime, endTime) { const durration = endTime - startTime; return { - userTimingCategory : 'lbrynet', - userTimingVariableName: 'publish', + userTimingCategory : category, + userTimingVariableName: variable, userTimingTime : durration, userTimingLabel : label, - uip : ip, - userAgentOverride : headers['user-agent'], }; }; function sendGoogleAnalyticsEvent (ip, params) { const visitorId = ip.replace(/\./g, '-'); - const visitor = ua(googleApiKey, visitorId, { strictCidFormat: false, https: true }); + const visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true }); visitor.event(params, (err) => { if (err) { logger.error('Google Analytics Event Error >>', err); @@ -35,9 +32,8 @@ function sendGoogleAnalyticsEvent (ip, params) { }); }; -function sendGoogleAnalyticsTiming (ip, params) { - const visitorId = ip.replace(/\./g, '-'); - const visitor = ua(googleApiKey, visitorId, { strictCidFormat: false, https: true }); +function sendGoogleAnalyticsTiming (visitorId, params) { + const visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true }); visitor.timing(params, (err) => { if (err) { logger.error('Google Analytics Event Error >>', err); @@ -51,12 +47,14 @@ module.exports = { const params = createServeEventParams(headers, ip, originalUrl); sendGoogleAnalyticsEvent(ip, params); }, - sendGAAnonymousPublishTiming (headers, ip, originalUrl, startTime, endTime) { - const params = createPublishTimingEventParams('PUBLISH_ANONYMOUS_CLAIM', startTime, endTime, ip, headers); - sendGoogleAnalyticsTiming(ip, params); + sendGATimingEvent (category, variable, label, startTime, endTime) { + const params = createPublishTimingEventParams(category, variable, label, startTime, endTime); + sendGoogleAnalyticsTiming(siteName, params); }, - sendGAChannelPublishTiming (headers, ip, originalUrl, startTime, endTime) { - const params = createPublishTimingEventParams('PUBLISH_IN_CHANNEL_CLAIM', startTime, endTime, ip, headers); - sendGoogleAnalyticsTiming(ip, params); + chooseGaPublishLabel (publishParams) { + if (publishParams.channel_name || publishParams.channel_id) { + return 'PUBLISH_IN_CHANNEL'; + } + return 'PUBLISH_ANONYMOUS'; }, }; diff --git a/helpers/lbryApi.js b/helpers/lbryApi.js index b90cc594..3ad68ffe 100644 --- a/helpers/lbryApi.js +++ b/helpers/lbryApi.js @@ -3,8 +3,9 @@ const logger = require('winston'); const config = require('../config/speechConfig.js'); const { apiHost, apiPort } = config.api; const lbryApiUri = 'http://' + apiHost + ':' + apiPort; +const { chooseGaPublishLabel, sendGATimingEvent } = require('./googleAnalytics.js'); -function handleLbrynetResponse ({ data }, resolve, reject) { +const handleLbrynetResponse = ({ data }, resolve, reject) => { logger.debug('lbry api data:', data); if (data.result) { // check for an error @@ -18,11 +19,12 @@ function handleLbrynetResponse ({ data }, resolve, reject) { } // fallback in case it just timed out reject(JSON.stringify(data)); -} +}; module.exports = { publishClaim (publishParams) { logger.debug(`lbryApi >> Publishing claim to "${publishParams.name}"`); + const gaStartTime = Date.now(); return new Promise((resolve, reject) => { axios .post(lbryApiUri, { @@ -30,6 +32,7 @@ module.exports = { params: publishParams, }) .then(response => { + sendGATimingEvent('lbrynet', 'publish', chooseGaPublishLabel(publishParams), gaStartTime, Date.now()); handleLbrynetResponse(response, resolve, reject); }) .catch(error => { @@ -39,6 +42,7 @@ module.exports = { }, getClaim (uri) { logger.debug(`lbryApi >> Getting Claim for "${uri}"`); + const gaStartTime = Date.now(); return new Promise((resolve, reject) => { axios .post(lbryApiUri, { @@ -46,6 +50,7 @@ module.exports = { params: { uri, timeout: 20 }, }) .then(response => { + sendGATimingEvent('lbrynet', 'getClaim', 'GET', gaStartTime, Date.now()); handleLbrynetResponse(response, resolve, reject); }) .catch(error => { @@ -55,6 +60,7 @@ module.exports = { }, getClaimList (claimName) { logger.debug(`lbryApi >> Getting claim_list for "${claimName}"`); + const gaStartTime = Date.now(); return new Promise((resolve, reject) => { axios .post(lbryApiUri, { @@ -62,6 +68,7 @@ module.exports = { params: { name: claimName }, }) .then(response => { + sendGATimingEvent('lbrynet', 'getClaimList', 'CLAIM_LIST', gaStartTime, Date.now()); handleLbrynetResponse(response, resolve, reject); }) .catch(error => { @@ -71,6 +78,7 @@ module.exports = { }, resolveUri (uri) { logger.debug(`lbryApi >> Resolving URI for "${uri}"`); + const gaStartTime = Date.now(); return new Promise((resolve, reject) => { axios .post(lbryApiUri, { @@ -78,6 +86,7 @@ module.exports = { params: { uri }, }) .then(({ data }) => { + sendGATimingEvent('lbrynet', 'resolveUri', 'RESOLVE', gaStartTime, Date.now()); if (data.result[uri].error) { // check for errors reject(data.result[uri].error); } else { // if no errors, resolve @@ -91,12 +100,14 @@ module.exports = { }, getDownloadDirectory () { logger.debug('lbryApi >> Retrieving the download directory path from lbry daemon...'); + const gaStartTime = Date.now(); return new Promise((resolve, reject) => { axios .post(lbryApiUri, { method: 'settings_get', }) .then(({ data }) => { + sendGATimingEvent('lbrynet', 'getDownloadDirectory', 'SETTINGS_GET', gaStartTime, Date.now()); if (data.result) { resolve(data.result.download_directory); } else { @@ -110,6 +121,8 @@ module.exports = { }); }, createChannel (name) { + logger.debug(`lbryApi >> Creating channel for ${name}...`); + const gaStartTime = Date.now(); return new Promise((resolve, reject) => { axios .post(lbryApiUri, { @@ -120,11 +133,10 @@ module.exports = { }, }) .then(response => { - logger.verbose('createChannel response:', response); + sendGATimingEvent('lbrynet', 'createChannel', 'CHANNEL_NEW', gaStartTime, Date.now()); handleLbrynetResponse(response, resolve, reject); }) .catch(error => { - logger.error('createChannel error:', error); reject(error); }); }); diff --git a/routes/api-routes.js b/routes/api-routes.js index 044863f0..b4b8e451 100644 --- a/routes/api-routes.js +++ b/routes/api-routes.js @@ -7,7 +7,7 @@ const { claimNameIsAvailable, checkChannelAvailability, publish } = require('../ const { getClaimList, resolveUri, getClaim } = require('../helpers/lbryApi.js'); const { addGetResultsToFileData, createBasicPublishParams, createThumbnailPublishParams, parsePublishApiRequestBody, parsePublishApiRequestFiles, createFileData } = require('../helpers/publishHelpers.js'); const errorHandlers = require('../helpers/errorHandlers.js'); -const { sendGAAnonymousPublishTiming, sendGAChannelPublishTiming } = require('../helpers/googleAnalytics.js'); +const { sendGATimingEvent } = require('../helpers/googleAnalytics.js'); const { authenticateUser } = require('../auth/authentication.js'); const { getChannelData, getChannelClaims, getClaimId } = require('../controllers/serveController.js'); @@ -131,9 +131,9 @@ module.exports = (app) => { logger.debug('api/claim/publish req.body:', body); logger.debug('api/claim/publish req.files:', files); // define variables - let name, fileName, filePath, fileType, thumbnailFileName, thumbnailFilePath, thumbnailFileType, nsfw, license, title, description, thumbnail, channelName, channelId, channelPassword; + let channelName, channelId, channelPassword, description, fileName, filePath, fileType, gaStartTime, license, name, nsfw, thumbnail, thumbnailFileName, thumbnailFilePath, thumbnailFileType, title; // record the start time of the request - const publishStartTime = Date.now(); + gaStartTime = Date.now(); // validate the body and files of the request try { // validateApiPublishRequest(body, files); @@ -175,12 +175,7 @@ module.exports = (app) => { }, }); // record the publish end time and send to google analytics - const publishEndTime = Date.now(); - if (channelName) { - sendGAChannelPublishTiming(headers, ip, originalUrl, publishStartTime, publishEndTime); - } else { - sendGAAnonymousPublishTiming(headers, ip, originalUrl, publishStartTime, publishEndTime); - } + sendGATimingEvent('end-to-end', 'publish', 'publish endpoint', gaStartTime, Date.now()); }) .catch(error => { errorHandlers.handleErrorResponse(originalUrl, ip, error, res); From 64edbb3619c4049edb8ea795641c2b5c5bd25a9e Mon Sep 17 00:00:00 2001 From: bill bittner Date: Tue, 6 Mar 2018 09:27:35 -0800 Subject: [PATCH 2/4] updated label for lbrynet publish events --- helpers/googleAnalytics.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helpers/googleAnalytics.js b/helpers/googleAnalytics.js index 250ad617..55e991e9 100644 --- a/helpers/googleAnalytics.js +++ b/helpers/googleAnalytics.js @@ -53,8 +53,8 @@ module.exports = { }, chooseGaPublishLabel (publishParams) { if (publishParams.channel_name || publishParams.channel_id) { - return 'PUBLISH_IN_CHANNEL'; + return 'PUBLISH_IN_CHANNEL_CLAIM'; } - return 'PUBLISH_ANONYMOUS'; + return 'PUBLISH_ANONYMOUS_CLAIM'; }, }; From dedf13c3166c83757197e4404831218706058637 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Tue, 6 Mar 2018 09:39:22 -0800 Subject: [PATCH 3/4] changed end-to-end publish label --- helpers/googleAnalytics.js | 2 +- helpers/lbryApi.js | 4 ++-- routes/api-routes.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/helpers/googleAnalytics.js b/helpers/googleAnalytics.js index 55e991e9..a02b024c 100644 --- a/helpers/googleAnalytics.js +++ b/helpers/googleAnalytics.js @@ -51,7 +51,7 @@ module.exports = { const params = createPublishTimingEventParams(category, variable, label, startTime, endTime); sendGoogleAnalyticsTiming(siteName, params); }, - chooseGaPublishLabel (publishParams) { + chooseGaLbrynetPublishLabel (publishParams) { if (publishParams.channel_name || publishParams.channel_id) { return 'PUBLISH_IN_CHANNEL_CLAIM'; } diff --git a/helpers/lbryApi.js b/helpers/lbryApi.js index 3ad68ffe..47384316 100644 --- a/helpers/lbryApi.js +++ b/helpers/lbryApi.js @@ -3,7 +3,7 @@ const logger = require('winston'); const config = require('../config/speechConfig.js'); const { apiHost, apiPort } = config.api; const lbryApiUri = 'http://' + apiHost + ':' + apiPort; -const { chooseGaPublishLabel, sendGATimingEvent } = require('./googleAnalytics.js'); +const { chooseGaLbrynetPublishLabel, sendGATimingEvent } = require('./googleAnalytics.js'); const handleLbrynetResponse = ({ data }, resolve, reject) => { logger.debug('lbry api data:', data); @@ -32,7 +32,7 @@ module.exports = { params: publishParams, }) .then(response => { - sendGATimingEvent('lbrynet', 'publish', chooseGaPublishLabel(publishParams), gaStartTime, Date.now()); + sendGATimingEvent('lbrynet', 'publish', chooseGaLbrynetPublishLabel(publishParams), gaStartTime, Date.now()); handleLbrynetResponse(response, resolve, reject); }) .catch(error => { diff --git a/routes/api-routes.js b/routes/api-routes.js index b4b8e451..e65d0a1c 100644 --- a/routes/api-routes.js +++ b/routes/api-routes.js @@ -175,7 +175,7 @@ module.exports = (app) => { }, }); // record the publish end time and send to google analytics - sendGATimingEvent('end-to-end', 'publish', 'publish endpoint', gaStartTime, Date.now()); + sendGATimingEvent('end-to-end', 'publish', fileType, gaStartTime, Date.now()); }) .catch(error => { errorHandlers.handleErrorResponse(originalUrl, ip, error, res); From 24b95280be37b8f106d794b0364505085b771607 Mon Sep 17 00:00:00 2001 From: bill bittner Date: Tue, 6 Mar 2018 16:23:21 -0800 Subject: [PATCH 4/4] fixed spelling and ternary --- helpers/googleAnalytics.js | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/helpers/googleAnalytics.js b/helpers/googleAnalytics.js index a02b024c..b224638f 100644 --- a/helpers/googleAnalytics.js +++ b/helpers/googleAnalytics.js @@ -13,11 +13,11 @@ function createServeEventParams (headers, ip, originalUrl) { }; function createPublishTimingEventParams (category, variable, label, startTime, endTime) { - const durration = endTime - startTime; + const duration = endTime - startTime; return { userTimingCategory : category, userTimingVariableName: variable, - userTimingTime : durration, + userTimingTime : duration, userTimingLabel : label, }; }; @@ -51,10 +51,7 @@ module.exports = { const params = createPublishTimingEventParams(category, variable, label, startTime, endTime); sendGoogleAnalyticsTiming(siteName, params); }, - chooseGaLbrynetPublishLabel (publishParams) { - if (publishParams.channel_name || publishParams.channel_id) { - return 'PUBLISH_IN_CHANNEL_CLAIM'; - } - return 'PUBLISH_ANONYMOUS_CLAIM'; + chooseGaLbrynetPublishLabel ({ channel_name: channelName, channel_id: channelId }) { + return (channelName || channelId ? 'PUBLISH_IN_CHANNEL_CLAIM' : 'PUBLISH_ANONYMOUS_CLAIM'); }, };