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);