summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Burwell <ben@benburwell.com>2015-05-22 00:46:04 -0400
committerBen Burwell <ben@benburwell.com>2015-05-22 00:46:04 -0400
commitc5afc5400d656b5584380f3e3a74f2b6dd94e257 (patch)
tree8d864b7e556c805440ad7eea37c4e4c5ed13fec1
parenta0eb7b9f5fbafc6d7fc0104b391949fb60b6fddd (diff)
Add metrics and update privacy info
-rw-r--r--_layouts/master.html1
-rw-r--r--assets/scripts/metrics.coffee104
-rw-r--r--privacy/index.md13
3 files changed, 117 insertions, 1 deletions
diff --git a/_layouts/master.html b/_layouts/master.html
index 73b1b8d..c2b4754 100644
--- a/_layouts/master.html
+++ b/_layouts/master.html
@@ -88,5 +88,6 @@
<footer class="print-hide">
<div class="light-gray"><a href="/license/">&copy; 2015</a> &bull; <a href="/privacy/">Privacy</a></div>
</footer>
+ <script async src="/assets/scripts/metrics.js"></script>
</body>
</html>
diff --git a/assets/scripts/metrics.coffee b/assets/scripts/metrics.coffee
new file mode 100644
index 0000000..9d246d2
--- /dev/null
+++ b/assets/scripts/metrics.coffee
@@ -0,0 +1,104 @@
+---
+---
+
+ENDPOINT_URL = 'https://metrics.benburwell.com/api/events'
+
+# Collects and reports browser metrics
+class Metrics
+
+ # Constructor for the Metrics class
+ constructor: ->
+
+ # Shall we track detailed metrics?
+ @dnt = false
+ @dnt = true if window.navigator.doNotTrack is '1'
+ @dnt = true if window.navigator.doNotTrack is 'yes'
+ @dnt = true if window.doNotTrack is '1'
+
+ # Initialize an object to store the metrics
+ @m =
+ timing_redirect: 0
+ timing_appCache: 0
+ timing_dns: 0
+ timing_tcp: 0
+ timing_request: 0
+ timing_response: 0
+ timing_processing: 0
+ timing_onLoad: 0
+ timing_click_to_interactive: 0
+ timing_total: 0
+ path: '[unknown]'
+ pageTitle: '[unknown]'
+ language: 'Unknown'
+ referring_domain: '[none]'
+ browser: 'Other'
+
+ # Gather metric values and add them to the field
+ collect: ->
+ # We collect certain metrics regardless of
+ # the user's Do Not Track setting -- these
+ # reveal no information about the browser
+ # other than the fact that the DNT flag is
+ # set.
+
+ t = window.performance?.timing
+
+ @m.timing_redirect = t?.redirectEnd - t?.redirectStart
+ @m.timing_appCache = t?.domainLookupStart - t?.fetchStart
+ @m.timing_dns = t?.domainLookupEnd - t?.domainLookupStart
+ @m.timing_tcp = t?.connectEnd - t?.connectStart
+ @m.timing_request = t?.responseStart - t?.requestStart
+ @m.timing_response = t?.responseEnd - t?.responseStart
+ @m.timing_processing = t?.domComplete - t?.domLoading
+ @m.timing_onLoad = t?.loadEventEnd - t?.loadEventStart
+ @m.timing_click_to_interactive = t?.domInteractive - t?.navigationStart
+ @m.timing_total = t?.loadEventEnd - t?.navigationStart
+
+ @m.path = window.location.pathname
+ @m.pageTitle = window.document.title
+
+ if @dnt
+ # These metrics are _not_ collected if DNT
+ # flag is set, as they can potentially
+ # reveal information about the browser or
+ # the user
+ @m.referring_domain = 'Not Reported' if window.document.referrer
+ @m.browser = 'Not Reported'
+ @m.language = 'Not Reported'
+ else
+ # Since the DNT flag is not set, we are going
+ # to gather a small bit of info about the
+ # visitor
+ @m.language = window.navigator.language
+ @m.referring_domain = window.document.referrer?.match(/\/\/(.+)\//)?[1]
+
+ # Now the ridiculous process of browser detection
+ # Ref: https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent
+ ua = window.navigator.userAgent
+
+ if /Firefox/.test(ua) and not /Seamonkey/.test(ua)
+ @m.browser = 'Firefox'
+ else if /Seamonkey/.test(ua)
+ @m.browser = 'Seamonkey'
+ else if /Chrome/.test(ua) and not /Chromium/.test(ua)
+ @m.browser = 'Chrome'
+ else if /Chromium/.test(ua)
+ @m.browser = 'Chromium'
+ else if /Safari/.test(ua) and not /Chrome/.test(ua) and not /Chromium/.test(ua)
+ @m.browser = 'Safari'
+ else if /OPR/.test(ua) or /Opera/.test(ua)
+ @m.browser = 'Opera'
+ else if /MSIE/.test(ua)
+ @m.browser = 'Internet Explorer'
+
+ send: ->
+ http = new XMLHttpRequest()
+ http.open 'POST', ENDPOINT_URL
+ http.setRequestHeader 'Content-Type', 'application/json;charset=UTF-8'
+ http.send JSON.stringify({type:'benburwell-com.pageview', properties: @m})
+
+setTimeout ->
+ m = new Metrics
+ m.collect()
+ m.send()
+, 100
diff --git a/privacy/index.md b/privacy/index.md
index 227e797..195e52f 100644
--- a/privacy/index.md
+++ b/privacy/index.md
@@ -10,4 +10,15 @@ This site contains scripts loaded from github.com in order to display code snipp
This site uses the CloudFlare CDN. Limited analytic data are kept by CloudFlare. CloudFlare also sets a `__cfduid` cookie for overriding IP-based security restrictions. You can read more about this cookie [here](https://support.cloudflare.com/hc/en-us/articles/200170156-What-does-the-CloudFlare-cfduid-cookie-do-). You can also read [CloudFlare's privacy policy](https://www.cloudflare.com/security-policy).
-If you have questions or concerns, please [shoot me a note](mailto:hi@benburwell.com).
+Furthermore, very limited metrics are collected and recorded for my own use. A [custom tracking script](https://github.com/benburwell/benburwell.github.io/assets/scripts/metrics.coffee) is used and metrics are stored in an isolated app running on Heroku. The data collected from all visitors are limited to that which cannot be used to identify the visitor, and includes:
+
+* page load timing information (using the [Navigation Timing API](http://www.w3.org/TR/navigation-timing/));
+* the path and title of the page visited.
+
+The metrics script respects the visitor's [Do Not Track](https://en.wikipedia.org/wiki/Do_Not_Track) preference. If the Do Not Track flag is _not_ set, the following information is collected in addition to the information collected about all visits:
+
+* language;
+* browser (not the entire User-Agent string);
+* referring domain.
+
+If you have questions or concerns, please [shoot me a note](mailto:ben@benburwell.com).