diff --git a/lib/gui/app/app.js b/lib/gui/app/app.js index 19bde91b..015e50f2 100644 --- a/lib/gui/app/app.js +++ b/lib/gui/app/app.js @@ -29,6 +29,7 @@ var angular = require('angular') const electron = require('electron') const Bluebird = require('bluebird') const semver = require('semver') +const uuidV4 = require('uuid/v4') const EXIT_CODES = require('../../shared/exit-codes') const messages = require('../../shared/messages') const s3Packages = require('../../shared/s3-packages') @@ -58,6 +59,21 @@ const updateLock = require('./modules/update-lock') process.env.DRIVELIST_DEBUG = /drivelist|^\*$/i.test(process.env.DEBUG) ? '1' : '' window.localStorage.debug = process.env.DEBUG +// Set application session UUID +store.dispatch({ + type: store.Actions.SET_APPLICATION_SESSION_UUID, + data: uuidV4() +}) + +// Set first flashing workflow UUID +store.dispatch({ + type: store.Actions.SET_FLASHING_WORKFLOW_UUID, + data: uuidV4() +}) + +const applicationSessionUuid = store.getState().toJS().applicationSessionUuid +const flashingWorkflowUuid = store.getState().toJS().flashingWorkflowUuid + const app = angular.module('Etcher', [ require('angular-ui-router'), require('angular-ui-bootstrap'), @@ -103,7 +119,8 @@ app.run(() => { analytics.logEvent('Application start', { packageType: packageJSON.packageType, - version: currentVersion + version: currentVersion, + applicationSessionUuid }) const shouldCheckForUpdates = updateNotifier.shouldCheckForUpdates({ @@ -119,7 +136,8 @@ app.run(() => { analytics.logEvent('Not checking for updates', { shouldCheckForUpdates, updatesEnabled, - stable: isStableRelease + stable: isStableRelease, + applicationSessionUuid }) return Bluebird.resolve() @@ -132,7 +150,8 @@ app.run(() => { currentVersion, stable: isStableRelease, updateSemverRange, - includeUnstableChannel + includeUnstableChannel, + applicationSessionUuid }) return s3Packages.getLatestVersion(release.getReleaseType(currentVersion), { @@ -141,7 +160,8 @@ app.run(() => { }).then((latestVersion) => { if (semver.gte(currentVersion, latestVersion || '0.0.0')) { analytics.logEvent('Update notification skipped', { - reason: 'Latest version' + reason: 'Latest version', + applicationSessionUuid }) return Bluebird.resolve() } @@ -153,13 +173,15 @@ app.run(() => { // might be annoying. if (selectionState.hasImage()) { analytics.logEvent('Update notification skipped', { - reason: 'Image selected' + reason: 'Image selected', + applicationSessionUuid }) return Bluebird.resolve() } analytics.logEvent('Notifying update', { - latestVersion + latestVersion, + applicationSessionUuid }) return updateNotifier.notify(latestVersion, { @@ -174,7 +196,8 @@ app.run(() => { }, (error) => { analytics.logEvent('Update check user error', { title: errors.getTitle(error), - description: errors.getDescription(error) + description: errors.getDescription(error), + applicationSessionUuid }) }).catch(exceptionReporter.report) }) @@ -247,7 +270,8 @@ app.run(($window) => { $window.addEventListener('beforeunload', (event) => { if (!flashState.isFlashing() || popupExists) { analytics.logEvent('Close application', { - isFlashing: flashState.isFlashing() + isFlashing: flashState.isFlashing(), + applicationSessionUuid }) return } @@ -258,7 +282,7 @@ app.run(($window) => { // Don't open any more popups popupExists = true - analytics.logEvent('Close attempt while flashing') + analytics.logEvent('Close attempt while flashing', { applicationSessionUuid, flashingWorkflowUuid }) osDialog.showWarning({ confirmationLabel: 'Yes, quit', @@ -268,7 +292,9 @@ app.run(($window) => { }).then((confirmed) => { if (confirmed) { analytics.logEvent('Close confirmed while flashing', { - uuid: flashState.getFlashUuid() + flashInstanceUuid: flashState.getFlashUuid(), + applicationSessionUuid, + flashingWorkflowUuid }) // This circumvents the 'beforeunload' event unlike @@ -276,7 +302,7 @@ app.run(($window) => { electron.remote.process.exit(EXIT_CODES.SUCCESS) } - analytics.logEvent('Close rejected while flashing') + analytics.logEvent('Close rejected while flashing', { applicationSessionUuid, flashingWorkflowUuid }) popupExists = false }).catch(exceptionReporter.report) }) @@ -308,7 +334,8 @@ app.run(($rootScope) => { analytics.logEvent('Navigate', { to: toState.name, - from: fromState.name + from: fromState.name, + applicationSessionUuid }) }) }) diff --git a/lib/gui/app/components/drive-selector/controllers/drive-selector.js b/lib/gui/app/components/drive-selector/controllers/drive-selector.js index c008cf9c..35bc3c19 100644 --- a/lib/gui/app/components/drive-selector/controllers/drive-selector.js +++ b/lib/gui/app/components/drive-selector/controllers/drive-selector.js @@ -20,6 +20,7 @@ const angular = require('angular') const _ = require('lodash') const Bluebird = require('bluebird') const constraints = require('../../../../../shared/drive-constraints') +const store = require('../../../models/store') const analytics = require('../../../modules/analytics') const availableDrives = require('../../../models/available-drives') const selectionState = require('../../../models/selection-state') @@ -96,7 +97,9 @@ module.exports = function ( if (canChangeDriveSelectionState) { analytics.logEvent('Toggle drive', { drive, - previouslySelected: selectionState.isCurrentDrive(drive.device) + previouslySelected: selectionState.isCurrentDrive(drive.device), + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid }) selectionState.toggleDrive(drive.device) @@ -125,7 +128,9 @@ module.exports = function ( this.installMissingDrivers = (drive) => { if (drive.link) { analytics.logEvent('Open driver link modal', { - url: drive.link + url: drive.link, + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid }) return ConfirmModalService.show({ @@ -187,7 +192,10 @@ module.exports = function ( if (canChangeDriveSelectionState) { selectionState.selectDrive(drive.device) - analytics.logEvent('Drive selected (double click)') + analytics.logEvent('Drive selected (double click)', { + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + }) this.closeModal() } diff --git a/lib/gui/app/components/file-selector/file-selector/file-selector.jsx b/lib/gui/app/components/file-selector/file-selector/file-selector.jsx index 59fd3386..af694472 100644 --- a/lib/gui/app/components/file-selector/file-selector/file-selector.jsx +++ b/lib/gui/app/components/file-selector/file-selector/file-selector.jsx @@ -177,7 +177,11 @@ class FileSelector extends React.PureComponent { }) osDialog.showError(invalidImageError) - analytics.logEvent('Invalid image', image) + analytics.logEvent('Invalid image', { + image, + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + }) return } @@ -185,10 +189,18 @@ class FileSelector extends React.PureComponent { let message = null if (supportedFormats.looksLikeWindowsImage(image.path)) { - analytics.logEvent('Possibly Windows image', image) + analytics.logEvent('Possibly Windows image', { + image, + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + }) message = messages.warning.looksLikeWindowsImage() } else if (!image.hasMBR) { - analytics.logEvent('Missing partition table', image) + analytics.logEvent('Missing partition table', { + image, + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + }) message = messages.warning.missingPartitionTable() } @@ -218,7 +230,11 @@ class FileSelector extends React.PureComponent { image.logo = Boolean(image.logo) image.bmap = Boolean(image.bmap) - analytics.logEvent('Select image', image) + analytics.logEvent('Select image', { + image, + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + }) }).catch(exceptionReporter.report) } diff --git a/lib/gui/app/components/flash-error-modal/services/flash-error-modal.js b/lib/gui/app/components/flash-error-modal/services/flash-error-modal.js index 42494138..5110ddff 100644 --- a/lib/gui/app/components/flash-error-modal/services/flash-error-modal.js +++ b/lib/gui/app/components/flash-error-modal/services/flash-error-modal.js @@ -18,6 +18,7 @@ const flashState = require('../../../models/flash-state') const selectionState = require('../../../models/selection-state') +const store = require('../../../models/store') const analytics = require('../../../modules/analytics') module.exports = function (WarningModalService) { @@ -40,7 +41,10 @@ module.exports = function (WarningModalService) { flashState.resetState() if (confirmed) { - analytics.logEvent('Restart after failure') + analytics.logEvent('Restart after failure', { + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + }) } else { selectionState.clear() } diff --git a/lib/gui/app/components/modal/services/modal.js b/lib/gui/app/components/modal/services/modal.js index e84dc2ee..52abea1d 100644 --- a/lib/gui/app/components/modal/services/modal.js +++ b/lib/gui/app/components/modal/services/modal.js @@ -17,6 +17,7 @@ 'use strict' const _ = require('lodash') +const store = require('../../../models/store') const analytics = require('../../../modules/analytics') module.exports = function ($uibModal, $q) { @@ -45,7 +46,9 @@ module.exports = function ($uibModal, $q) { }) analytics.logEvent('Open modal', { - name: options.name + name: options.name, + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid }) const modal = $uibModal.open({ @@ -62,7 +65,9 @@ module.exports = function ($uibModal, $q) { modal.result.then((value) => { analytics.logEvent('Modal accepted', { name: options.name, - value + value, + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid }) resolve(value) @@ -71,7 +76,9 @@ module.exports = function ($uibModal, $q) { if (error === 'escape key press' || error === 'backdrop click') { analytics.logEvent('Modal rejected', { name: options.name, - method: error + method: error, + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid }) return resolve() @@ -79,7 +86,9 @@ module.exports = function ($uibModal, $q) { analytics.logEvent('Modal rejected', { name: options.name, - value: error + value: error, + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid }) return reject(error) diff --git a/lib/gui/app/components/safe-webview.js b/lib/gui/app/components/safe-webview.js index 4d0c2a02..d938df2d 100644 --- a/lib/gui/app/components/safe-webview.js +++ b/lib/gui/app/components/safe-webview.js @@ -25,6 +25,7 @@ const react = require('react') const propTypes = require('prop-types') const { react2angular } = require('react2angular') const analytics = require('../modules/analytics') +const store = require('../models/store') const settings = require('../models/settings') const packageJSON = require('../../../../package.json') @@ -198,7 +199,10 @@ class SafeWebview extends react.PureComponent { if (event.resourceType === 'mainFrame') { const HTTP_OK = 200 - analytics.logEvent(event) + analytics.logEvent(event, { + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + }) this.setState({ shouldShow: event.httpResponseCode === HTTP_OK @@ -248,7 +252,10 @@ class SafeWebview extends react.PureComponent { if (message.command === 'error') { analytics.logException(message.data) } else { - analytics.logEvent(message.data || message) + analytics.logEvent(message.data || message, { + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + }) } } } diff --git a/lib/gui/app/components/update-notifier.js b/lib/gui/app/components/update-notifier.js index f886361a..3a2d00c1 100644 --- a/lib/gui/app/components/update-notifier.js +++ b/lib/gui/app/components/update-notifier.js @@ -19,6 +19,7 @@ const electron = require('electron') const Bluebird = require('bluebird') const _ = require('lodash') +const store = require('../models/store') const settings = require('../models/settings') const analytics = require('../modules/analytics') const units = require('../../../shared/units') @@ -145,7 +146,9 @@ exports.notify = (version, options = {}) => { sleepUpdateCheck: results.sleepUpdateCheck, notifyVersion: version, currentVersion: packageJSON.version, - agreed: results.agreed + agreed: results.agreed, + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid }) if (results.agreed) { diff --git a/lib/gui/app/models/store.js b/lib/gui/app/models/store.js index 7c79a955..147cd486 100644 --- a/lib/gui/app/models/store.js +++ b/lib/gui/app/models/store.js @@ -80,6 +80,8 @@ const selectImageNoNilFields = [ * @private */ const DEFAULT_STATE = Immutable.fromJS({ + applicationSessionUuid: '', + flashingWorkflowUuid: '', availableDrives: [], selection: { devices: new Immutable.OrderedSet() @@ -111,7 +113,9 @@ const ACTIONS = _.fromPairs(_.map([ 'SELECT_DRIVE', 'SELECT_IMAGE', 'DESELECT_DRIVE', - 'DESELECT_IMAGE' + 'DESELECT_IMAGE', + 'SET_APPLICATION_SESSION_UUID', + 'SET_FLASHING_WORKFLOW_UUID' ], (message) => { return [ message, message ] })) @@ -499,6 +503,14 @@ const storeReducer = (state = DEFAULT_STATE, action) => { return state.deleteIn([ 'selection', 'image' ]) } + case ACTIONS.SET_APPLICATION_SESSION_UUID: { + return state.set('applicationSessionUuid', action.data) + } + + case ACTIONS.SET_FLASHING_WORKFLOW_UUID: { + return state.set('flashingWorkflowUuid', action.data) + } + default: { return state } diff --git a/lib/gui/app/modules/image-writer.js b/lib/gui/app/modules/image-writer.js index 22dd826a..e94bc9a6 100644 --- a/lib/gui/app/modules/image-writer.js +++ b/lib/gui/app/modules/image-writer.js @@ -23,6 +23,7 @@ const os = require('os') const ipc = require('node-ipc') const isRunningInAsar = require('electron-is-running-in-asar') const electron = require('electron') +const store = require('../models/store') const settings = require('../models/settings') const flashState = require('../models/flash-state') const errors = require('../../../shared/errors') @@ -74,20 +75,26 @@ const getApplicationEntryPoint = () => { * handleErrorLogging({ code: 'EUNPLUGGED' }, { image: 'resin.img' }) */ const handleErrorLogging = (error, analyticsData) => { + const eventData = _.assign({ + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid, + flashInstanceUuid: flashState.getFlashUuid() + }, analyticsData) + if (error.code === 'EVALIDATION') { - analytics.logEvent('Validation error', analyticsData) + analytics.logEvent('Validation error', eventData) } else if (error.code === 'EUNPLUGGED') { - analytics.logEvent('Drive unplugged', analyticsData) + analytics.logEvent('Drive unplugged', eventData) } else if (error.code === 'EIO') { - analytics.logEvent('Input/output error', analyticsData) + analytics.logEvent('Input/output error', eventData) } else if (error.code === 'ENOSPC') { - analytics.logEvent('Out of space', analyticsData) + analytics.logEvent('Out of space', eventData) } else if (error.code === 'ECHILDDIED') { - analytics.logEvent('Child died unexpectedly', analyticsData) + analytics.logEvent('Child died unexpectedly', eventData) } else { analytics.logEvent('Flash error', _.merge({ error: errors.toJSON(error) - }, analyticsData)) + }, eventData)) } } @@ -163,6 +170,7 @@ exports.performWrite = (image, drives, onProgress) => { drives, driveCount: drives.length, uuid: flashState.getFlashUuid(), + flashInstanceUuid: flashState.getFlashUuid(), unmountOnSuccess: settings.get('unmountOnSuccess'), validateWriteOnSuccess: settings.get('validateWriteOnSuccess') } @@ -306,8 +314,12 @@ exports.flash = (image, drives) => { drives, driveCount: drives.length, uuid: flashState.getFlashUuid(), + status: 'started', + flashInstanceUuid: flashState.getFlashUuid(), unmountOnSuccess: settings.get('unmountOnSuccess'), - validateWriteOnSuccess: settings.get('validateWriteOnSuccess') + validateWriteOnSuccess: settings.get('validateWriteOnSuccess'), + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid } analytics.logEvent('Flash', analyticsData) @@ -315,10 +327,17 @@ exports.flash = (image, drives) => { return exports.performWrite(image, drives, (state) => { flashState.setProgressState(state) }).then(flashState.unsetFlashingFlag).then(() => { + const { results } = flashState.getFlashResults() + const event = _.assign({ + errors: results.errors, + devices: results.devices, + status: 'finished' + }, + analyticsData) if (flashState.wasLastFlashCancelled()) { - analytics.logEvent('Elevation cancelled', analyticsData) + analytics.logEvent('Elevation cancelled', event) } else { - analytics.logEvent('Done', analyticsData) + analytics.logEvent('Done', event) } }).catch((error) => { flashState.unsetFlashingFlag({ @@ -327,7 +346,14 @@ exports.flash = (image, drives) => { // eslint-disable-next-line no-magic-numbers if (drives.length > 1) { - analytics.logEvent('Write failed', analyticsData) + const { results } = flashState.getFlashResults() + const event = _.assign({ + errors: results.errors, + devices: results.devices, + status: 'failed' + }, + analyticsData) + analytics.logEvent('Write failed', event) } return Bluebird.reject(error) @@ -346,14 +372,25 @@ exports.flash = (image, drives) => { */ exports.cancel = () => { const drives = selectionState.getSelectedDevices() - analytics.logEvent('Cancel', { + const { results } = flashState.getFlashResults() + const analyticsData = { image: selectionState.getImagePath(), drives, driveCount: drives.length, uuid: flashState.getFlashUuid(), + flashInstanceUuid: flashState.getFlashUuid(), unmountOnSuccess: settings.get('unmountOnSuccess'), - validateWriteOnSuccess: settings.get('validateWriteOnSuccess') - }) + validateWriteOnSuccess: settings.get('validateWriteOnSuccess'), + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + } + const event = _.assign({ + errors: results.errors, + devices: results.devices, + status: 'finished' + }, + analyticsData) + analytics.logEvent('Cancel', event) // Re-enable lock release on inactivity updateLock.resume() diff --git a/lib/gui/app/os/open-external/services/open-external.js b/lib/gui/app/os/open-external/services/open-external.js index 97d21e1c..f2527ee2 100644 --- a/lib/gui/app/os/open-external/services/open-external.js +++ b/lib/gui/app/os/open-external/services/open-external.js @@ -17,6 +17,7 @@ 'use strict' const electron = require('electron') +const store = require('../../../models/store') const analytics = require('../../../modules/analytics') const settings = require('../../../models/settings') @@ -38,7 +39,8 @@ module.exports = function () { } analytics.logEvent('Open external link', { - url + url, + applicationSessionUuid: store.getState().toJS().applicationSessionUuid }) if (url) { diff --git a/lib/gui/app/pages/finish/controllers/finish.js b/lib/gui/app/pages/finish/controllers/finish.js index 6bd52279..d237cec0 100644 --- a/lib/gui/app/pages/finish/controllers/finish.js +++ b/lib/gui/app/pages/finish/controllers/finish.js @@ -17,6 +17,8 @@ 'use strict' const _ = require('lodash') +const uuidV4 = require('uuid/v4') +const store = require('../../../models/store') const settings = require('../../../models/settings') const flashState = require('../../../models/flash-state') const selectionState = require('../../../models/selection-state') @@ -57,10 +59,20 @@ module.exports = function ($state) { selectionState.deselectImage() } selectionState.deselectAllDrives() - analytics.logEvent('Restart', options) + analytics.logEvent('Restart', _.assign({ + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + }, options)) // Re-enable lock release on inactivity updateLock.resume() + + // Reset the flashing workflow uuid + store.dispatch({ + type: 'SET_FLASHING_WORKFLOW_UUID', + data: uuidV4() + }) + $state.go('main') } diff --git a/lib/gui/app/pages/main/controllers/drive-selection.js b/lib/gui/app/pages/main/controllers/drive-selection.js index b099ec89..8abdf0c8 100644 --- a/lib/gui/app/pages/main/controllers/drive-selection.js +++ b/lib/gui/app/pages/main/controllers/drive-selection.js @@ -19,6 +19,7 @@ const _ = require('lodash') const angular = require('angular') const prettyBytes = require('pretty-bytes') +const store = require('../../../models/store') const settings = require('../../../models/settings') const selectionState = require('../../../models/selection-state') const analytics = require('../../../modules/analytics') @@ -109,7 +110,9 @@ module.exports = function (DriveSelectorService) { analytics.logEvent('Select drive', { device: drive.device, - unsafeMode: settings.get('unsafeMode') && !settings.get('disableUnsafeMode') + unsafeMode: settings.get('unsafeMode') && !settings.get('disableUnsafeMode'), + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid }) }).catch(exceptionReporter.report) } @@ -124,7 +127,10 @@ module.exports = function (DriveSelectorService) { */ this.reselectDrive = () => { this.openDriveSelector() - analytics.logEvent('Reselect drive') + analytics.logEvent('Reselect drive', { + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + }) } /** diff --git a/lib/gui/app/pages/main/controllers/image-selection.js b/lib/gui/app/pages/main/controllers/image-selection.js index 9485b46a..38f12901 100644 --- a/lib/gui/app/pages/main/controllers/image-selection.js +++ b/lib/gui/app/pages/main/controllers/image-selection.js @@ -19,6 +19,7 @@ const _ = require('lodash') const Bluebird = require('bluebird') const path = require('path') +const store = require('../../../models/store') const messages = require('../../../../../shared/messages') const errors = require('../../../../../shared/errors') const imageStream = require('../../../../../sdk/image-stream') @@ -76,7 +77,10 @@ module.exports = function ( }) osDialog.showError(invalidImageError) - analytics.logEvent('Invalid image', image) + analytics.logEvent('Invalid image', _.merge({ + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + }, image)) return } @@ -84,10 +88,18 @@ module.exports = function ( let message = null if (supportedFormats.looksLikeWindowsImage(image.path)) { - analytics.logEvent('Possibly Windows image', image) + analytics.logEvent('Possibly Windows image', { + image, + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + }) message = messages.warning.looksLikeWindowsImage() } else if (!image.hasMBR) { - analytics.logEvent('Missing partition table', image) + analytics.logEvent('Missing partition table', { + image, + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + }) message = messages.warning.missingPartitionTable() } @@ -114,7 +126,11 @@ module.exports = function ( image.logo = Boolean(image.logo) image.bmap = Boolean(image.bmap) - return analytics.logEvent('Select image', image) + return analytics.logEvent('Select image', { + image, + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + }) }).catch(exceptionReporter.report) } @@ -155,7 +171,10 @@ module.exports = function ( * ImageSelectionController.openImageSelector(); */ this.openImageSelector = () => { - analytics.logEvent('Open image selector') + analytics.logEvent('Open image selector', { + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + }) if (settings.get('experimentalFilePicker')) { FileSelectorService.open() @@ -164,7 +183,10 @@ module.exports = function ( // Avoid analytics and selection state changes // if no file was resolved from the dialog. if (!imagePath) { - analytics.logEvent('Image selector closed') + analytics.logEvent('Image selector closed', { + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + }) return } @@ -183,7 +205,9 @@ module.exports = function ( */ this.reselectImage = () => { analytics.logEvent('Reselect image', { - previousImage: selectionState.getImage() + previousImage: selectionState.getImage(), + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid }) this.openImageSelector() diff --git a/lib/gui/app/pages/main/controllers/main.js b/lib/gui/app/pages/main/controllers/main.js index ba60fb46..c1b1abfb 100644 --- a/lib/gui/app/pages/main/controllers/main.js +++ b/lib/gui/app/pages/main/controllers/main.js @@ -16,6 +16,7 @@ 'use strict' +const store = require('../../../models/store') const settings = require('../../../models/settings') const flashState = require('../../../models/flash-state') const analytics = require('../../../modules/analytics') @@ -82,7 +83,9 @@ module.exports = function ( */ this.showSelectedImageDetails = () => { analytics.logEvent('Show selected image tooltip', { - imagePath: selectionState.getImagePath() + imagePath: selectionState.getImagePath(), + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid, + applicationSessionUuid: store.getState().toJS().applicationSessionUuid }) return TooltipModalService.show({ diff --git a/lib/gui/app/pages/settings/controllers/settings.js b/lib/gui/app/pages/settings/controllers/settings.js index 96d6333d..21f4cf1b 100644 --- a/lib/gui/app/pages/settings/controllers/settings.js +++ b/lib/gui/app/pages/settings/controllers/settings.js @@ -18,6 +18,7 @@ const os = require('os') const _ = require('lodash') +const store = require('../../../models/store') const settings = require('../../../models/settings') const analytics = require('../../../modules/analytics') const exceptionReporter = require('../../../modules/exception-reporter') @@ -87,7 +88,8 @@ module.exports = function (WarningModalService) { analytics.logEvent('Toggle setting', { setting, value, - dangerous + dangerous, + applicationSessionUuid: store.getState().toJS().applicationSessionUuid }) if (!value || !dangerous) {