Skip to content

Commit 0c49138

Browse files
author
Sergey
committed
MVC 5 support added
Core lib has been refactored
1 parent 7fec1b3 commit 0c49138

File tree

66 files changed

+2287
-129
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+2287
-129
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,9 @@ BuildNuget
1111
/TestServer/bin
1212
/TestServer/obj/Debug
1313
/TestServer/obj/Release
14+
/Perfon.Mvc/bin
15+
/Perfon.Mvc/obj/Debug
16+
/Perfon.Mvc/obj/Release
17+
/TestMvcApp/obj/Release
18+
/TestMvcApp/bin
19+
/TestMvcApp/obj/Debug

JMeterTests/StressTest_PollCounters_TestService.jmx

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
</elementProp>
2121
<elementProp name="host_port" elementType="Argument">
2222
<stringProp name="Argument.name">host_port</stringProp>
23-
<stringProp name="Argument.value">8010</stringProp>
23+
<stringProp name="Argument.value">8012</stringProp>
2424
<stringProp name="Argument.metadata">=</stringProp>
2525
</elementProp>
2626
<elementProp name="api_prefix" elementType="Argument">
@@ -44,9 +44,9 @@
4444
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
4545
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
4646
<boolProp name="LoopController.continue_forever">false</boolProp>
47-
<stringProp name="LoopController.loops">4</stringProp>
47+
<stringProp name="LoopController.loops">10</stringProp>
4848
</elementProp>
49-
<stringProp name="ThreadGroup.num_threads">350</stringProp>
49+
<stringProp name="ThreadGroup.num_threads">150</stringProp>
5050
<stringProp name="ThreadGroup.ramp_time">2</stringProp>
5151
<longProp name="ThreadGroup.start_time">1483557187000</longProp>
5252
<longProp name="ThreadGroup.end_time">1483557187000</longProp>
@@ -58,7 +58,7 @@
5858
<hashTree>
5959
<LoopController guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
6060
<boolProp name="LoopController.continue_forever">true</boolProp>
61-
<stringProp name="LoopController.loops">150</stringProp>
61+
<stringProp name="LoopController.loops">30</stringProp>
6262
</LoopController>
6363
<hashTree>
6464
<CounterConfig guiclass="CounterConfigGui" testclass="CounterConfig" testname="Counter" enabled="true">
@@ -109,7 +109,7 @@
109109
</JSONPostProcessor>
110110
<hashTree/>
111111
</hashTree>
112-
<LoopController guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
112+
<LoopController guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller Get Full Track" enabled="true">
113113
<boolProp name="LoopController.continue_forever">true</boolProp>
114114
<stringProp name="LoopController.loops">${records_name_matchNr}</stringProp>
115115
</LoopController>
@@ -143,7 +143,61 @@
143143
<boolProp name="HTTPSampler.monitor">false</boolProp>
144144
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
145145
</HTTPSamplerProxy>
146-
<hashTree/>
146+
<hashTree>
147+
<JSONPostProcessor guiclass="JSONPostProcessorGui" testclass="JSONPostProcessor" testname="JSON Extractor NumOfRecords" enabled="true">
148+
<stringProp name="JSONPostProcessor.referenceNames">count_vals</stringProp>
149+
<stringProp name="JSONPostProcessor.jsonPathExprs">$[*]</stringProp>
150+
<stringProp name="JSONPostProcessor.match_numbers">-1</stringProp>
151+
</JSONPostProcessor>
152+
<hashTree/>
153+
</hashTree>
154+
</hashTree>
155+
<LoopController guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller Update" enabled="true">
156+
<boolProp name="LoopController.continue_forever">true</boolProp>
157+
<stringProp name="LoopController.loops">3</stringProp>
158+
</LoopController>
159+
<hashTree>
160+
<LoopController guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
161+
<boolProp name="LoopController.continue_forever">true</boolProp>
162+
<stringProp name="LoopController.loops">${records_name_matchNr}</stringProp>
163+
</LoopController>
164+
<hashTree>
165+
<UniformRandomTimer guiclass="UniformRandomTimerGui" testclass="UniformRandomTimer" testname="Uniform Random Timer" enabled="true">
166+
<stringProp name="ConstantTimer.delay">0</stringProp>
167+
<stringProp name="RandomTimer.range">50.0</stringProp>
168+
</UniformRandomTimer>
169+
<hashTree/>
170+
<CounterConfig guiclass="CounterConfigGui" testclass="CounterConfig" testname="Counter" enabled="true">
171+
<stringProp name="CounterConfig.start">1</stringProp>
172+
<stringProp name="CounterConfig.end">${records_name_matchNr}</stringProp>
173+
<stringProp name="CounterConfig.incr">1</stringProp>
174+
<stringProp name="CounterConfig.name">cnt2</stringProp>
175+
<stringProp name="CounterConfig.format"></stringProp>
176+
<boolProp name="CounterConfig.per_user">false</boolProp>
177+
</CounterConfig>
178+
<hashTree/>
179+
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="Get Counter Track Skip" enabled="true">
180+
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
181+
<collectionProp name="Arguments.arguments"/>
182+
</elementProp>
183+
<stringProp name="HTTPSampler.domain">${host_url}</stringProp>
184+
<stringProp name="HTTPSampler.port">${host_port}</stringProp>
185+
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
186+
<stringProp name="HTTPSampler.response_timeout"></stringProp>
187+
<stringProp name="HTTPSampler.protocol"></stringProp>
188+
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
189+
<stringProp name="HTTPSampler.path">/${api_prefix}/perfcounters?name=${__urlencode(${__V(records_name_${cnt2})})}&amp;skip=${count_vals_matchNr}</stringProp>
190+
<stringProp name="HTTPSampler.method">GET</stringProp>
191+
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
192+
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
193+
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
194+
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
195+
<stringProp name="HTTPSampler.implementation">HttpClient4</stringProp>
196+
<boolProp name="HTTPSampler.monitor">false</boolProp>
197+
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
198+
</HTTPSamplerProxy>
199+
<hashTree/>
200+
</hashTree>
147201
</hashTree>
148202
</hashTree>
149203
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="false">
@@ -251,7 +305,7 @@
251305
<connectTime>true</connectTime>
252306
</value>
253307
</objProp>
254-
<stringProp name="filename"></stringProp>
308+
<stringProp name="filename">D:\MyProgs\PerfMonLib\Perfon.Net\JMeterTests\StressTest_PollCounters_TestService_res2.jtl</stringProp>
255309
</ResultCollector>
256310
<hashTree/>
257311
<ResultCollector guiclass="GraphVisualizer" testclass="ResultCollector" testname="Graph Results" enabled="false">
@@ -325,7 +379,7 @@
325379
</objProp>
326380
<stringProp name="RespTimeGraph.interval">1000</stringProp>
327381
<stringProp name="RespTimeGraph.yaxisscalemaxvalue">300</stringProp>
328-
<stringProp name="filename"></stringProp>
382+
<stringProp name="filename">D:\MyProgs\PerfMonLib\Perfon.Net\JMeterTests\StressTest_PollCounters_TestService_res2.jtl</stringProp>
329383
</ResultCollector>
330384
<hashTree/>
331385
<Summariser guiclass="SummariserGui" testclass="Summariser" testname="Generate Summary Results" enabled="false"/>

