Skip to content
Open
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
74 changes: 72 additions & 2 deletions docs/src/content/docs/about/telemetry.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,75 @@
title: Telemetry
---

As of now we do not collect any telemetry data from the extension that would be sent to any external service allowing us to understand how the extension is used. We are considering adding telemetry in the future to help us improve the extension and its features. If we do so, we will ensure that it is done in a way that respects user privacy and complies with relevant regulations.
Currently we only record the number of times the extension is installed and was it installed from the Marketplace website or the embedded VS Code Marketplace. This data is used to understand the popularity of the extension and to help us prioritize features and improvements.
The SPFx Toolkit collects basic usage telemetry to help us understand how the extension is used and improve its features. We follow the VS Code Telemetry extension authors guide and use the recommended `@vscode/extension-telemetry` package to send anonymized telemetry data to Azure Application Insights.

## What We Track

We collect anonymized usage data for the following actions:

### Actions View
- Create New Project
- Add Component to Project
- Upgrade Project
- Validate Project
- Rename Project
- Increase Project Version
- Grant API Permissions
- Deploy Project
- Set Form Customizer
- Scaffold CI/CD Workflow
- View Samples Gallery
- Use @spfx in GitHub Copilot
- Validate Local Setup
- Install Dependencies

### Tasks View
- Build Project
- Bundle Project
- Clean Project
- Deploy to Azure Storage
- Package Project
- Publish Project
- Serve Project
- Test Project
- Trust Dev Cert
- Execute Terminal Command (for NPM scripts with script name tracking)

### App Management (Environment View)
- Add Tenant App Catalog
- Add Site App Catalog
- Remove Site App Catalog
- Deploy App
- Retract App
- Enable App
- Disable App
- Install App
- Uninstall App
- Upgrade App
- Remove App
- Copy App
- Move App
- Remove Tenant Wide Extension
- Enable Tenant Wide Extension
- Disable Tenant Wide Extension
- Update Tenant Wide Extension

### Authentication
- Microsoft 365 login and logout actions

## Privacy and Data Protection

- All telemetry data is anonymized and does not contain personal information
- No code, file paths, or project-specific data is collected
- Data is used solely to understand feature usage and prioritize improvements
- We comply with relevant privacy regulations and Microsoft's privacy policies
- You can disable telemetry through VS Code's standard telemetry settings

## How to Disable Telemetry

To disable telemetry collection, you can use VS Code's built-in telemetry settings:
1. Open VS Code Settings (File > Preferences > Settings)
2. Search for "Telemetry"
3. Set "Telemetry: Telemetry Level" to "off"

