1313const Services = require ( "Services" ) ;
1414const TOOLS_OPENED_PREF = "devtools.telemetry.tools.opened.version" ;
1515
16- // Object to be shared among all instances.
17- const PENDING_EVENTS = new Map ( ) ;
18- const PENDING_EVENT_PROPERTIES = new Map ( ) ;
19-
2016class Telemetry {
2117 constructor ( ) {
2218 // Bind pretty much all functions so that callers do not need to.
@@ -26,10 +22,6 @@ class Telemetry {
2622 this . logScalar = this . logScalar . bind ( this ) ;
2723 this . logKeyedScalar = this . logKeyedScalar . bind ( this ) ;
2824 this . logOncePerBrowserVersion = this . logOncePerBrowserVersion . bind ( this ) ;
29- this . recordEvent = this . recordEvent . bind ( this ) ;
30- this . setEventRecordingEnabled = this . setEventRecordingEnabled . bind ( this ) ;
31- this . preparePendingEvent = this . preparePendingEvent . bind ( this ) ;
32- this . addEventProperty = this . addEventProperty . bind ( this ) ;
3325 this . destroy = this . destroy . bind ( this ) ;
3426
3527 this . _timers = new Map ( ) ;
@@ -298,10 +290,10 @@ class Telemetry {
298290 }
299291
300292 try {
301- if ( isNaN ( value ) && typeof value !== "boolean" ) {
302- dump ( `Warning: An attempt was made to write a non-numeric and ` +
303- `non-boolean value ${ value } to the ${ scalarId } scalar. Only ` +
304- `numeric and boolean values are allowed.` ) ;
293+ if ( isNaN ( value ) ) {
294+ dump ( `Warning: An attempt was made to write a non-numeric value ` +
295+ `${ value } to the ${ scalarId } scalar. Only numeric values are ` +
296+ `allowed.` ) ;
305297
306298 return ;
307299 }
@@ -392,188 +384,6 @@ class Telemetry {
392384 }
393385 }
394386
395- /**
396- * Event telemetry is disabled by default. Use this method to enable it for
397- * a particular category.
398- *
399- * @param {String } category
400- * The telemetry event category e.g. "devtools.main"
401- * @param {Boolean } enabled
402- * Enabled: true or false.
403- */
404- setEventRecordingEnabled ( category , enabled ) {
405- return Services . telemetry . setEventRecordingEnabled ( category , enabled ) ;
406- }
407-
408- /**
409- * Telemetry events often need to make use of a number of properties from
410- * completely different codepaths. To make this possible we create a
411- * "pending event" along with an array of property names that we need to wait
412- * for before sending the event.
413- *
414- * As each property is received via addEventProperty() we check if all
415- * properties have been received. Once they have all been received we send the
416- * telemetry event.
417- *
418- * @param {String } category
419- * The telemetry event category (a group name for events and helps to
420- * avoid name conflicts) e.g. "devtools.main"
421- * @param {String } method
422- * The telemetry event method (describes the type of event that
423- * occurred e.g. "open")
424- * @param {String } object
425- * The telemetry event object name (the name of the object the event
426- * occurred on) e.g. "tools" or "setting"
427- * @param {String|null } value
428- * The telemetry event value (a user defined value, providing context
429- * for the event) e.g. "console"
430- * @param {Array } expected
431- * An array of the properties needed before sending the telemetry
432- * event e.g.
433- * [
434- * "host",
435- * "width"
436- * ]
437- */
438- preparePendingEvent ( category , method , object , value , expected = [ ] ) {
439- const sig = `${ category } ,${ method } ,${ object } ,${ value } ` ;
440-
441- if ( expected . length === 0 ) {
442- throw new Error ( `preparePendingEvent() was called without any expected ` +
443- `properties.` ) ;
444- }
445-
446- PENDING_EVENTS . set ( sig , {
447- extra : { } ,
448- expected : new Set ( expected )
449- } ) ;
450-
451- const props = PENDING_EVENT_PROPERTIES . get ( sig ) ;
452- if ( props ) {
453- for ( let [ name , val ] of Object . entries ( props ) ) {
454- this . addEventProperty ( category , method , object , value , name , val ) ;
455- }
456- PENDING_EVENT_PROPERTIES . delete ( sig ) ;
457- }
458- }
459-
460- /**
461- * Adds an expected property for either a current or future pending event.
462- * This means that if preparePendingEvent() is called before or after sending
463- * the event properties they will automatically added to the event.
464- *
465- * @param {String } category
466- * The telemetry event category (a group name for events and helps to
467- * avoid name conflicts) e.g. "devtools.main"
468- * @param {String } method
469- * The telemetry event method (describes the type of event that
470- * occurred e.g. "open")
471- * @param {String } object
472- * The telemetry event object name (the name of the object the event
473- * occurred on) e.g. "tools" or "setting"
474- * @param {String|null } value
475- * The telemetry event value (a user defined value, providing context
476- * for the event) e.g. "console"
477- * @param {String } pendingPropName
478- * The pending property name
479- * @param {String } pendingPropValue
480- * The pending property value
481- */
482- addEventProperty ( category , method , object , value , pendingPropName , pendingPropValue ) {
483- const sig = `${ category } ,${ method } ,${ object } ,${ value } ` ;
484-
485- // If the pending event has not been created add the property to the pending
486- // list.
487- if ( ! PENDING_EVENTS . has ( sig ) ) {
488- PENDING_EVENT_PROPERTIES . set ( sig , {
489- [ pendingPropName ] : pendingPropValue
490- } ) ;
491- return ;
492- }
493-
494- const { expected, extra } = PENDING_EVENTS . get ( sig ) ;
495-
496- if ( expected . has ( pendingPropName ) ) {
497- extra [ pendingPropName ] = pendingPropValue ;
498-
499- if ( expected . size === Object . keys ( extra ) . length ) {
500- this . _sendPendingEvent ( category , method , object , value ) ;
501- }
502- } else {
503- // The property was not expected, warn and bail.
504- throw new Error ( `An attempt was made to add the unexpected property ` +
505- `"${ pendingPropName } " to a telemetry event with the ` +
506- `signature "${ sig } "\n` ) ;
507- }
508- }
509-
510- /**
511- * Send a telemetry event.
512- *
513- * @param {String } category
514- * The telemetry event category (a group name for events and helps to
515- * avoid name conflicts) e.g. "devtools.main"
516- * @param {String } method
517- * The telemetry event method (describes the type of event that
518- * occurred e.g. "open")
519- * @param {String } object
520- * The telemetry event object name (the name of the object the event
521- * occurred on) e.g. "tools" or "setting"
522- * @param {String|null } value
523- * The telemetry event value (a user defined value, providing context
524- * for the event) e.g. "console"
525- * @param {Object } extra
526- * The telemetry event extra object containing the properties that will
527- * be sent with the event e.g.
528- * {
529- * host: "bottom",
530- * width: "1024"
531- * }
532- */
533- recordEvent ( category , method , object , value , extra ) {
534- // Only string values are allowed so cast all values to strings.
535- for ( let [ name , val ] of Object . entries ( extra ) ) {
536- extra [ name ] = val + "" ;
537-
538- if ( val . length > 80 ) {
539- const sig = `${ category } ,${ method } ,${ object } ,${ value } ` ;
540-
541- throw new Error ( `The property "${ name } " was added to a telemetry ` +
542- `event with the signature ${ sig } but it's value ` +
543- `"${ val } " is longer than the maximum allowed length ` +
544- `of 80 characters\n` ) ;
545- }
546- }
547- Services . telemetry . recordEvent ( category , method , object , value , extra ) ;
548- }
549-
550- /**
551- * A private method that is not to be used externally. This method is used to
552- * prepare a pending telemetry event for sending and then send it via
553- * recordEvent().
554- *
555- * @param {String } category
556- * The telemetry event category (a group name for events and helps to
557- * avoid name conflicts) e.g. "devtools.main"
558- * @param {String } method
559- * The telemetry event method (describes the type of event that
560- * occurred e.g. "open")
561- * @param {String } object
562- * The telemetry event object name (the name of the object the event
563- * occurred on) e.g. "tools" or "setting"
564- * @param {String|null } value
565- * The telemetry event value (a user defined value, providing context
566- * for the event) e.g. "console"
567- */
568- _sendPendingEvent ( category , method , object , value ) {
569- const sig = `${ category } ,${ method } ,${ object } ,${ value } ` ;
570- const { extra } = PENDING_EVENTS . get ( sig ) ;
571-
572- PENDING_EVENTS . delete ( sig ) ;
573- PENDING_EVENT_PROPERTIES . delete ( sig ) ;
574- this . recordEvent ( category , method , object , value , extra ) ;
575- }
576-
577387 destroy ( ) {
578388 for ( let histogramId of this . _timers . keys ( ) ) {
579389 this . stopTimer ( histogramId ) ;
0 commit comments