Perfon.Core/Constants.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace Perfon.Core
8+
{
9+
public enum EnumKeyNames
10+
{
11+
PerfMonitorLib
12+
}
13+
}

Perfon.Core/PerfMonitor.cs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Diagnostics;
55
using System.IO;
66
using System.Linq;
7+
using System.Reflection;
78
using System.Text;
89
using System.Threading;
910
using System.Threading.Tasks;
@@ -251,6 +252,72 @@ public void Stop()
251252
}
252253

253254

255+
/// <summary>
256+
/// Return UI html page for monitor perf counters
257+
/// </summary>
258+
public Lazy<string> UIPage = new Lazy<string>(() =>
259+
{
260+
var assembly = Assembly.GetExecutingAssembly();
261+
var resourceName = "Perfon.Core.UI.PerfCountersUI.html";
262+
263+
string result = "";
264+
265+
try
266+
{
267+
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
268+
{
269+
using (StreamReader reader = new StreamReader(stream))
270+
{
271+
result = reader.ReadToEnd();
272+
273+
using (Stream stream2 = assembly.GetManifestResourceStream("Perfon.Core.UI.PerfCountersUIPanel.html"))
274+
{
275+
using (StreamReader reader2 = new StreamReader(stream2))
276+
{
277+
result = result.Replace("PLACEHOLDER_FOR_PANEL", reader2.ReadToEnd());
278+
}
279+
}
280+
281+
}
282+
}
283+
}
284+
catch (Exception exc)
285+
{
286+
result = exc.ToString();
287+
}
288+
289+
return result;
290+
});
291+
/// <summary>
292+
/// Return UI html panel as div for monitor perf counters
293+
/// </summary>
294+
private Lazy<string> uiPanel = new Lazy<string>(() =>
295+
{
296+
var assembly = Assembly.GetExecutingAssembly();
297+
var resourceName = "Perfon.Core.UI.PerfCountersUIPanel.html";
298+
299+
string result = "";
300+
301+
try
302+
{
303+
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
304+
{
305+
using (StreamReader reader = new StreamReader(stream))
306+
{
307+
result = reader.ReadToEnd();
308+
}
309+
}
310+
}
311+
catch (Exception exc)
312+
{
313+
result = exc.ToString();
314+
}
315+
316+
return result;
317+
});
318+
public string UIPanel { get { return uiPanel.Value; } }
319+
320+
254321

