mediawiki-extensions-Visual.../modules/ve-mw/init/ve.init.mw.trackSubscriber.js
Roan Kattouw a032ea039e Move from legacy TimingData schema to new statsd API
This API doesn't have the ability to track any other data
in addition to a name and a duration in milliseconds, so
we add the target name ('mwTarget' or 'mobile') to the
event name and discard all other data.

Change-Id: I25ae0243f8983142d7755b65b05c18d5df36a253
2014-12-10 00:25:42 +00:00

113 lines
3.5 KiB
JavaScript

/*!
* VisualEditor MediaWiki event subscriber.
*
* Subscribes to ve.track() events and routes them to mw.track().
*
* @copyright 2011-2014 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
( function () {
var lastEventWithAction = {},
editingSessionId = mw.user.generateRandomSessionId();
function getDefaultTiming( action, data, now ) {
switch ( action ) {
case 'init':
// Account for second opening
return now - Math.max(
Math.floor( window.mediaWikiLoadStart ),
lastEventWithAction.saveSuccess || 0,
lastEventWithAction.abort || 0
);
case 'ready':
return now - lastEventWithAction.init;
case 'saveIntent':
return now - lastEventWithAction.ready;
case 'saveAttempt':
return now - lastEventWithAction.saveIntent;
case 'saveSuccess':
case 'saveFailure':
// HERE BE DRAGONS: the caller must compute these themselves
// for sensible results. Deliberately sabotage any attempts to
// use the default by returning -1
mw.log.warn( 've.init.mw.trackSubscriber: Do not rely on default timing value for saveSuccess/saveFailure' );
return -1;
case 'abort':
switch ( data.type ) {
case 'preinit':
return now - lastEventWithAction.init;
case 'nochange':
case 'switchwith':
case 'switchwithout':
case 'abandon':
return now - lastEventWithAction.ready;
case 'abandonMidsave':
return now - lastEventWithAction.saveAttempt;
}
}
mw.log.warn( 've.init.mw.trackSubscriber: Unrecognized action', action );
return -1;
}
ve.trackSubscribeAll( function ( topic, data ) {
data = data || {};
var newData, action,
now = Math.floor( ve.now() ),
prefix = topic.slice( 0, topic.indexOf( '.' ) );
if ( prefix === 'mwtiming' ) {
// Add type for save errors; not in the topic for stupid historical reasons
if ( topic === 'mwtiming.performance.user.saveError' ) {
topic += '.' + data.type;
}
// Map mwtiming.foo --> timing.ve.foo.mobile
topic = 'timing.ve.' + topic.slice( 'mwtiming.'.length ) + '.' + data.targetName;
data = data.duration;
} else if ( prefix === 'mwedit' ) {
// Edit schema
action = topic.split( '.' )[1];
if ( action === 'init' ) {
// Regenerate editingSessionId
editingSessionId = mw.user.generateRandomSessionId();
}
newData = $.extend( {
version: 1,
action: action,
editor: 'visualeditor',
platform: 'desktop', // FIXME
integration: ve.init.target && ve.init.target.constructor.static.integrationType || 'page',
'page.id': mw.config.get( 'wgArticleId' ),
'page.title': mw.config.get( 'wgPageName' ),
'page.ns': mw.config.get( 'wgNamespaceNumber' ),
'page.revid': mw.config.get( 'wgRevisionId' ),
'page.length': -1, // FIXME
editingSessionId: editingSessionId,
'user.id': mw.user.getId(),
'user.editCount': mw.config.get( 'wgUserEditCount', 0 )
}, data );
if ( mw.user.isAnon() ) {
newData['user.class'] = 'IP';
}
newData['action.' + action + '.type'] = data.type;
newData['action.' + action + '.mechanism'] = data.mechanism;
newData['action.' + action + '.timing'] = data.timing !== undefined ?
Math.floor( data.timing ) : getDefaultTiming( action, data, now );
// Remove renamed properties
delete newData.type;
delete newData.mechanism;
delete newData.timing;
data = newData;
topic = 'event.Edit';
lastEventWithAction[action] = now;
}
mw.track( topic, data );
} );
} )();