Skip to content
This repository was archived by the owner on Jun 21, 2023. It is now read-only.

Commit 25fae6b

Browse files
Merge pull request #1606 from github/metrics/tweaks
Adding metrics tests for the new metrics
2 parents c0dc9cb + 46294b6 commit 25fae6b

File tree

23 files changed

+831
-120
lines changed

23 files changed

+831
-120
lines changed

GitHubVS.sln

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHub.Logging", "src\GitHu
106106
EndProject
107107
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitHub.Services.Vssdk", "src\GitHub.Services.Vssdk\GitHub.Services.Vssdk.csproj", "{2D3D2834-33BE-45CA-B3CC-12F853557D7B}"
108108
EndProject
109+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Metrics", "Metrics", "{C2D88962-BD6B-4F11-B914-535B38377962}"
110+
EndProject
111+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetricsServer", "test\MetricsTests\MetricsServer\MetricsServer.csproj", "{14FDEE91-7301-4247-846C-049647BF8E99}"
112+
EndProject
113+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MetricsTests", "test\MetricsTests\MetricsTests\MetricsTests.csproj", "{09313E65-7ADB-48C1-AD3A-572020C5BDCB}"
114+
EndProject
109115
Global
110116
GlobalSection(SolutionConfigurationPlatforms) = preSolution
111117
Debug|Any CPU = Debug|Any CPU
@@ -415,6 +421,26 @@ Global
415421
{2D3D2834-33BE-45CA-B3CC-12F853557D7B}.Release|Any CPU.Build.0 = Release|Any CPU
416422
{2D3D2834-33BE-45CA-B3CC-12F853557D7B}.ReleaseWithoutVsix|Any CPU.ActiveCfg = Release|Any CPU
417423
{2D3D2834-33BE-45CA-B3CC-12F853557D7B}.ReleaseWithoutVsix|Any CPU.Build.0 = Release|Any CPU
424+
{14FDEE91-7301-4247-846C-049647BF8E99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
425+
{14FDEE91-7301-4247-846C-049647BF8E99}.Debug|Any CPU.Build.0 = Debug|Any CPU
426+
{14FDEE91-7301-4247-846C-049647BF8E99}.DebugCodeAnalysis|Any CPU.ActiveCfg = Debug|Any CPU
427+
{14FDEE91-7301-4247-846C-049647BF8E99}.DebugCodeAnalysis|Any CPU.Build.0 = Debug|Any CPU
428+
{14FDEE91-7301-4247-846C-049647BF8E99}.DebugWithoutVsix|Any CPU.ActiveCfg = Debug|Any CPU
429+
{14FDEE91-7301-4247-846C-049647BF8E99}.DebugWithoutVsix|Any CPU.Build.0 = Debug|Any CPU
430+
{14FDEE91-7301-4247-846C-049647BF8E99}.Release|Any CPU.ActiveCfg = Release|Any CPU
431+
{14FDEE91-7301-4247-846C-049647BF8E99}.Release|Any CPU.Build.0 = Release|Any CPU
432+
{14FDEE91-7301-4247-846C-049647BF8E99}.ReleaseWithoutVsix|Any CPU.ActiveCfg = Release|Any CPU
433+
{14FDEE91-7301-4247-846C-049647BF8E99}.ReleaseWithoutVsix|Any CPU.Build.0 = Release|Any CPU
434+
{09313E65-7ADB-48C1-AD3A-572020C5BDCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
435+
{09313E65-7ADB-48C1-AD3A-572020C5BDCB}.Debug|Any CPU.Build.0 = Debug|Any CPU
436+
{09313E65-7ADB-48C1-AD3A-572020C5BDCB}.DebugCodeAnalysis|Any CPU.ActiveCfg = Debug|Any CPU
437+
{09313E65-7ADB-48C1-AD3A-572020C5BDCB}.DebugCodeAnalysis|Any CPU.Build.0 = Debug|Any CPU
438+
{09313E65-7ADB-48C1-AD3A-572020C5BDCB}.DebugWithoutVsix|Any CPU.ActiveCfg = Debug|Any CPU
439+
{09313E65-7ADB-48C1-AD3A-572020C5BDCB}.DebugWithoutVsix|Any CPU.Build.0 = Debug|Any CPU
440+
{09313E65-7ADB-48C1-AD3A-572020C5BDCB}.Release|Any CPU.ActiveCfg = Release|Any CPU
441+
{09313E65-7ADB-48C1-AD3A-572020C5BDCB}.Release|Any CPU.Build.0 = Release|Any CPU
442+
{09313E65-7ADB-48C1-AD3A-572020C5BDCB}.ReleaseWithoutVsix|Any CPU.ActiveCfg = Release|Any CPU
443+
{09313E65-7ADB-48C1-AD3A-572020C5BDCB}.ReleaseWithoutVsix|Any CPU.Build.0 = Release|Any CPU
418444
EndGlobalSection
419445
GlobalSection(SolutionProperties) = preSolution
420446
HideSolutionNode = FALSE
@@ -438,5 +464,8 @@ Global
438464
{7B835A7D-CF94-45E8-B191-96F5A4FE26A8} = {8A7DA2E7-262B-4581-807A-1C45CE79CDFD}
439465
{110B206F-8554-4B51-BF86-94DAA32F5E26} = {8A7DA2E7-262B-4581-807A-1C45CE79CDFD}
440466
{17EB676B-BB91-48B5-AA59-C67695C647C2} = {8A7DA2E7-262B-4581-807A-1C45CE79CDFD}
467+
{C2D88962-BD6B-4F11-B914-535B38377962} = {8A7DA2E7-262B-4581-807A-1C45CE79CDFD}
468+
{14FDEE91-7301-4247-846C-049647BF8E99} = {C2D88962-BD6B-4F11-B914-535B38377962}
469+
{09313E65-7ADB-48C1-AD3A-572020C5BDCB} = {C2D88962-BD6B-4F11-B914-535B38377962}
441470
EndGlobalSection
442471
EndGlobal

src/GitHub.Exports/Models/UsageModel.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ namespace GitHub.Models
44
{
55
public class UsageModel
66
{
7-
public DimensionsModel Dimensions { get; set; }
8-
public MeasuresModel Measures { get; set; }
7+
public DimensionsModel Dimensions { get; set; } = new DimensionsModel();
8+
public MeasuresModel Measures { get; set; } = new MeasuresModel();
9+
10+
// this should never be called by our code but it's required to be public by the serialization code
11+
public UsageModel() { }
912

1013
public static UsageModel Create(Guid guid)
1114
{
@@ -14,9 +17,8 @@ public static UsageModel Create(Guid guid)
1417
Dimensions = new DimensionsModel
1518
{
1619
Guid = guid,
17-
Date = DateTime.Now,
18-
},
19-
Measures = new MeasuresModel(),
20+
Date = DateTimeOffset.Now,
21+
}
2022
};
2123
}
2224

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using System.Reflection;
2+
using System.Runtime.CompilerServices;
23
using System.Runtime.InteropServices;
34

45
[assembly: AssemblyTitle("GitHub.Exports")]
56
[assembly: AssemblyDescription("GitHub interfaces for mef exports")]
67
[assembly: Guid("9aea02db-02b5-409c-b0ca-115d05331a6b")]
8+
[assembly: InternalsVisibleTo("MetricsTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c1a49bb6a01873a4e5434cbaa9993f5a75d3ba66fecfff4d85066c7094913d43f6f9bb706d2eb65f4990a7adfe7321e120ba8be5a8367fc5551c0a6eeb4850c5646377d314142abe69a5fb8ec0957a63ba5893901adb5b4cf0eb7f7e5861376e0cb4fd975576094b2fb4843df9c186eb17232365291b93e17f5e2b6cc1cda2c2")]

src/GitHub.Exports/Services/MetricsService.cs

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
using Octokit;
1111
using Octokit.Internal;
1212

13-
namespace GitHub.App
13+
namespace GitHub.Services
1414
{
1515
[Export(typeof(IMetricsService))]
1616
[PartCreationPolicy(CreationPolicy.NonShared)]
@@ -99,34 +99,18 @@ public Task SendOptIn()
9999
*/
100100
}
101101

102-
static StringContent SerializeRequest(UsageModel model)
102+
internal static StringContent SerializeRequest(UsageModel model)
103103
{
104104
var serializer = new SimpleJsonSerializer();
105105
var dictionary = new Dictionary<string, object>
106106
{
107-
{ToJsonPropertyName("Dimensions"), ToStringDictionary(model.Dimensions) },
108-
{ToJsonPropertyName("Measures"), ToObjectDictionary(model.Measures) }
107+
{ToJsonPropertyName("Dimensions"), ToModelDictionary(model.Dimensions) },
108+
{ToJsonPropertyName("Measures"), ToModelDictionary(model.Measures) }
109109
};
110110
return new StringContent(serializer.Serialize(dictionary), Encoding.UTF8, "application/json");
111111
}
112112

113-
static Dictionary<string, string> ToStringDictionary(object model)
114-
{
115-
var dict = new Dictionary<string, string>();
116-
var type = model.GetType();
117-
118-
foreach (var prop in type.GetProperties())
119-
{
120-
if (prop.PropertyType.IsValueType || prop.PropertyType == typeof(string))
121-
{
122-
dict.Add(ToJsonPropertyName(prop.Name), prop.GetValue(model).ToString());
123-
}
124-
}
125-
126-
return dict;
127-
}
128-
129-
static Dictionary<string, object> ToObjectDictionary(object model)
113+
static Dictionary<string, object> ToModelDictionary(object model)
130114
{
131115
var dict = new Dictionary<string, object>();
132116
var type = model.GetType();
@@ -137,11 +121,25 @@ static Dictionary<string, object> ToObjectDictionary(object model)
137121
{
138122
dict.Add(ToJsonPropertyName(prop.Name), prop.GetValue(model));
139123
}
124+
else
125+
{
126+
var value = prop.GetValue(model);
127+
128+
if (value == null)
129+
{
130+
dict.Add(ToJsonPropertyName(prop.Name), value);
131+
}
132+
else
133+
{
134+
dict.Add(ToJsonPropertyName(prop.Name), ToModelDictionary(value));
135+
}
136+
}
140137
}
141138

142139
return dict;
143140
}
144141

142+
145143
/// <summary>
146144
/// Convert from PascalCase to camelCase.
147145
/// </summary>

src/GitHub.VisualStudio/Services/UsageTracker.cs

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -59,28 +59,34 @@ public async Task IncrementCounter(Expression<Func<UsageModel.MeasuresModel, int
5959

6060
IDisposable StartTimer()
6161
{
62-
return service.StartTimer(TimerTick, TimeSpan.FromMinutes(3), TimeSpan.FromHours(8));
62+
return service.StartTimer(TimerTick, TimeSpan.FromMinutes(3), TimeSpan.FromDays(1));
6363
}
6464

6565
async Task Initialize()
6666
{
67+
if (initialized)
68+
return;
69+
6770
// The services needed by the usage tracker are loaded when they are first needed to
6871
// improve the startup time of the extension.
69-
if (!initialized)
70-
{
71-
await ThreadingHelper.SwitchToMainThreadAsync();
72+
await ThreadingHelper.SwitchToMainThreadAsync();
7273

73-
client = gitHubServiceProvider.TryGetService<IMetricsService>();
74-
connectionManager = gitHubServiceProvider.GetService<IConnectionManager>();
75-
vsservices = gitHubServiceProvider.GetService<IVSServices>();
76-
initialized = true;
77-
}
74+
client = gitHubServiceProvider.TryGetService<IMetricsService>();
75+
connectionManager = gitHubServiceProvider.GetService<IConnectionManager>();
76+
vsservices = gitHubServiceProvider.GetService<IVSServices>();
77+
initialized = true;
7878
}
7979

8080
async Task TimerTick()
8181
{
8282
await Initialize();
8383

84+
if (firstTick)
85+
{
86+
await IncrementCounter(x => x.NumberOfStartups);
87+
firstTick = false;
88+
}
89+
8490
if (client == null || !userSettings.CollectMetrics)
8591
{
8692
timer.Dispose();
@@ -89,16 +95,8 @@ async Task TimerTick()
8995
}
9096

9197
var data = await service.ReadLocalData();
92-
var changed = false;
93-
94-
if (firstTick)
95-
{
96-
var current = await GetCurrentReport(data);
97-
current.Measures.NumberOfStartups++;
98-
changed = true;
99-
firstTick = false;
100-
}
10198

99+
var changed = false;
102100
for (var i = data.Reports.Count - 1; i >= 0; --i)
103101
{
104102
if (data.Reports[i].Dimensions.Date.Date != DateTimeOffset.Now.Date)
@@ -138,16 +136,8 @@ async Task<UsageModel> GetCurrentReport(UsageData data)
138136
current.Dimensions.AppVersion = AssemblyVersionInformation.Version;
139137
current.Dimensions.VSVersion = vsservices.VSVersion;
140138

141-
if (connectionManager.Connections.Any(x => x.HostAddress.IsGitHubDotCom()))
142-
{
143-
current.Dimensions.IsGitHubUser = true;
144-
}
145-
146-
if (connectionManager.Connections.Any(x => !x.HostAddress.IsGitHubDotCom()))
147-
{
148-
current.Dimensions.IsEnterpriseUser = true;
149-
}
150-
139+
current.Dimensions.IsGitHubUser = connectionManager.Connections.Any(x => x.HostAddress.IsGitHubDotCom());
140+
current.Dimensions.IsEnterpriseUser = connectionManager.Connections.Any(x => !x.HostAddress.IsGitHubDotCom());
151141
return current;
152142
}
153143
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<configuration>
3+
<startup>
4+
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
5+
</startup>
6+
</configuration>
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
4+
<PropertyGroup>
5+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
6+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
7+
<ProjectGuid>{14FDEE91-7301-4247-846C-049647BF8E99}</ProjectGuid>
8+
<OutputType>Library</OutputType>
9+
<AppDesignerFolder>Properties</AppDesignerFolder>
10+
<RootNamespace>MetricsServer</RootNamespace>
11+
<AssemblyName>MetricsServer</AssemblyName>
12+
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
13+
<FileAlignment>512</FileAlignment>
14+
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
15+
<NuGetPackageImportStamp>
16+
</NuGetPackageImportStamp>
17+
</PropertyGroup>
18+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
19+
<PlatformTarget>AnyCPU</PlatformTarget>
20+
<DebugSymbols>true</DebugSymbols>
21+
<DebugType>full</DebugType>
22+
<Optimize>false</Optimize>
23+
<OutputPath>bin\Debug\</OutputPath>
24+
<DefineConstants>DEBUG;TRACE</DefineConstants>
25+
<ErrorReport>prompt</ErrorReport>
26+
<WarningLevel>4</WarningLevel>
27+
<NoWarn>8002,618</NoWarn>
28+
</PropertyGroup>
29+
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
30+
<PlatformTarget>AnyCPU</PlatformTarget>
31+
<DebugType>pdbonly</DebugType>
32+
<Optimize>true</Optimize>
33+
<OutputPath>bin\Release\</OutputPath>
34+
<DefineConstants>TRACE</DefineConstants>
35+
<ErrorReport>prompt</ErrorReport>
36+
<WarningLevel>4</WarningLevel>
37+
</PropertyGroup>
38+
<PropertyGroup>
39+
<StartupObject />
40+
</PropertyGroup>
41+
<PropertyGroup>
42+
<SignAssembly>true</SignAssembly>
43+
</PropertyGroup>
44+
<PropertyGroup>
45+
<AssemblyOriginatorKeyFile>key.snk</AssemblyOriginatorKeyFile>
46+
</PropertyGroup>
47+
<ItemGroup>
48+
<Reference Include="Nancy, Version=1.4.1.0, Culture=neutral, processorArchitecture=MSIL">
49+
<SpecificVersion>False</SpecificVersion>
50+
<HintPath>$(SolutionDir)\packages\Nancy.1.4.1\lib\net40\Nancy.dll</HintPath>
51+
<Private>True</Private>
52+
</Reference>
53+
<Reference Include="Nancy.Hosting.Self, Version=1.4.1.0, Culture=neutral, processorArchitecture=MSIL">
54+
<HintPath>$(SolutionDir)\packages\Nancy.Hosting.Self.1.4.1\lib\net40\Nancy.Hosting.Self.dll</HintPath>
55+
<Private>True</Private>
56+
</Reference>
57+
<Reference Include="System" />
58+
<Reference Include="System.Core" />
59+
<Reference Include="System.Xml.Linq" />
60+
<Reference Include="System.Data.DataSetExtensions" />
61+
<Reference Include="Microsoft.CSharp" />
62+
<Reference Include="System.Data" />
63+
<Reference Include="System.Net.Http" />
64+
<Reference Include="System.Xml" />
65+
</ItemGroup>
66+
<ItemGroup>
67+
<Compile Include="Program.cs" />
68+
<Compile Include="Properties\AssemblyInfo.cs" />
69+
<None Include="..\..\..\src\GitHub.Exports\Models\UsageData.cs">
70+
<Link>UsageData.cs</Link>
71+
</None>
72+
<None Include="..\..\..\src\GitHub.Exports\Models\UsageModel.cs">
73+
<Link>UsageModel.cs</Link>
74+
</None>
75+
</ItemGroup>
76+
<ItemGroup>
77+
<None Include="App.config" />
78+
<None Include="key.snk" />
79+
<None Include="packages.config" />
80+
</ItemGroup>
81+
<ItemGroup>
82+
<ProjectReference Include="..\..\..\src\GitHub.Exports\GitHub.Exports.csproj">
83+
<Project>{9AEA02DB-02B5-409C-B0CA-115D05331A6B}</Project>
84+
<Name>GitHub.Exports</Name>
85+
</ProjectReference>
86+
</ItemGroup>
87+
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
88+
<Import Project="..\..\..\packages\StrongNamer.0.0.6\build\StrongNamer.targets" Condition="Exists('..\..\..\packages\StrongNamer.0.0.6\build\StrongNamer.targets')" />
89+
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
90+
<PropertyGroup>
91+
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
92+
</PropertyGroup>
93+
<Error Condition="!Exists('..\..\..\packages\StrongNamer.0.0.6\build\StrongNamer.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\packages\StrongNamer.0.0.6\build\StrongNamer.targets'))" />
94+
</Target>
95+
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
96+
Other similar extension points exist, see Microsoft.Common.targets.
97+
<Target Name="BeforeBuild">
98+
</Target>
99+
<Target Name="AfterBuild">
100+
</Target>
101+
-->
102+
</Project>

0 commit comments

Comments
 (0)