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 1 commit
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
11 changes: 11 additions & 0 deletions src/editor/EditorStatusBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,17 @@ 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(
"usagelanguageChange" + filelanguageName + fileType,
"usage",
Copy link
Contributor

Choose a reason for hiding this comment

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

@niteskum can all analytics strings be moved to another file as variables and use that variable everywhere needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

moved all common strings constant to HealthLogger.js as earlier all constants were defined in this file

"languageChange",
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
46 changes: 43 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("codeHints");
}
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("parameterHints");
}
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("jumpToDefinition");
}
return $.Deferred().resolve(response);
}, function(err) {
return $.Deferred().reject(err);
});
};

//gotoDeclaration
Expand Down Expand Up @@ -621,6 +645,22 @@ define(function (require, exports, module) {

exports.LanguageClientWrapper = LanguageClientWrapper;

function logAnalyticsData(typeStr) {
var editor = require("editor/EditorManager").getActiveEditor(),
document = editor ? editor.document : null,
language = document ? document.language : null,
languageName = language ? language._name : "",
HealthLogger = require("utils/HealthLogger");

HealthLogger.sendAnalyticsData(
"usagelanguageServerProtocol" + typeStr + languageName,
"usage",
"languageServerProtocol",
typeStr,
languageName.toLowerCase()
);
}

//For unit testting
exports.validateRequestParams = validateRequestParams;
exports.validateNotificationParams = validateNotificationParams;
Expand Down
89 changes: 89 additions & 0 deletions src/utils/HealthLogger.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ define(function (require, exports, module) {
var PreferencesManager = require("preferences/PreferencesManager"),
LanguageManager = require("language/LanguageManager"),
FileUtils = require("file/FileUtils"),
FileSystem = require("filesystem/FileSystem"),
PerfUtils = require("utils/PerfUtils"),
FindUtils = require("search/FindUtils"),
StringUtils = require("utils/StringUtils"),
Expand Down Expand Up @@ -165,6 +166,92 @@ define(function (require, exports, module) {
fileEncCountMap[encoding]++;
setHealthData(healthData);
}


sendAnalyticsData("usagefileOpen" + language._name,
"usage",
"fileOpen",
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("usagefileSave" + fileType,
"usage",
"fileSave",
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 === -1) {
subType = "";
}
if(fileSize < 10) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

shouldn't the check be <=? if the file size is 10kb, it will log in 10_50KB range.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed

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("usagefileClose" + language._name + subType,
"usage",
"fileClose",
language._name.toLowerCase(),
subType
);
}

file.stat(function(err, fileStat) {
if(!err) {
size = fileStat.size.valueOf()/1024;
}
_sendData(size);
});
}

/**
Expand Down Expand Up @@ -243,6 +330,8 @@ 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;
Expand Down