255322
private Timer timer { get; set; }
256323

Perfon.Core/Perfon.Core.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
<Reference Include="System.Xml" />
4747
</ItemGroup>
4848
<ItemGroup>
49+
<Compile Include="Constants.cs" />
4950
<Compile Include="Notifications\ThresholdMaxNotification.cs" />
5051
<Compile Include="Notifications\IThresholdNotification.cs" />
5152
<Compile Include="Notifications\ThresholdBaseNotification.cs" />
@@ -72,6 +73,12 @@
7273
<ItemGroup>
7374
<None Include="packages.config" />
7475
</ItemGroup>
76+
<ItemGroup>
77+
<EmbeddedResource Include="UI\PerfCountersUI.html" />
78+
</ItemGroup>
79+
<ItemGroup>
80+
<EmbeddedResource Include="UI\PerfCountersUIPanel.html" />
81+
</ItemGroup>
7582
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
7683
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
7784
Other similar extension points exist, see Microsoft.Common.targets.

Perfon.Core/Perfon.Core.nuspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<projectUrl>http://perfon.1gb.ru/</projectUrl>
1010
<requireLicenseAcceptance>false</requireLicenseAcceptance>
1111
<description>$description$</description>
12-
<releaseNotes>Dashboard bug fix</releaseNotes>
12+
<releaseNotes>MVC 5 support has been added</releaseNotes>
1313
<copyright>$copyright$</copyright>
1414
<tags>Performance Monitoring .Net </tags>
1515
</metadata>

Perfon.Core/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("1.0.2.0")]
36-
[assembly: AssemblyFileVersion("1.0.w.0")]
35+
[assembly: AssemblyVersion("1.0.3.0")]
36+
[assembly: AssemblyFileVersion("1.0.3.0")]
File renamed without changes.

