Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.

Sending Analytics Data for file Operation and LSP features #14683

Merged
merged 5 commits into from
Apr 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/document/DocumentCommandHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -1186,6 +1187,7 @@ define(function (require, exports, module) {
function doClose(file) {
if (!promptOnly) {
MainViewManager._close(paneId, file);
HealthLogger.fileClosed(file);
}
}

Expand Down
12 changes: 12 additions & 0 deletions src/editor/EditorStatusBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
47 changes: 44 additions & 3 deletions src/languageTools/LanguageClientWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand Down
102 changes: 101 additions & 1 deletion src/utils/HealthLogger.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/**
Expand Down Expand Up @@ -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 : "";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SnchitGrover Do we want an empty string here or something like "unknown"? Empty strings are sometimes treated as null values while serialization depending on platform. Depends on your use case.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@niteskum Is there ever a possibility of not having the language property in a document object?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shubhsnov I think document will always have language. but since file save is critical operation , don't want to leave any space in code to trigger exception so I am doing null check.

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);
});
}

/**
Expand Down Expand Up @@ -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()
Expand All @@ -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;
});