Weppy is a client-side library for reporting performance data. It can automatically collect page load data using window.performance API and allows any other metric to be reported as well.
Weppy is heavily inspired by BuckyClient. However it puts more focus into structure of the reported data, allows custom attributes to be reported with the measurement itself and supports sending the page context with all the measurements done on a page. See comparison with Bucky for more details.
You can report the following to the server:
{
"context": {
"url": "http://my.domain.com/article/Some_great_article",
"skin": "modern",
"user-agent": "Whatever User Agent the visitor has"
},
"data": {
"Lightbox.open": [
[ 0.24, { "image-count": 12 } ],
[ 0.12, { "image-count": 3 } ]
],
"pageview.fromuser.Testuser": [
[ 1 ]
]
}
}
by using code like this:
<script src="weppy.js"></script>
<script type="text/javascript">
Set your configuration
Weppy.setOptions({
context: {
url: window.location.href.split('#')[0],
skin: window.myApp.skinName,
'user-agent': window.navigator.userAgent
}
});
Report a page view from a user. You could as well want to include it in the global context and specify it above.
// report page view from logger in user
Weppy.count('pageview.fromuser.'+window.myApp.userName);
Create a helper Weppy object so you don't need to repeat the measurement name prefix
// handle Lightbox metrics
var lightboxMetrics = Weppy('Lightbox');
Let's try to report how long it takes to open a lightbox. First try to do it manually:
var openTimer = lightboxMetrics.timer.start('open');
// do some ajax call
ajax_call(function(response) {
openTimer.stop({
'image-count': response.imagesCount
});
});
On the other hand you might leverage the helper function timer.time():
lightboxMetrics.timer.time('open',function(stopTimer) {
ajax_call(function(response) { // called with global scope as we didn't pass third argument to .timer.time()
stopTimer({
'image-count': response.imagesCount
});
});
});
And then when a user opens two lightboxes during session, first one with 12 images and second with 3 images we might get the example data reported to server. For more features please refer to the next section API.
</script>
Weppy API can be accessed by using:
- global variable named
Weppy
orwindow.Weppy
(defined with empty namespace and empty prefix) - an object returned by
.into()
or.namespace()
bound to a specific namespace and prefix
Weppy API consists of the following methods:
Update global configuration. See options reference
Create and return a new Weppy object bound to a prefix with appended path
at the end.
Create and return a new Weppy object bound to a different namespace
and with specified prefix path
. Both
arguments can be an empty string meaning either selecting a default namespace or empty prefix.
Add a new measurement name
(type: "counter") with value
and optional annotations
.
Add a new measurement name
(type: "gauge") with value
and optional annotations
.
Send all pending measurements.
Instruct Weppy to report all metrics available in window.performance API as soon as DOMContentLoaded event is fired.
Start a new timer name
with optional annotations
. Return Timer
object for convenience.
Stop a timer name
and add a new measurement name
(type: "timer"). Extend previously defined annotations
with annotations
.
Add a new measurement name
(type: "timer") with duration
and optional annotations
.
Update annotations of currently running timer name
with annotations
.
Add a new measurement name
(type: "timer") with the time passed after window.performance.navigationStart
with
optional annotations
.
Call a function action
with scope
and arguments args
prepended by a callback that should be called when the
asynchronous operation finishes. The callback takes one optional parameter annotations
that are appended if specified.
When a callback gets called add a new measurement name
with the time of the operation and optional annotations
.
Call a function action
with scope
and args
. Then add a new measurement name
(type: "timer") with the time taken
to execute the function and optional annotations
.
Create and return a wrapper function that calls the function action
with optional scope override with scope
.
Arguments and return value are passed without change.
Each time the function gets called add a new measurement name
(type: "timer") with the time taken to execute
the function and optional annotations
.
Update annotations of given Timer
with annotations
.
Stop the timer and optionally update annotations
. Then add a new measurement with previously specified name
(type: "timer").
Type: string (default: "/weppy")
Absolute or relative base path for reporting data. Some automatic suffix is added, currently "/v3/store".
Type: "url" | "post" | callback (default: "url")
Transport that should be used to report collected measurements. See transport options explanation for more information.
Type: boolean (default: true)
Disables Weppy completely if active
is set to false.
Type: number (default: 0.01 = 1%)
Sampling rate in the range between 0 and 1. 0 is 0%, 0.1 is 10% and 1 is 100%.
Type: number (default: 1000)
When no new measurement is added within aggregationInterval
ms all the previously collected data is sent to the server.
Type: number (default: 5000)
Maximum age that the measurement could have before getting reported to the server.
Type: number (default: 3)
Time ang gauge measurements decimal precision.
Type: string (default: 'index')
Page name used to report page load performance data by sendPagePerformance()
.
Type: object (default: {})
Page context that is reported along with any measurement.
Type: boolean | function (default: false)
Debug control. Set to true to send debugging information to console using window.console.log()
. You also may pass
a function that will receive all the calls instead of console.log
.
Weppy uses "host" option (default: "/weppy") to find the base path on the server to report collected data to. Then it adds suffix "/vX/send" where X is replaced by protocol version. It always does a POST request.
Next you need to choose a method for encoding the data using the "transport" option. You have two options right now:
- "url" (default one) - puts the entire JSON data into a single URL parameter "p", example: "/weppy/v3/send?p=ENCODED_JSON_DATA"
- "post" - does a POST request and puts the JSON data into POST data.
To be correctly precise you have the third option for processing collected metrics. If you pass a function as a "transport" option you can take over the entire data reporting process. The normal request is not made in such case and your function will be called every time Weppy would send a request. The single parameter will be passed to this function containing the collected data as a plain Javascript object (exactly as in the example).
Weppy is definitely a browser-only library while Bucky can also run in node.js environment.
Page load data are reported using different namespacing.
Binding measurements to a specific prefix is done using Bucky('Lightbox')
in BuckyClient while you need to call
Weppy.into('Lightbox')
in Weppy. There is also support for namespaces in Weppy using
Weppy.namespace('MyNamespace','myprefix')
that ends up reporting MyNamespace::myprefix.measurementname'
.
Features not present in Bucky:
- global context
- measurement annotations
Features not supported by Weppy:
- requests
- timer.stopwatch()
- built-in "url" transport which puts the payload into GET parameter does not check for any URL length limit, that might cause your data will not be correctly reported if you queue too many measurements without issuing .flush() manually