Enabling DacFx telemetry (#1993)

* Enabling DacFx telemetry
This commit is contained in:
Leila Lali
2023-04-11 14:22:05 -07:00
committed by GitHub
parent 9aa84f517c
commit a37093a773
7 changed files with 116 additions and 9 deletions

View File

@@ -3,19 +3,21 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.SqlServer.Dac;
using Microsoft.SqlServer.Dac.Model;
using Microsoft.SqlTools.Hosting.Protocol;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.DacFx.Contracts;
using Microsoft.SqlTools.ServiceLayer.Hosting;
using Microsoft.SqlTools.ServiceLayer.SqlContext;
using Microsoft.SqlTools.ServiceLayer.TaskServices;
using Microsoft.SqlServer.Dac.Model;
using DacTableDesigner = Microsoft.Data.Tools.Sql.DesignServices.TableDesigner.TableDesigner;
using Microsoft.SqlTools.ServiceLayer.Utility;
using Microsoft.SqlTools.Utility;
using DacTableDesigner = Microsoft.Data.Tools.Sql.DesignServices.TableDesigner.TableDesigner;
namespace Microsoft.SqlTools.ServiceLayer.DacFx
{
@@ -27,6 +29,9 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
private static ConnectionService connectionService = null;
private SqlTaskManager sqlTaskManagerInstance = null;
private static readonly Lazy<DacFxService> instance = new Lazy<DacFxService>(() => new DacFxService());
private static Version? serviceVersion = LoadServiceVersion();
private const string TelemetryDefaultApplicationName = "sqltoolsservice";
private string telemetryApplicationName = TelemetryDefaultApplicationName;
private readonly Lazy<ConcurrentDictionary<string, DacFxOperation>> operations =
new Lazy<ConcurrentDictionary<string, DacFxOperation>>(() => new ConcurrentDictionary<string, DacFxOperation>());
/// <summary>
@@ -47,7 +52,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
/// Initializes the service instance
/// </summary>
/// <param name="serviceHost"></param>
public void InitializeService(ServiceHost serviceHost)
public void InitializeService(ServiceHost serviceHost, ServiceLayerCommandOptions commandOptions)
{
serviceHost.SetRequestHandler(ExportRequest.Type, this.HandleExportRequest, true);
serviceHost.SetRequestHandler(ImportRequest.Type, this.HandleImportRequest, true);
@@ -62,6 +67,15 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
serviceHost.SetRequestHandler(GenerateTSqlModelRequest.Type, this.HandleGenerateTSqlModelRequest, true);
serviceHost.SetRequestHandler(GetObjectsFromTSqlModelRequest.Type, this.HandleGetObjectsFromTSqlModelRequest, true);
serviceHost.SetRequestHandler(SavePublishProfileRequest.Type, this.HandleSavePublishProfileRequest, true);
Workspace.WorkspaceService<SqlToolsSettings>.Instance.RegisterConfigChangeCallback(UpdateSettings);
telemetryApplicationName = string.IsNullOrEmpty(commandOptions?.ApplicationName) ? TelemetryDefaultApplicationName : commandOptions.ApplicationName;
}
internal Task UpdateSettings(SqlToolsSettings newSettings, SqlToolsSettings oldSettings, EventContext eventContext)
{
// Update telemetry status in DacFx service
UpdateTelemetryStatus(newSettings.TelemetrySettings.Telemetry != TelemetryLevel.Off);
return Task.CompletedTask;
}
/// <summary>
@@ -341,7 +355,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
profile.Save(parameters.ProfilePath);
}
}, requestContext);
return;
}
@@ -416,5 +430,46 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
{
operation.Execute(taskExecutionMode);
}
/// <summary>
/// Changes telemetry status
/// </summary>
private void UpdateTelemetryStatus(bool telemetryEnabled)
{
try
{
if (telemetryEnabled)
{
DacServices.EnableTelemetry(telemetryApplicationName, serviceVersion);
}
else
{
DacServices.DisableTelemetry();
}
}
catch (Exception ex)
{
Logger.Warning($"Failed to update DacFx telemetry status. telemetry enable: {telemetryEnabled}, error: {ex.Message}");
}
}
private static Version? LoadServiceVersion()
{
try
{
string fileVersion = FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion;
if (Version.TryParse(fileVersion, out Version version))
{
return version;
}
return null;
}
catch (Exception ex)
{
Logger.Warning($"Failed to load assembly version: error: {ex.Message}");
return null;
}
}
}
}

