Fix #126 Google Analytics

- Added analytics.js to navigation
- Converted $scope.report to $scope.marvelOpts.report in optin html
- Instrumented navigation panel for Google Analytics
- Instrumented sense for Google Analytics
- Moved the Google Analytics tracking code to config.js
- Changed the config.js to use an absolute url for the settings
  dependency since analytics.js needs to reuse the config (only an issue in Sense )
- Moved analytics to the common directory
- Refactored analytics to return an object with a track function for
  fine grain tracking and a pageview for sending the page view
- Added checks around the pageview code to only trigger a pageview()
  when the user has implictly set their optin/optout status (checking
  marvelOpts.version is set)
- Added ga.pageview() to setOptIn() to fire if the user opts in
- Ensuring the cluster report and analytics.js doesnt get sent or load before they make their decission
This commit is contained in:
Chris Cowan 2014-03-05 08:49:41 -07:00
parent 90f555f861
commit 55f806075e
9 changed files with 93 additions and 15 deletions

View file

@ -14,6 +14,10 @@ module.exports = function (grunt) {
dev: '":'+ (grunt.option('es_port') || 9200) +'"',
dist: "(window.location.port !== '' ? ':'+window.location.port : '')"
},
ga_tracking_code: {
dev: '"UA-12395217-6"',
dist: '"UA-12395217-5"'
},
statsReportUrl: {
dev: '"http://" + window.location.hostname + ":'+ (grunt.option('es_port') || 9200) +'/.marvel_cluster_report/report"',
dist: '"https://marvel-stats.elasticsearch.com/"'

44
common/analytics.js Normal file
View file

@ -0,0 +1,44 @@
define(function (require) {
'use strict';
var config = require('/kibana/config.js');
var loaded = false;
window.GoogleAnalyticsObject = 'ga';
// create an initali ga function. queue commands so it's executed
// once the analytics.js loads.
window.ga = window.ga || function () {
(window.ga.q = window.ga.q || []).push(arguments);
};
// set the time as an interger for timmings
window.ga.l = 1 * new Date();
// create the async tag and inject it into the page.
function load () {
if (loaded) return;
var asyncTag = document.createElement('script');
var firstScript = document.getElementsByTagName('script')[0];
asyncTag.async = 1;
asyncTag.src = '//www.google-analytics.com/analytics.js';
firstScript.parentNode.insertBefore(asyncTag, firstScript);
loaded = true;
}
// return the ga function
window.ga('create', config.ga_tracking_code, 'auto');
return {
track: function () {
load();
window.ga.apply(null, Array.prototype.slice.call(arguments));
},
pageview: function () {
load();
window.ga('send', 'pageview', {
cookieDomain: window.location.hostname,
page: window.location.pathname+window.location.hash,
location: window.location.href
});
}
}
});

View file

@ -3,7 +3,7 @@
* config.js is where you will find the core Kibana configuration. This file contains parameter that
* must be set before kibana is run for the first time.
*/
define(['settings'],
define(['/kibana/app/components/settings.js'],
function (Settings) {
"use strict";
@ -68,6 +68,7 @@ define(['settings'],
]
});
s.stats_report_url = @@stats_report_url;
s.ga_tracking_code = @@ga_tracking_code;
return s;
});

View file