Perfon.WebApi/UI/PerfCountersUIPanel.html renamed to Perfon.Core/UI/PerfCountersUIPanel.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
<div class="pane">
1+
<script src="https://cdnjs.cloudflare.com/ajax/libs/dygraph/2.0.0/dygraph.js"></script>
2+
<div class="pane">
23
<form class="navbar-form">
34
<div class="form-group">
45
<label for="selected_date">Date </label>
@@ -19,7 +20,6 @@
1920
<div id="chartsContainer">
2021
</div>
2122
</div>
22-
2323
<style>
2424
.graph-block
2525
{
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Runtime.Caching;
5+
using System.Threading.Tasks;
6+
using System.Web;
7+
using System.Web.Mvc;
8+
using Perfon.Core;
9+
using Perfon.Core.PerfCounterStorages;
10+
using Perfon.Mvc;
11+
12+
namespace Perfon.Mvc.Controllers
13+
{
14+
public class PerfCountersController : Controller
15+
{
16+
readonly string keyList = "PerfListCounters";
17+
18+
19+
public IPerfomanceCountersStorage Db
20+
{
21+
get
22+
{
23+
//How to deal with DI here??
24+
return (this.HttpContext.Application[EnumKeyNames.PerfMonitorLib.ToString()] as PerfMonitorForMvc).Storage;
25+
}
26+
}
27+
28+
29+
/// <summary>
30+
/// Get counters list
31+
/// </summary>
32+
/// <returns></returns>
33+
public async Task<ActionResult> Get()
34+
{
35+
var requestQueryString = HttpContext.Request.QueryString;
36+
37+
var name = requestQueryString["name"];
38+
39+
if (string.IsNullOrEmpty(name))
40+
{
41+
42+
var res = MemoryCache.Default.Get(keyList) as IEnumerable<string>;
43+
44+
if (res == null || res.Count() <= 0)
45+
{
46+
// Not the best solution. Use Lazy here??
47+
res = await Db.GetCountersList();
48+
MemoryCache.Default.Add(keyList, res, new DateTimeOffset(DateTime.Now.AddSeconds(60)));
49+
}
50+
51+
return Json(res, JsonRequestBehavior.AllowGet);
52+
}
53+
else
54+
{
55+
DateTime? date = null;
56+
int? skip = null;
57+
if(!string.IsNullOrEmpty(requestQueryString["date"]))
58+
{
59+
date = DateTime.Parse(requestQueryString["date"]);
60+
}
61+
if (!string.IsNullOrEmpty(requestQueryString["skip"]))
62+
{
63+
skip = int.Parse(requestQueryString["skip"]);
64+
}
65+
66+
return await GetTrack(name, date, skip);
67+
}
68+
}
69+
70+
/// <summary>
71+
/// Get perf counter values history track
72+
/// </summary>
73+
/// <param name="name"></param>
74+
/// <returns></returns>
75+
private async Task<ActionResult> GetTrack(string name, DateTime? date = null, int? skip = null)
76+
{
77+
int skip2 = 0;
78+
if (skip.HasValue)
79+
{
80+
skip2 = skip.Value;
81+
}
82+
83+
string key = name + date.GetHashCode();
84+
var res = MemoryCache.Default.Get(key) as IEnumerable<PerfCounterValue>;
85+
86+
if (res == null || res.Count() <= 0)
87+
{
88+
// Not the best solution. Use Lazy here??
89+
res = await Db.QueryCounterValues(name, date);
90+
MemoryCache.Default.Add(key, res, new DateTimeOffset(DateTime.Now.AddSeconds(3)));
91+
}
92+
93+
if (res != null && skip2 > 0)
94+
{
95+
res = res.Skip(skip2).ToList();
96+
}
97+
98+
return new CustomJsonResult { Data = res };
99+
//return new CustomJsonResult(res, JsonRequestBehavior.AllowGet);
100+
}
101+
}
102+
}

0 commit comments

Comments
 (0)