Bmansurov has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/250057

Change subject: Add Schema class
......................................................................

Add Schema class

The class allows inheriting classes to log events based on a sampling
rate if sampling is enabled.

How to use:
```
mw.loader.using( 'ext.eventLogging.Schema' ).done( function () {
    var MySchema = function () {
            this.name = 'MySchema';
            this.defaults = {
                someDefaultData: 'hello'
            };
            this.isSampled = true;
            this.samplingRate = 0.01;
        },
        mySchema;

    OO.inheritClass( MySchema, mw.eventLog.Schema );

    mySchema = new MySchema();
    mySchema.log( { 'action': 'viewed' } );
    // Log beacon when navigating away from the page
    mySchema.logBeacon( { 'action': 'clicked' } );
} );
```

Bug: T117140
Change-Id: Iea00d534371353c3ae5c06c74a08aa10cb60047b
---
M .jshintrc
M EventLogging.php
A modules/ext.eventLogging.Schema.js
3 files changed, 144 insertions(+), 1 deletion(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/EventLogging 
refs/changes/57/250057/1

diff --git a/.jshintrc b/.jshintrc
index d3ba265..3b2b4b9 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -20,6 +20,7 @@
                "mediaWiki",
                "jQuery",
                "QUnit",
-               "JSON"
+               "JSON",
+               "OO"
        ]
 }
diff --git a/EventLogging.php b/EventLogging.php
index 57d19a4..bcd340b 100644
--- a/EventLogging.php
+++ b/EventLogging.php
@@ -210,6 +210,14 @@
                'position'      => 'top',
 );
 
+$wgResourceModules[ 'ext.eventLogging.Schema' ] = array(
+       'scripts'       => 'modules/ext.eventLogging.Schema.js',
+       'localBasePath' => __DIR__,
+       'remoteExtPath' => 'EventLogging',
+       'dependencies'  => array( 'mediawiki.storage', 'ext.eventLogging', 
'ext.eventLogging.subscriber' ),
+       'targets'       => array( 'desktop', 'mobile' ),
+);
+
 // Hooks
 
 $wgExtensionFunctions[] = 'EventLoggingHooks::onSetup';
diff --git a/modules/ext.eventLogging.Schema.js 
b/modules/ext.eventLogging.Schema.js
new file mode 100644
index 0000000..38199a6
--- /dev/null
+++ b/modules/ext.eventLogging.Schema.js
@@ -0,0 +1,134 @@
+( function ( mw, $ ) {
+       'use strict';
+
+       var BEACON_SETTING_KEY = 'ext.eventLogging.beacon',
+               beacon,
+               Schema;
+
+       /**
+        * @class Schema
+        */
+       Schema = function () {
+               /**
+                * Name of Schema to log to
+                * Must be overwritten by the extending class
+                * @property {String|null}
+                */
+               this.name = null;
+
+               /**
+                * A set of defaults to log to the schema
+                *
+                * @cfg {Object} defaults Default options hash.
+                */
+               this.defaults = {};
+
+               /**
+                * Whether or not the logging is sampled (i.e. not recorded at 
100% frequency)
+                * @property {Boolean}
+                */
+               this.isSampled = false;
+
+               /**
+                * The rate at which sampling is performed
+                * @property {Number}
+                */
+               this.samplingRate = 1 / 2;
+
+               /**
+                * Whether the user is in the sampling bucket. Used as a cache 
variable.
+                * @property {Boolean|null}
+                * @private
+                */
+               this._isInBucket = null;
+       };
+       OO.initClass( Schema );
+
+       /**
+        * Whether the user is bucketed.
+        * @returns {Boolean}
+        * @private
+        */
+       Schema.prototype._isUserInBucket = function () {
+               if ( this._isInBucket === null ) {
+                       this._isInBucket = this.isSampled && Math.random() <= 
this.samplingRate;
+               }
+               return this._isInBucket;
+       };
+
+       /**
+        * Log event via the EventLogging subscriber.
+        *
+        * @method
+        * @param {Object} data to log
+        * @return {jQuery.Deferred}
+        */
+       Schema.prototype.log = function ( data ) {
+               var deferred = $.Deferred();
+
+               // Log event if logging schema is not sampled or if user is in 
the bucket
+               if ( !this.isSampled || this._isUserInBucket() ) {
+                       mw.track( 'event.' + this.name, $.extend( {}, 
this.defaults, data ) );
+
+                       return deferred.resolve();
+               }
+
+               return deferred.reject();
+       };
+
+       /**
+        * Try to log an event after the next page load if the sendBeacon 
method is not supported.
+        * Otherwise log now.
+        *
+        * @method
+        * @param {Object} data to log
+        */
+       Schema.prototype.logBeacon = function ( data ) {
+               if ( mw.eventLog.sendBeacon !== $.noop ) {
+                       this.log( data );
+               } else if ( !this.isSampled || this._isUserInBucket() ) {
+                       saveBeacon( {
+                               schema: this.name,
+                               data: $.extend( {}, this.defaults, data )
+                       } );
+               }
+       };
+
+       mw.eventLog.Schema = Schema;
+
+       /**
+        * Loads the beacon from local storage.
+        * @ignore
+        *
+        * @returns {Array}
+        */
+       function loadBeacon() {
+               return JSON.parse( mw.storage.get( BEACON_SETTING_KEY ) );
+       }
+
+       /**
+        * Saves the beacon to local storage.
+        * @ignore
+        *
+        * @param {Object} beacon
+        */
+       function saveBeacon( beacon ) {
+               mw.storage.set( BEACON_SETTING_KEY, JSON.stringify( beacon ) );
+       }
+
+       /**
+        * Deletes the beacon, if there is one, from local storage.
+        * @ignore
+        */
+       function deleteBeacon() {
+               mw.storage.remove( BEACON_SETTING_KEY );
+       }
+
+       beacon = loadBeacon();
+       // If a beacon was saved previously, then it is logged.
+       if ( beacon && typeof beacon === 'object' ) {
+               mw.track( 'event.' + beacon.schema, beacon.data );
+               deleteBeacon();
+       }
+
+}( mediaWiki, jQuery ) );

-- 
To view, visit https://gerrit.wikimedia.org/r/250057
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iea00d534371353c3ae5c06c74a08aa10cb60047b
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/EventLogging
Gerrit-Branch: master
Gerrit-Owner: Bmansurov <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to