Skip to content

Commit 7dd0ad8

Browse files
authored
Merge pull request #3 from gokatz/v2_release_skull
add tweaks in measuring flow and few additional methods
2 parents c980ddb + d812cbc commit 7dd0ad8

11 files changed

Lines changed: 424 additions & 130 deletions

File tree

.ember-cli

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55

66
Setting `disableAnalytics` to true will prevent any data from being sent.
77
*/
8-
"disableAnalytics": false
8+
"disableAnalytics": false,
9+
"port": 4301
910
}

.eslintrc.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module.exports = {
2+
root: true,
3+
parserOptions: {
4+
ecmaVersion: 2017,
5+
sourceType: 'module'
6+
},
7+
extends: 'eslint:recommended',
8+
env: {
9+
browser: true
10+
},
11+
rules: {
12+
"no-console": "off"
13+
}
14+
};

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@
1515
/libpeerconnection.log
1616
npm-debug.log*
1717
testem.log
18+
*.DS_Store

.jshintrc

Lines changed: 0 additions & 32 deletions
This file was deleted.

README.md

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
# ember-appmetrics
1+
# ember-appmetrics 🐹
22

33
[![Build Status](https://travis-ci.org/gokatz/ember-appmetrics.svg?branch=master)](https://travis-ci.org/gokatz/ember-appmetrics)
44

5-
The ember version of [appmetrics.js](https://github.com/ebidel/appmetrics.js). Used to measure various things in your Ember app with ever simple APIs.
5+
Ember library used to measure various metrics in your Ember app with ultra simple APIs. Especially useful for [RUM](https://en.wikipedia.org/wiki/Real_user_monitoring) in Ember SPAs.
66

7-
## Installation
7+
## Installation 💻
88
For Ember CLI >= `0.2.3`:
99
```shell
1010
ember install ember-appmetrics
@@ -17,14 +17,22 @@ ember install:addon ember-appmetrics
1717
## Compatibility
1818
This addon is tested against the latest stable Ember version.
1919

20-
## Usage
20+
## Usage 🏹
2121

2222
Inject the metrics service like `'metrics: Ember.inject.service()'` into the class where you want to measure the performance or use initializers if you are going with one-time injection.
2323

24-
Addon provides three API to measure the performace of a given period.
25-
- `start` : need to call this api with an event name as argument to mark the starting point
26-
- `end` : need to call this api with an event name as argument to mark the ending point
27-
- `measure` : will return the calculated time for the given event
24+
Addon provides three API for measuring the performance of a given period.
25+
- `start` : need to call this API with an event name as an argument to mark the starting point.
26+
- `end` : need to call this API with an event name as an argument to mark the ending point and it returns the duration for the corresponding mark.
27+
- `measure` : will return the latest calculated time for the given event. This API will be deprecated in the future release in the favor of `end` API as the `end` method itself return the duration.
28+
29+
30+
- `getAllMetrics` :
31+
32+
1. will return an object containing all the previously measured metrics and its duration, if no arguments were passed.
33+
2. will return an array containing all the duration for the given metric name if the metric name is given as arguments.
34+
35+
- `clearAllMetrics` : Will clear out all the performance marks and measures.
2836

2937
```js
3038
this.get('metrics').start('accounts_page');
@@ -35,24 +43,24 @@ Addon provides three API to measure the performace of a given period.
3543
});
3644
```
3745

38-
## Browser support
46+
## Browser support 🌏
3947

40-
Since fall back machanism of all level has been handled in addon itself, the only thing addon needs is that the browser must have Date API, which is supported in all major and minor browsers.
48+
Since fall back mechanism of all level has been handled in the addon itself, the only thing addon need is that the browser must have Date API, which is supported in all major and minor browsers.
4149

4250
PS: In Safari, the User Timing API (performance.mark()) is not available, so the DevTools timeline will not be annotated with marks.
4351

44-
## Installation
52+
## Installation 💻
4553

4654
* `git clone` this repository
4755
* `npm install`
4856
* `bower install`
4957

50-
## Running
58+
## Running 👟👟
5159

5260
* `ember server`
53-
* Visit your app at http://localhost:4200.
61+
* Visit your app at http://localhost:4301.
5462

55-
## Running Tests
63+
## Running Tests 💉
5664

5765
* `ember test`
5866
* `ember test --server`
@@ -62,3 +70,7 @@ PS: In Safari, the User Timing API (performance.mark()) is not available, so the
6270
* `ember build`
6371

6472
For more information on using ember-cli, visit [http://www.ember-cli.com/](http://www.ember-cli.com/).
73+
74+
## Contribution 👨‍👧‍👦
75+
76+
Missing something? Let's work together to get that done 😉

addon/services/metrics.js

Lines changed: 81 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,44 @@
11
import Ember from 'ember';
22

3-
const { typeOf } = Ember;
3+
const { typeOf, Service } = Ember;
44

5-
export default Ember.Service.extend({
5+
export default Service.extend({
66
isMarkSupportedBrowser: true,
77
isNowSupportedBrowser: true,
88

99
secondaryPerformanceObj: {},
10+
metricsObj: {},
1011

1112
init() {
13+
14+
// detecting the browser's Compatibility over window.performance.mark and window.performance.now
15+
1216
if (!(window.performance && window.performance.mark)) {
13-
console.log('Performance.mark is not supported in this browser. Hence falling back to performance.now()');
17+
console.warn('Performance.mark is not supported in this browser. Hence falling back to performance.now()');
1418
this.set('isMarkSupportedBrowser', false);
1519

1620
if (!(window.performance && window.performance.now)) {
17-
console.log('Performance.now is also not supported. Hence falling back to javascript Date API');
21+
console.warn('Performance.now is also not supported. Hence falling back to javascript Date API');
1822
this.set('isNowSupportedBrowser', false);
19-
2023
}
2124
}
2225
},
2326

2427
start(eventName) {
28+
29+
if (typeOf(eventName) !== 'string') {
30+
console.error('Expected type String for invoking `start`');
31+
return -1;
32+
}
33+
2534
let secondaryPerformanceObj = this.get('secondaryPerformanceObj');
2635
secondaryPerformanceObj[eventName] = secondaryPerformanceObj[eventName] || {};
2736
let eventObj = secondaryPerformanceObj[eventName];
2837

29-
if (typeOf(eventName) !== 'string') {
30-
throw 'Expected type String for invoking `start`';
31-
}
3238

3339
if (this.get('isNowSupportedBrowser')) {
3440
if (this.get('isMarkSupportedBrowser')) {
35-
performance.mark(`mark_${eventName}_start`);
41+
performance.mark(`eam:mark_${eventName}_start`);
3642
} else {
3743
eventObj.start = window.performance.now();
3844
}
@@ -44,48 +50,102 @@ export default Ember.Service.extend({
4450
},
4551

4652
end(eventName) {
47-
let secondaryPerformanceObj = this.get('secondaryPerformanceObj');
48-
49-
secondaryPerformanceObj[eventName] = secondaryPerformanceObj[eventName] || {};
50-
let eventObj = secondaryPerformanceObj[eventName];
5153

5254
if (typeOf(eventName) !== 'string') {
53-
throw 'Expected type String for invoking `end`';
55+
console.error('Expected type String for invoking `end`');
56+
return -1;
5457
}
5558

59+
let secondaryPerformanceObj = this.get('secondaryPerformanceObj');
60+
secondaryPerformanceObj[eventName] = secondaryPerformanceObj[eventName] || {}; // creating a new entry if not already present
61+
let eventObj = secondaryPerformanceObj[eventName];
62+
63+
let metricObj = this.get('metricsObj');
64+
metricObj[eventName] = metricObj[eventName] || []; // creating a new entry if not already present
65+
let metricArray = metricObj[eventName];
66+
5667
if (this.get('isNowSupportedBrowser')) {
57-
let startMark = `mark_${eventName}_start`;
58-
let endMark = `mark_${eventName}_end`;
68+
let startMark = `eam:mark_${eventName}_start`;
69+
let endMark = `eam:mark_${eventName}_end`;
5970

6071
if (this.get('isMarkSupportedBrowser')) {
6172
performance.mark(endMark);
62-
performance.measure(eventName, startMark, endMark);
73+
performance.measure(`eam:${eventName}`, startMark, endMark);
6374
} else {
6475
eventObj.end = window.performance.now();
6576
}
6677
} else {
6778
eventObj.end = new Date().valueOf();
6879
}
69-
return;
80+
81+
/*
82+
pushing to the `metricsObj` here, since pushing in measure method will leads to have duplicate entires when
83+
the measure api is invoked by the consuming application
84+
*/
85+
let duration = this.measure(eventName);
86+
metricArray.push(duration);
87+
return duration;
7088
},
7189

7290
measure(eventName) {
91+
if (typeOf(eventName) !== 'string') {
92+
console.error('Expected type String for invoking `measure`');
93+
return -1;
94+
}
95+
7396
let secondaryPerformanceObj = this.get('secondaryPerformanceObj');
7497
let eventObj = secondaryPerformanceObj[eventName] || {};
98+
7599
let duration;
76100

77101
if (this.get('isMarkSupportedBrowser')) {
78-
let perfEntries = performance.getEntriesByName(eventName);
79-
// poping up the last entry pushed into teh array
102+
let perfEntries = performance.getEntriesByName(`eam:${eventName}`);
103+
// poping up the last entry pushed into the array
80104
let entry = perfEntries[perfEntries.length - 1];
81105
if (entry) {
82106
duration = entry.duration;
83107
}
84108
} else {
85109
duration = eventObj.end - eventObj.start;
110+
eventObj.duration = duration;
111+
}
112+
return typeOf(duration) === 'number' ? duration : -1;
113+
},
114+
115+
getAllMetrics(eventName) {
116+
/*
117+
getAllMetrics will return the entires of given event name.
118+
if no eventName is given, it will return the entire metricsObj
119+
*/
120+
121+
if (eventName) {
122+
return this.get(`metricsObj.${eventName}`) || {};
123+
}
124+
return this.get('metricsObj') || {};
125+
},
126+
127+
clearAllMetrics() {
128+
if (this.get('isMarkSupportedBrowser')) {
129+
let eventNames = Object.keys(this.get('metricsObj') || {});
130+
131+
eventNames.forEach((eventName) => {
132+
this.clearMetric(eventName);
133+
});
86134
}
135+
this.set('secondaryPerformanceObj', {});
136+
this.set('metricsObj', {});
137+
},
138+
139+
clearMetric(eventName) {
140+
if (this.get('isMarkSupportedBrowser')) {
141+
performance.clearMeasures(`eam:${eventName}`);
142+
}
143+
let secondaryPerformanceObj = this.get('secondaryPerformanceObj') || {};
144+
delete secondaryPerformanceObj[eventName];
145+
146+
let metricsObj = this.get('metricsObj') || {};
147+
delete metricsObj[eventName];
87148

88-
return duration || -1;
89149
}
90150

91151
});

package.json

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "ember-appmetrics",
3-
"version": "0.1.0",
4-
"description": "Ember library used to measure various things in your Ember app with ultra simple APIs.",
3+
"version": "1.0.0",
4+
"description": "Ember library used to measure various metrics in your Ember app with ultra simple APIs. Especially useful for RUM in Ember SPA.",
55
"keywords": [
66
"ember-addon"
77
],
@@ -22,20 +22,18 @@
2222
},
2323
"devDependencies": {
2424
"broccoli-asset-rev": "^2.4.5",
25-
"ember-ajax": "^2.4.1",
2625
"ember-cli": "2.10.0",
2726
"ember-cli-app-version": "^2.0.0",
2827
"ember-cli-dependency-checker": "^1.3.0",
28+
"ember-cli-eslint": "4.1.0",
2929
"ember-cli-htmlbars": "^1.0.10",
3030
"ember-cli-htmlbars-inline-precompile": "^0.3.3",
3131
"ember-cli-inject-live-reload": "^1.4.1",
32-
"ember-cli-jshint": "^2.0.1",
3332
"ember-cli-qunit": "^3.0.1",
3433
"ember-cli-release": "^0.2.9",
3534
"ember-cli-sri": "^2.1.0",
3635
"ember-cli-test-loader": "^1.1.0",
3736
"ember-cli-uglify": "^1.2.0",
38-
"ember-data": "^2.10.0",
3937
"ember-disable-prototype-extensions": "^1.1.0",
4038
"ember-export-application-global": "^1.0.5",
4139
"ember-load-initializers": "^0.5.1",

tests/.eslintrc.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = {
2+
env: {
3+
embertest: true
4+
},
5+
rules: {
6+
"no-console": "off"
7+
}
8+
};

0 commit comments

Comments
 (0)