This will disable telemetry for all VS Code extensions that respect the standard telemetry settings, including the SharePoint Framework Toolkit.
140 changes: 139 additions & 1 deletion npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
],
"license": "MIT",
"main": "./dist/extension.js",
"aiConnectionString": "InstrumentationKey=137865b8-3555-4866-a2c9-7e35ead3d578;IngestionEndpoint=https://northeurope-2.in.applicationinsights.azure.com/;LiveEndpoint=https://northeurope.livediagnostics.monitor.azure.com/;ApplicationId=d253fe5b-d38c-41f5-841d-afed5bcd9557",
"contributes": {
"chatParticipants": [
{
Expand Down Expand Up @@ -73,7 +74,7 @@
]
}
],
"languageModelTools": [
"languageModelTools": [
{
"name": "install_spo_app",
"tags": [
Expand Down Expand Up @@ -471,7 +472,7 @@
}
}
}
},
},
{
"name": "upgrade_spfx_project",
"tags": [
Expand Down Expand Up @@ -1305,10 +1306,11 @@
"dependencies": {
"@grconrad/vscode-extension-feedback": "^1.0.0",
"@pnp/cli-microsoft365-spfx-toolkit": "1.4.0",
"@vscode/extension-telemetry": "^1.2.0",
"node-forge": "1.3.1",
"react-markdown": "10.1.0",
"rehype-raw": "7.0.0",
"remark-gfm": "4.0.1",
"use-debounce": "10.0.4",
"rehype-raw": "7.0.0"
"use-debounce": "10.0.4"
}
}
27 changes: 26 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ import { ChatTools } from './chat/tools/ChatTools';
import { SpfxAppCLIActions } from './services/actions/SpfxAppCLIActions';
import { IncreaseVersionActions } from './services/actions/IncreaseVersionActions';
import { scheduleFeedbackChecks } from '@grconrad/vscode-extension-feedback';
import { TelemetryService } from './utils/telemetry';


const feedbackFormUrl = 'https://forms.office.com/e/ZTfqAissqt';
let telemetryService: TelemetryService;

export async function activate(context: vscode.ExtensionContext) {
const activationStartTime = Date.now();

const chatParticipant = vscode.chat.createChatParticipant(CHAT_PARTICIPANT_NAME, PromptHandlers.handle);
chatParticipant.iconPath = vscode.Uri.joinPath(context.extensionUri, 'assets', 'images', 'parker-pnp.png');
Expand All @@ -46,6 +49,23 @@ export async function activate(context: vscode.ExtensionContext) {

PnPWebview.register();

telemetryService = TelemetryService.getInstance();
const packageJson = context.extension?.packageJSON;
const connectionString = packageJson?.aiConnectionString;
if (connectionString) {
telemetryService.initialize(context, connectionString);

const activationDuration = Date.now() - activationStartTime;

telemetryService.sendEvent('Extension Activated', {
version: context.extension.packageJSON.version,
nodeVersion: process.version,
platform: process.platform
}, {
activationTimeMs: activationDuration
});
}

const channel = vscode.window.createOutputChannel('SPFx Toolkit Extension');

scheduleFeedbackChecks(
Expand Down Expand Up @@ -130,4 +150,9 @@ export async function activate(context: vscode.ExtensionContext) {
}

// this method is called when your extension is deactivated
export function deactivate() { }
export function deactivate() {
if (telemetryService) {
telemetryService.sendEvent('Extension Deactivated');
telemetryService.dispose();
}
}
4 changes: 2 additions & 2 deletions src/panels/CommandPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ export class CommandPanel {
actionCommands.push(new ActionTreeItem('Scaffold CI/CD Workflow', '', { name: 'rocket', custom: false }, undefined, Commands.pipeline));
actionCommands.push(new ActionTreeItem('Add new component', '', { name: 'add', custom: false }, undefined, Commands.addToProject));
actionCommands.push(new ActionTreeItem('View samples', '', { name: 'library', custom: false }, undefined, Commands.samplesGallery));
actionCommands.push(new ActionTreeItem('Use @spfx in GitHub Copilot ', '', { name: 'copilot', custom: false }, undefined, Commands.openCopilot));
actionCommands.push(new ActionTreeItem('Use @spfx in GitHub Copilot', '', { name: 'copilot', custom: false }, undefined, Commands.openCopilot));
} else {
actionCommands.push(new ActionTreeItem('Create new project', '', { name: 'add', custom: false }, undefined, Commands.createProject));
actionCommands.push(new ActionTreeItem('View samples', '', { name: 'library', custom: false }, undefined, Commands.samplesGallery));
Expand All @@ -319,7 +319,7 @@ export class CommandPanel {

actionCommands.push(new ActionTreeItem('Validate local setup', '', { name: 'verified', custom: false }, undefined, Commands.checkDependencies));
actionCommands.push(new ActionTreeItem('Install dependencies', '', { name: 'cloud-download', custom: false }, undefined, Commands.installDependencies));
actionCommands.push(new ActionTreeItem('Use @spfx in GitHub Copilot ', '', { name: 'copilot', custom: false }, undefined, Commands.openCopilot));
actionCommands.push(new ActionTreeItem('Use @spfx in GitHub Copilot', '', { name: 'copilot', custom: false }, undefined, Commands.openCopilot));
}

window.registerTreeDataProvider('pnp-view-actions', new ActionTreeDataProvider(actionCommands));
Expand Down
5 changes: 3 additions & 2 deletions src/providers/AuthProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { TerminalCommandExecuter } from '../services/executeWrappers/TerminalCom
import { isValidGUID } from '../utils/validateGuid';
import { CliExecuter } from '../services/executeWrappers/CliCommandExecuter';
import { EntraAppRegistration } from '../services/actions/EntraAppRegistration';
import { TelemetryService } from '../utils/telemetry';


export class M365AuthenticationSession implements AuthenticationSession {
Expand Down Expand Up @@ -52,10 +53,10 @@ export class AuthProvider implements AuthenticationProvider, Disposable {
);

subscriptions.push(
commands.registerCommand(Commands.login, AuthProvider.signIn)
commands.registerCommand(Commands.login, TelemetryService.withTelemetry(Commands.login, AuthProvider.signIn))
);
subscriptions.push(
commands.registerCommand(Commands.logout, AuthProvider.logout)
commands.registerCommand(Commands.logout, TelemetryService.withTelemetry(Commands.logout, AuthProvider.logout))
);
}

Expand Down
Loading