monitoring for the masses
TRANSCRIPT
Monitoring for the masses
Rodrigo Fernandez HTML5DevConf 2015
What is monitoring?
To be aware of the state of a system and observe any changes
which may occur over Cme
Why should we monitor?
Our responsibility shouldn’t end in a commit
Users
Product Owner
Developer System Admin
Code Infrastructure
How can we monitor?
Easy! We simply instrument our applicaCon and stream events data to a trending system for
analysis, correlaAon and anomaly detecAon.
app
server
messenger
tsdb
analyAcs
InstrumentaCon and telemetry
High ResoluCon Time API
var Circle = function (radius) { ! if (radius <= 0) { ! throw new RangeError('Radius must be greater than zero!'); ! } ! this.radius = radius; !}; !!Circle.prototype.perimeter = function () { ! return 2 * Math.PI * this.radius; !}; !!Circle.prototype.area = function () { ! return Math.PI * Math.pow(this.radius, 2); !};
var start = Date.now(); !!var circle = new Circle(1); !circle.perimeter(); !circle.area(); !!Date.now() - start;
var start = Date.now(); !!var circle = new Circle(1); !circle.perimeter(); !circle.area(); !!Date.now() - start; // 0
var start = performance.now(); !!var circle = new Circle(1); !circle.perimeter(); !circle.area(); !!performance.now() - start;
var start = performance.now(); !!var circle = new Circle(1); !circle.perimeter(); !circle.area(); !!performance.now() - start; // 0.1449999999999818
-performance.now() + performance.now();
-performance.now() + performance.now(); // 0.009999999999990905
NavigaCon Cming API
performance.timing; !!{ ! "navigationStart": 1444712367243, ! "unloadEventStart": 0, ! "unloadEventEnd": 0, ! "redirectStart": 0, ! "redirectEnd": 0, ! "fetchStart": 1444712367504, ! "domainLookupStart": 1444712367507, ! "domainLookupEnd": 1444712367538, ! "connectStart": 1444712367538, ! "connectEnd": 1444712367616, ! "secureConnectionStart": 0, ! "requestStart": 1444712367616, ! "responseStart": 1444712367866, ! "responseEnd": 1444712367954, ! "domLoading": 1444712367867, ! "domInteractive": 1444712368966, ! "domContentLoadedEventStart": 1444712368966, ! "domContentLoadedEventEnd": 1444712369180, ! "domComplete": 1444712376251, ! "loadEventStart": 1444712376251, ! "loadEventEnd": 1444712376891 !}
Resource Cming API
performance.getEntriesByType('resource'); !!{ ! "connectEnd": 0, ! "connectStart": 0, ! "domainLookupEnd": 0, ! "domainLookupStart": 0, ! "duration": 380.53100000252016, ! "entryType": "resource", ! "fetchStart": 661.7220000043744, ! "initiatorType": "link", ! "name": "https://lorem.ipsum.dolor/sit/amet.css", ! "redirectEnd": 0, ! "redirectStart": 0, ! "requestStart": 0, ! "responseEnd": 1042.2530000068946, ! "responseStart": 0, ! "secureConnectionStart": 0, ! "startTime": 661.7220000043744 !} !
User Cming API
var circle = new Circle(1); !!performance.mark(’p:before'); !!circle.perimeter(); !!performance.mark(’p:after'); !!performance.measure(’p', ’p:before', ’p:after'); !!performance.getEntriesByType('measure');
{ ! "name": "p", ! "entryType": "measure", ! "startTime": 31442.615000000005, ! "duration": 0.09000000000014552 !}
Beacon API
window.addEventListener('unload', function () { !! var entries = performance.getEntries(); !! navigator.sendBeacon('/phone/home', JSON.stringify(entries)); !!});
Polyfills (modernizr.com)
High ResoluAon Time hVps://gist.github.com/paulirish/5438650
NavigaAon Timing -‐
Resource Timing -‐
User Timing hVps://github.com/nicjansma/userCming.js
Page Visibility hVps://github.com/ai/visibility.js hVps://github.com/addyosmani/visibly.js hVps://github.com/mathiasbynens/jquery-‐visibility
Beacon hVps://github.com/miguelmota/Navigator.sendBeacon
Why the obsession with Amings and duraAons?
Doherty & Thadani (1982)
150
200
250
300
350
400
0.0 0.5 1.0 1.5 2.0 2.5 3.0
Tran
sacAon
s per Hou
r
System Response Time (Seconds)
InstrumentaCon with AOP
var Circle = function (radius) { ! if (radius <= 0) { ! throw new RangeError('Radius must be greater than zero!'); ! } ! this.radius = radius; !}; !!Circle.prototype.perimeter = function () { ! return 2 * Math.PI * this.radius; !}; !!Circle.prototype.area = function () { ! return Math.PI * Math.pow(this.radius, 2); !};
meld.before(Circle.prototype, 'perimeter', function () { ! performance.mark('Circle.perimeter:before'); !}); !!meld.after(Circle.prototype, 'perimeter', function () { ! performance.mark('Circle.perimeter:after'); ! performance.measure('Circle.perimeter', 'Circle.perimeter:before', !'Circle.perimeter:after'); !});
var c1 = new Circle(1); !c1.perimeter(); !!var c2 = new Circle(2); !c2.perimeter(); !
performance.getEntriesByName('Circle.perimeter'); !!![ ! { ! "name": "Circle.perimeter", ! "entryType": "measure", ! "startTime": 16.725, ! "duration": 0.11499999999999844 ! }, ! { ! "name": "Circle.perimeter", ! "entryType": "measure", ! "startTime": 16.89, ! "duration": 0.015000000000000568 ! } !] !
InstrumentaCon with decorators (ES2016)
let duration = function (target, name, descriptor) { ! let {value} = descriptor; ! let tag = `${target.constructor.name}.${name}`; ! let before = `${tag}:before`; ! let after = `${tag}:after`; !! descriptor.value = function(){ ! performance.mark(before); ! let result = value.call(this, ...arguments); ! performance.mark(after); ! performance.measure(tag, before, after); ! return result; ! }; !}; !
class Circle { ! constructor(radius) { ! if (radius <= 0) { ! throw new RangeError('Radius must be greater than zero!'); ! } ! this.radius = radius; ! } !! @duration ! perimeter() { ! return 2 * Math.PI * this.radius; ! } !! @duration ! area() { ! return Math.PI * Math.pow(this.radius, 2); ! } !} !
let c1 = new Circle(1); !let p1 = c1.perimeter(); !let a1 = c1.area(); !!!let c2 = new Circle(2); !let p2 = c2.perimeter(); !let a2 = c2.area(); !!!performance.getEntriesByType('measure'); !
[ ! { ! "name": "Circle.perimeter", ! "entryType": "measure", ! "startTime": 8.280000000000001, ! "duration": 0.05999999999999872 ! }, ! { ! "name": "Circle.area", ! "entryType": "measure", ! "startTime": 8.360000000000001, ! "duration": 0.10499999999999865 ! }, ! { ! "name": "Circle.perimeter", ! "entryType": "measure", ! "startTime": 8.5, ! "duration": 0.015000000000000568 ! }, ! { ! "name": "Circle.area", ! "entryType": "measure", ! "startTime": 8.525, ! "duration": 0.005000000000000782 ! } !] !
app
server
messenger
tsdb
analyAcs
Demo
Thank you!
github.com/rodfernandez