View File

@@ -20,10 +20,11 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
/// </summary>
/// <param name="deploymentOptions"></param>
/// <returns>DacDeployOptions</returns
internal static DacDeployOptions CreateDeploymentOptions(DeploymentOptions deploymentOptions)
internal static DacDeployOptions CreateDeploymentOptions(DeploymentOptions? deploymentOptions = null)
{
try
{
deploymentOptions = deploymentOptions ?? new DeploymentOptions();
PropertyInfo[] deploymentOptionsProperties = deploymentOptions.GetType().GetProperties();
DacDeployOptions dacOptions = new DacDeployOptions();
@@ -38,7 +39,7 @@ namespace Microsoft.SqlTools.ServiceLayer.DacFx
{
List<ObjectType> finalExcludeObjects = new List<ObjectType> { };
var val = deployOptionsProp.GetValue(deploymentOptions);
string[] excludeObjectTypeOptionsArray = (string[])val.GetType().GetProperty("Value").GetValue(val);
string[] excludeObjectTypeOptionsArray = (string[])val?.GetType()?.GetProperty("Value")?.GetValue(val);
if (excludeObjectTypeOptionsArray != null)
{

View File

@@ -133,7 +133,7 @@ namespace Microsoft.SqlTools.ServiceLayer
SecurityService.Instance.InitializeService(serviceHost);
serviceProvider.RegisterSingleService(SecurityService.Instance);
DacFxService.Instance.InitializeService(serviceHost);
DacFxService.Instance.InitializeService(serviceHost, commandOptions);
serviceProvider.RegisterSingleService(DacFxService.Instance);
CmsService.Instance.InitializeService(serviceHost);

View File

@@ -17,6 +17,7 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext
private ISqlToolsSettingsValues sqlTools = null;
private SqlToolsSettingsValues mssqlTools = null;
private SqlToolsSettingsValues allSqlTools = null;
private TelemetrySettingsValues telemetrySettings = null;
public ISqlToolsSettingsValues SqlTools
{
@@ -65,6 +66,23 @@ namespace Microsoft.SqlTools.ServiceLayer.SqlContext
}
}
/// <summary>
/// Gets or sets the underlying settings value object
/// </summary>
[JsonProperty("telemetry")]
public TelemetrySettingsValues TelemetrySettings
{
get
{
this.telemetrySettings ??= new TelemetrySettingsValues();
return this.telemetrySettings;
}
set
{
this.telemetrySettings = value;
}
}
/// <summary>
/// Query execution settings forwarding property
/// </summary>

View File

@@ -0,0 +1,15 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
namespace Microsoft.SqlTools.ServiceLayer.SqlContext
{
public enum TelemetryLevel
{
All,
Error,
Crash,
Off
}
}

View File

@@ -0,0 +1,18 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Newtonsoft.Json;
namespace Microsoft.SqlTools.ServiceLayer.SqlContext
{
public class TelemetrySettingsValues
{
/// <summary>
/// Gets or sets the telemetry level setting
/// </summary>
[JsonProperty("telemetryLevel")]
public TelemetryLevel Telemetry { get; set; }
}
}

View File

@@ -72,7 +72,7 @@ namespace Microsoft.SqlTools.ServiceLayer.TableDesigner
internal Task UpdateSettings(SqlToolsSettings newSettings, SqlToolsSettings oldSettings, EventContext eventContext)
{
Settings.PreloadDatabaseModel = newSettings.MssqlTools.TableDesigner.PreloadDatabaseModel;
Settings.PreloadDatabaseModel = newSettings.MssqlTools.TableDesigner != null ? newSettings.MssqlTools.TableDesigner.PreloadDatabaseModel : false;
return Task.FromResult(0);
}