diff --git a/src/document/DocumentCommandHandlers.js b/src/document/DocumentCommandHandlers.js index 28ea9a9dfb0..832148befb4 100644 --- a/src/document/DocumentCommandHandlers.js +++ b/src/document/DocumentCommandHandlers.js @@ -788,6 +788,7 @@ define(function (require, exports, module) { .done(function () { docToSave.notifySaved(); result.resolve(file); + HealthLogger.fileSaved(docToSave); }) .fail(function (err) { if (err === FileSystemError.CONTENTS_MODIFIED) { @@ -1186,6 +1187,7 @@ define(function (require, exports, module) { function doClose(file) { if (!promptOnly) { MainViewManager._close(paneId, file); + HealthLogger.fileClosed(file); } } diff --git a/src/editor/EditorStatusBar.js b/src/editor/EditorStatusBar.js index c3a53857fae..7d27e926424 100644 --- a/src/editor/EditorStatusBar.js +++ b/src/editor/EditorStatusBar.js @@ -465,6 +465,18 @@ define(function (require, exports, module) { var document = EditorManager.getActiveEditor().document, fullPath = document.file.fullPath; + var fileType = (document.file instanceof InMemoryFile) ? "newFile" : "existingFile", + filelanguageName = lang ? lang._name : ""; + + HealthLogger.sendAnalyticsData( + HealthLogger.commonStrings.USAGE + HealthLogger.commonStrings.LANGUAGE_CHANGE + + filelanguageName + fileType, + HealthLogger.commonStrings.USAGE, + HealthLogger.commonStrings.LANGUAGE_CHANGE, + filelanguageName.toLowerCase(), + fileType + ); + if (lang === LANGUAGE_SET_AS_DEFAULT) { // Set file's current language in preferences as a file extension override (only enabled if not default already) var fileExtensionMap = PreferencesManager.get("language.fileExtensions"); diff --git a/src/languageTools/LanguageClientWrapper.js b/src/languageTools/LanguageClientWrapper.js index abd0c9b41f5..9cd7a5a42b1 100644 --- a/src/languageTools/LanguageClientWrapper.js +++ b/src/languageTools/LanguageClientWrapper.js @@ -358,7 +358,15 @@ define(function (require, exports, module) { */ //completion LanguageClientWrapper.prototype.requestHints = function (params) { - return this._request(ToolingInfo.FEATURES.CODE_HINTS, params); + return this._request(ToolingInfo.FEATURES.CODE_HINTS, params) + .then(function(response) { + if(response && response.items && response.items.length) { + logAnalyticsData("CODE_HINTS"); + } + return $.Deferred().resolve(response); + }, function(err) { + return $.Deferred().reject(err); + }); }; //completionItemResolve @@ -368,12 +376,28 @@ define(function (require, exports, module) { //signatureHelp LanguageClientWrapper.prototype.requestParameterHints = function (params) { - return this._request(ToolingInfo.FEATURES.PARAMETER_HINTS, params); + return this._request(ToolingInfo.FEATURES.PARAMETER_HINTS, params) + .then(function(response) { + if (response && response.signatures && response.signatures.length) { + logAnalyticsData("PARAM_HINTS"); + } + return $.Deferred().resolve(response); + }, function(err) { + return $.Deferred().reject(err); + }); }; //gotoDefinition LanguageClientWrapper.prototype.gotoDefinition = function (params) { - return this._request(ToolingInfo.FEATURES.JUMP_TO_DEFINITION, params); + return this._request(ToolingInfo.FEATURES.JUMP_TO_DEFINITION, params) + .then(function(response) { + if(response && response.range) { + logAnalyticsData("JUMP_TO_DEF"); + } + return $.Deferred().resolve(response); + }, function(err) { + return $.Deferred().reject(err); + }); }; //gotoDeclaration @@ -621,6 +645,23 @@ define(function (require, exports, module) { exports.LanguageClientWrapper = LanguageClientWrapper; + function logAnalyticsData(typeStrKey) { + var editor = require("editor/EditorManager").getActiveEditor(), + document = editor ? editor.document : null, + language = document ? document.language : null, + languageName = language ? language._name : "", + HealthLogger = require("utils/HealthLogger"), + typeStr = HealthLogger.commonStrings[typeStrKey] || ""; + + HealthLogger.sendAnalyticsData( + HealthLogger.commonStrings.USAGE + HealthLogger.commonStrings.LANGUAGE_SERVER_PROTOCOL + typeStr + languageName, + HealthLogger.commonStrings.USAGE, + HealthLogger.commonStrings.LANGUAGE_SERVER_PROTOCOL, + typeStr, + languageName.toLowerCase() + ); + } + //For unit testting exports.validateRequestParams = validateRequestParams; exports.validateNotificationParams = validateNotificationParams; diff --git a/src/utils/HealthLogger.js b/src/utils/HealthLogger.js index 6125314d616..3fd5e3d7e74 100644 --- a/src/utils/HealthLogger.js +++ b/src/utils/HealthLogger.js @@ -38,6 +38,17 @@ define(function (require, exports, module) { HEALTH_DATA_STATE_KEY = "HealthData.Logs", logHealthData = true; + var commonStrings = { USAGE: "usage", + FILE_OPEN: "fileOpen", + FILE_SAVE: "fileSave", + FILE_CLOSE: "fileClose", + LANGUAGE_CHANGE: "languageChange", + LANGUAGE_SERVER_PROTOCOL: "languageServerProtocol", + CODE_HINTS: "codeHints", + PARAM_HINTS: "parameterHints", + JUMP_TO_DEF: "jumpToDefinition" + }; + EventDispatcher.makeEventDispatcher(exports); /** @@ -165,6 +176,92 @@ define(function (require, exports, module) { fileEncCountMap[encoding]++; setHealthData(healthData); } + + + sendAnalyticsData(commonStrings.USAGE + commonStrings.FILE_OPEN + language._name, + commonStrings.USAGE, + commonStrings.FILE_OPEN, + language._name.toLowerCase() + ); + + } + + /** + * Whenever a file is saved call this function. + * The function will send the analytics Data + * We only log the standard filetypes and fileSize + * @param {String} filePath The path of the file to be registered + */ + function fileSaved(docToSave) { + if (!docToSave) { + return; + } + var fileType = docToSave.language ? docToSave.language._name : ""; + sendAnalyticsData(commonStrings.USAGE + commonStrings.FILE_SAVE + fileType, + commonStrings.USAGE, + commonStrings.FILE_SAVE, + fileType.toLowerCase() + ); + } + + /** + * Whenever a file is closed call this function. + * The function will send the analytics Data. + * We only log the standard filetypes and fileSize + * @param {String} filePath The path of the file to be registered + */ + function fileClosed(file) { + if (!file) { + return; + } + var language = LanguageManager.getLanguageForPath(file._path), + size = -1; + + function _sendData(fileSize) { + var subType = ""; + + if(fileSize/1024 <= 1) { + + if(fileSize < 0) { + subType = ""; + } + if(fileSize <= 10) { + subType = "Size_0_10KB"; + } else if (fileSize <= 50) { + subType = "Size_10_50KB"; + } else if (fileSize <= 100) { + subType = "Size_50_100KB"; + } else if (fileSize <= 500) { + subType = "Size_100_500KB"; + } else { + subType = "Size_500KB_1MB"; + } + + } else { + fileSize = fileSize/1024; + if(fileSize <= 2) { + subType = "Size_1_2MB"; + } else if(fileSize <= 5) { + subType = "Size_2_5MB"; + } else { + subType = "Size_Above_5MB"; + } + } + + sendAnalyticsData(commonStrings.USAGE + commonStrings.FILE_CLOSE + language._name + subType, + commonStrings.USAGE, + commonStrings.FILE_CLOSE, + language._name.toLowerCase(), + subType + ); + } + + file.stat(function(err, fileStat) { + if(!err) { + size = fileStat.size.valueOf()/1024; + } + _sendData(size); + }); } /** @@ -243,11 +340,14 @@ define(function (require, exports, module) { exports.getAggregatedHealthData = getAggregatedHealthData; exports.clearHealthData = clearHealthData; exports.fileOpened = fileOpened; + exports.fileSaved = fileSaved; + exports.fileClosed = fileClosed; exports.setProjectDetail = setProjectDetail; exports.searchDone = searchDone; exports.setHealthLogsEnabled = setHealthLogsEnabled; exports.shouldLogHealthData = shouldLogHealthData; exports.init = init; + exports.sendAnalyticsData = sendAnalyticsData; // constants // searchType for searchDone() @@ -262,5 +362,5 @@ define(function (require, exports, module) { exports.SEARCH_CASE_SENSITIVE = "searchCaseSensitive"; // A new search context on search bar up-Gives an idea of number of times user did a discrete search exports.SEARCH_NEW = "searchNew"; - exports.sendAnalyticsData = sendAnalyticsData; + exports.commonStrings = commonStrings; });