@ -14,9 +14,10 @@ define([
'app',
'kbn',
'lodash',
'/common/analytics.js',
'factories/store'
],
function (angular, app, kbn, _) {
function (angular, app, kbn, _, ga) {
'use strict';
var module = angular.module('kibana.panels.marvel.cluster', []);
@ -48,7 +49,6 @@ function (angular, app, kbn, _) {
$scope.init = function () {
$scope.kbnVersion = kbnVersion;
$scope.report = marvelOpts.report;
// If the user hasn't opted in or out, ask them to.
if(marvelOpts.version == null || marvelOpts.version !== kbnVersion) {
@ -138,7 +138,7 @@ function (angular, app, kbn, _) {
$scope.setOptIn = function(val) {
marvelOpts.version = kbnVersion;
marvelOpts.report = val;
$scope.report = val;
if (val) ga.pageview();
};
$scope.clearMarvelStorage = function() {
@ -165,7 +165,7 @@ function (angular, app, kbn, _) {
// Checks if we should send a report
var checkReport = function() {
if(marvelOpts.report) {
if(marvelOpts.version && marvelOpts.report) {
if(marvelOpts.lastReport == null) {
return true;
} else if (new Date().getTime() - parseInt(marvelOpts.lastReport,10) > reportInterval) {
@ -177,7 +177,7 @@ function (angular, app, kbn, _) {
return false;
}
};
var sendReport = function(data) {
if (!$scope.config.stats_report_url) {
return;

View file

@ -4,10 +4,10 @@
…or talk to us about our <a href="http://www.elasticsearch.com/support/" target="_BLANK">annual support packages</a> that include Marvel for free.</p>
<p>
<a href="http://www.elasticsearch.com/marvel/" target="_BLANK" class="btn btn-success">Buy Marvel Now</a>
<a class="btn btn-success" ng-click="setOptIn(report);dismiss();">Continue Free Trial</a>
<a class="btn btn-success" ng-click="setOptIn(marvelOpts.report);dismiss();">Continue Free Trial</a>
</p>
<p>Sharing your cluster statistics with us to help us improve. Totally anonymous and never shared with <br/>
anyone. Not ever. Curious what we see? <a ng-click="showSample=true">View report here</a>. <span ng-show="report">Not interested? <a ng-click="setOptIn(false);">Opt out here</a></span><span ng-hide="report">Opted Out? <a ng-click="setOptIn(true);">Click here to opt back in.</a></span></p>
anyone. Not ever. Curious what we see? <a ng-click="showSample=true">View report here</a>. <span ng-show="marvelOpts.report">Not interested? <a ng-click="setOptIn(false);">Opt out here</a></span><span ng-hide="marvelOpts.report">Opted Out? <a ng-click="setOptIn(true);">Click here to opt back in.</a></span></p>
<div ng-show="showSample" style="text-align: left;">
<h5>Sample Statistics</h5>
<span class="close" ng-click="showSample=false" style="margin: 10px 10px; font-size: 30px;">&times;</span>

View file

@ -15,20 +15,24 @@ define([
'angular',
'app',
'jquery',
'lodash'
'lodash',
'/common/analytics.js',
'factories/store'
],
function (angular, app, $, _) {
function (angular, app, $, _, ga) {
'use strict';
var module = angular.module('kibana.panels.marvel.navigation', []);
app.useModule(module);
module.controller('marvel.navigation', function($scope, $http) {
module.controller('marvel.navigation', function($scope, $http, storeFactory) {
$scope.panelMeta = {
status : "Experimental",
description : "A simple dropdown panel with a list of links"
};
// Check to see if the user is opted in to reporting
var marvelOpts = storeFactory($scope, 'marvelOpts');
// Set and populate defaults
var _d = {
@ -69,6 +73,10 @@ function (angular, app, $, _) {
$scope.links = $scope.panel.links;
}
if (marvelOpts.version && marvelOpts.report) {
ga.pageview();
}
if($scope.panel.source === 'url') {
$http.get($scope.panel.url).then(function(response) {
var a = $('<a />');

View file

@ -9,9 +9,10 @@ define([
'misc_inputs',
'es',
'utils',
'_'
'_',
'analytics'
],
function (curl, $helpPopup, history, input, $, mappings, output, miscInputs, es, utils, _) {
function (curl, $helpPopup, history, input, $, mappings, output, miscInputs, es, utils, _, ga) {
'use strict';
$(document.body).removeClass('fouc');
@ -19,6 +20,16 @@ define([
var $esServer = miscInputs.$esServer;
var $send = miscInputs.$send;
var marvelOpts = localStorage.getItem('marvelOpts');
if (marvelOpts) {
try {
marvelOpts = JSON.parse(marvelOpts);
if (marvelOpts.version && marvelOpts.report) {
ga.pageview();
}
} catch (e) { } // Meh! Who cares...
}
function submitCurrentRequestToES(cb) {
cb = typeof cb === 'function' ? cb : $.noop;

View file

@ -16,7 +16,9 @@
'ace': '../vendor/ace/ace',
'ace_mode_json': '../vendor/ace/mode-json',
'ace_ext_language_tools': '../vendor/ace/ext-language_tools',
'ace_ext_searchbox': '../vendor/ace/ext-searchbox'
'ace_ext_searchbox': '../vendor/ace/ext-searchbox',
'analytics': '/common/analytics',
'lodash': '/kibana/vendor/lodash'
},
map: {
'*': {
@ -45,4 +47,4 @@
},
waitSeconds: 60,
});
})();
})();

View file

@ -11,6 +11,10 @@ module.exports = function (config) {
{
match: 'stats_report_url',
replacement: '<%= statsReportUrl.dev %>',
},
{
match: 'ga_tracking_code',
replacement: '<%= ga_tracking_code.dev %>',
}
]
},
@ -28,6 +32,10 @@ module.exports = function (config) {
{
match: 'stats_report_url',
replacement: '<%= statsReportUrl.dist %>',
},
{
match: 'ga_tracking_code',
replacement: '<%= ga_tracking_code.dist %>',
}
]
},