This commit is contained in:
Yue Zhang 2015-04-17 17:24:47 +08:00
Родитель e37f3a3e02
Коммит 105dccffb4
58 изменённых файлов: 5569 добавлений и 0 удалений

188
.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,188 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
build/
bld/
[Bb]in/
[Oo]bj/
# Roslyn cache directories
*.ide/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
#NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding addin-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
## TODO: Comment the next line if you want to checkin your
## web deploy settings but do note that will include unencrypted
## passwords
*.pubxml
# Enable "build/" folder in the NuGet Packages folder since
# NuGet packages use it for MSBuild targets.
# This line needs to be after the ignore of the build folder
# (and the packages folder if the line above has been uncommented)
!packages/build/
# Windows Azure Build Output
csx/
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
#Source Depo
build*.prf
build*.trc
build*.err
sources
sources.dep
dirs
project.mk

Просмотреть файл

@ -0,0 +1,122 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
The MIT License (MIT)
Copyright 2015 Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define CurrentVersion="1.0.0.0"?>
<?ifdef var.EnhancedMonitoring.ProjectDir?>
<?define EnhancedMonitoring.Config.Path="$(var.EnhancedMonitoring.ProjectDir)\Configuration\EnhancedMonitoringProviderConfig.xml"?>
<?define EnhancedMonitoring.Common.Path="$(var.EnhancedMonitoring.TargetDir)\EnhancedMonitoring.dll"?>
<?define EnhancedMonitoring.Service.Path="$(var.Service.TargetDir)\EnhancedMonitoringProvider.Service.exe"?>
<?else?>
<?endif?>
<Product Id="*"
Name="Enhanced Monitoring Provider Service"
Language="1033"
Version="$(var.CurrentVersion)"
Manufacturer="Microsoft Corporation"
UpgradeCode="2ABBBB5B-39D3-4FB2-9FF2-384DE4DE8F97">
<!-- Package Information -->
<Package InstallerVersion="200" Platform="x64" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade Schedule="afterInstallValidate"
AllowDowngrades="yes" />
<Media Id="1" Cabinet="empsvc.cab" EmbedCab="yes" />
<!-- Conditions -->
<!-- Check Hyper-V Installation -->
<Property Id="HYPERVINSTALLED">
<DirectorySearch Id="SystemFolder" Path="[WindowsFolder]">
<DirectorySearch Id="HyperVInstallation" Path="System32">
<FileSearch Name="vmms.exe" />
</DirectorySearch>
</DirectorySearch>
</Property>
<Condition Message="You need to be an administrator to install this product.">Privileged</Condition>
<Condition Message="Make sure that Hyper-V role is installed, then try again.">
<![CDATA[Installed OR HYPERVINSTALLED]]>
</Condition>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="CommonAppDataFolder">
<Directory Id="EnhancedMonitoringDataFolder" Name="Enhanced Monitoring" >
<Component Id="EnhancedMonitoring.Config" Guid="B557EDF2-547A-49AF-BAEF-AE4A6D7FF08E" Win64='yes'>
<File Id="EnhancedMonitoringProviderConfig.xml" Name="EnhancedMonitoringProviderConfig.xml"
Source="$(var.EnhancedMonitoring.Config.Path)" Vital="yes" KeyPath="yes" DiskId="1"/>
</Component>
</Directory>
</Directory>
<Directory Id="ProgramFiles64Folder" Name="PFiles">
<Directory Id="INSTALLDIR" Name="Enhanced Monitoring" >
<Component Id="EnhancedMonitoring.Common" Guid="44DD941F-D097-4CC0-A57B-E12DD3311BDB" Win64='yes'>
<File Id="EnhancedMonitoring.dll" Name="EnhancedMonitoring.dll"
Source="$(var.EnhancedMonitoring.Common.Path)"
Vital="yes" KeyPath="yes" DiskId="1"/>
</Component>
<Component Id="EnhancedMonitoring.Service" Guid="379A9EFB-8813-43ED-B954-ED3065595D93" Win64='yes'>
<File Id="EnhancedMonitoringProvider.Service.exe" Name="EnhancedMonitoringProvider.Service.exe"
Source="$(var.EnhancedMonitoring.Service.Path)" Vital="yes" KeyPath="yes" DiskId="1"/>
<ServiceInstall
Id="ServiceInstaller"
Type="ownProcess"
Vital="yes"
Name="empsvc"
DisplayName="Enhanced Monitoring Provider Service"
Description="Provides enhanced data monitoring for virtual machines. Allows monitoring the performance and resource status of the physical server from within the virtual machine."
Start="auto"
Account=".\LocalSystem"
ErrorControl="ignore"
Interactive="no"
>
<ServiceConfig DelayedAutoStart ="yes" OnReinstall="yes" OnInstall="yes" />
</ServiceInstall>
<ServiceControl Id="StartService" Start="install" Stop="both" Remove="uninstall" Name="empsvc" Wait="yes" />
<util:EventSource xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
Log="Enhanced Monitoring"
Name="Enhanced Monitoring Provider Service"
EventMessageFile="C:\Windows\Microsoft.NET\Framework\v4.0.30319\EventLogMessages.dll"/>
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="ProductFeature" Title="Enhanced Monitoring Provider Service" Level="1">
<ComponentRef Id="EnhancedMonitoring.Config" />
<ComponentRef Id="EnhancedMonitoring.Common" />
<ComponentRef Id="EnhancedMonitoring.Service" />
</Feature>
</Product>
</Wix>

Просмотреть файл

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x64</Platform>
<ProductVersion>3.8</ProductVersion>
<ProjectGuid>a6aa397b-1031-4fbf-9a8a-b50ee7318ec6</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>Debug.EnhancedMonitoring</OutputName>
<OutputType>Package</OutputType>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>Debug</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugAndRelease|x86' ">
<DefineConstants>Debug</DefineConstants>
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugAndRelease|AnyCPU' ">
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugAndRelease|Any CPU' ">
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
<DefineConstants>Debug</DefineConstants>
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugAndRelease|x64' ">
<DefineConstants>Debug</DefineConstants>
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Platform)\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<ItemGroup>
<WixExtension Include="WixUtilExtension">
<HintPath>$(WixExtDir)\WixUtilExtension.dll</HintPath>
<Name>WixUtilExtension</Name>
</WixExtension>
</ItemGroup>
<ItemGroup>
<Compile Include="Product.wxs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\EnhancedMonitoring\EnhancedMonitoring.csproj">
<Name>EnhancedMonitoring</Name>
<Project>{7eacc378-2947-4f2e-ab0f-eb57be7d3680}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Service\Service.csproj">
<Name>Service</Name>
<Project>{ed1f3b96-683f-4d16-b4f9-06765e3697c1}</Project>
<Private>True</Private>
<DoNotHarvest>True</DoNotHarvest>
<RefProjectOutputGroups>Binaries;Content;Satellites</RefProjectOutputGroups>
<RefTargetDir>INSTALLFOLDER</RefTargetDir>
</ProjectReference>
</ItemGroup>
<Import Project="$(WixTargetsPath)" />
<!--
To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Wix.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Просмотреть файл

@ -0,0 +1,49 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.21005.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTest", "UnitTest\UnitTest.csproj", "{0B568E5B-3796-47CC-B934-C4684CBE241C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Service", "Service\Service.csproj", "{ED1F3B96-683F-4D16-B4F9-06765E3697C1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnhancedMonitoring", "EnhancedMonitoring\EnhancedMonitoring.csproj", "{7EACC378-2947-4F2E-AB0F-EB57BE7D3680}"
EndProject
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Setup", "..\packages\MSI\EnhancedMonitoring\Setup.wixproj", "{A6AA397B-1031-4FBF-9A8A-B50EE7318EC6}"
ProjectSection(ProjectDependencies) = postProject
{7EACC378-2947-4F2E-AB0F-EB57BE7D3680} = {7EACC378-2947-4F2E-AB0F-EB57BE7D3680}
{ED1F3B96-683F-4D16-B4F9-06765E3697C1} = {ED1F3B96-683F-4D16-B4F9-06765E3697C1}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
DebugAndRelease|x64 = DebugAndRelease|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0B568E5B-3796-47CC-B934-C4684CBE241C}.Debug|x64.ActiveCfg = Debug|Any CPU
{0B568E5B-3796-47CC-B934-C4684CBE241C}.Debug|x64.Build.0 = Debug|Any CPU
{0B568E5B-3796-47CC-B934-C4684CBE241C}.DebugAndRelease|x64.ActiveCfg = DebugAndRelease|Any CPU
{0B568E5B-3796-47CC-B934-C4684CBE241C}.Release|x64.ActiveCfg = Release|Any CPU
{ED1F3B96-683F-4D16-B4F9-06765E3697C1}.Debug|x64.ActiveCfg = Debug|x64
{ED1F3B96-683F-4D16-B4F9-06765E3697C1}.Debug|x64.Build.0 = Debug|x64
{ED1F3B96-683F-4D16-B4F9-06765E3697C1}.DebugAndRelease|x64.ActiveCfg = DebugAndRelease|x64
{ED1F3B96-683F-4D16-B4F9-06765E3697C1}.DebugAndRelease|x64.Build.0 = DebugAndRelease|x64
{ED1F3B96-683F-4D16-B4F9-06765E3697C1}.Release|x64.ActiveCfg = Release|x64
{ED1F3B96-683F-4D16-B4F9-06765E3697C1}.Release|x64.Build.0 = Release|x64
{7EACC378-2947-4F2E-AB0F-EB57BE7D3680}.Debug|x64.ActiveCfg = Debug|x64
{7EACC378-2947-4F2E-AB0F-EB57BE7D3680}.Debug|x64.Build.0 = Debug|x64
{7EACC378-2947-4F2E-AB0F-EB57BE7D3680}.DebugAndRelease|x64.ActiveCfg = DebugAndRelease|x64
{7EACC378-2947-4F2E-AB0F-EB57BE7D3680}.DebugAndRelease|x64.Build.0 = DebugAndRelease|x64
{7EACC378-2947-4F2E-AB0F-EB57BE7D3680}.Release|x64.ActiveCfg = Release|x64
{7EACC378-2947-4F2E-AB0F-EB57BE7D3680}.Release|x64.Build.0 = Release|x64
{A6AA397B-1031-4FBF-9A8A-B50EE7318EC6}.Debug|x64.ActiveCfg = Debug|x64
{A6AA397B-1031-4FBF-9A8A-B50EE7318EC6}.Debug|x64.Build.0 = Debug|x64
{A6AA397B-1031-4FBF-9A8A-B50EE7318EC6}.DebugAndRelease|x64.ActiveCfg = DebugAndRelease|x86
{A6AA397B-1031-4FBF-9A8A-B50EE7318EC6}.Release|x64.ActiveCfg = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,263 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
The MIT License (MIT)
Copyright 2015 Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<Monitor>
<!-- Refresh interval in seconds-->
<!-- Mandatory -->
<RefreshRate>60</RefreshRate>
<!-- Mandatory -->
<Version>1.0.0</Version>
<!-- Optional -->
<LogLevel>Verbose</LogLevel>
<!-- Mandatory -->
<DataItemKeyPrefix>Enhanced_Monitoring_Metric_Data_Item_Part_</DataItemKeyPrefix>
<!-- Detect supported VMs through WMI-->
<SupportedVMDetector>
<!-- Mandatory -->
<!-- A key name that host uses to identify VMs supported-->
<GuestDataItemKey>Enhanced_Monitoring_Supported</GuestDataItemKey>
<!-- Select WMI properties as arguments passed to future WMI Query -->
<!-- The following properties are selected by default: -->
<!-- 1. Name as VirtualMachineName -->
<!-- 2. ElementName as VirtualMachineElementName -->
<!-- 3. Path as VirtualMachinePath -->
<!-- 4. GuestExchangeItems as GuestExchangeItems -->
<!-- Optional -->
<VirtualMachineProperties>
<VirtualMachineProperty>
<Select>Status</Select>
<As>VirtualMachineStatus</As>
</VirtualMachineProperty>
</VirtualMachineProperties>
</SupportedVMDetector>
<MgmtObjects>
<MgmtObject>
<Namespace>root\cimv2</Namespace>
<From>Win32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor</From>
<Where>Name="_Total"</Where>
<PerfCounters>
<PerfCounter>
<Select>PercentHypervisorRuntime</Select>
</PerfCounter>
<PerfCounter>
<Select>PercentTotalRunTime</Select>
</PerfCounter>
<PerfCounter>
<Select>TimeStamp_PerfTime</Select>
</PerfCounter>
<PerfCounter>
<Select>Frequency_PerfTime</Select>
</PerfCounter>
</PerfCounters>
</MgmtObject>
<MgmtObject>
<Namespace>root\cimv2</Namespace>
<From>Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor</From>
<Where>Name like "{0}:Hv VP%"</Where>
<WhereArgs>
<!--'{0}' in 'Where' statement will be replaced by the bellow argument-->
<WhereArg Escape="true">VirtualMachineElementName</WhereArg>
</WhereArgs>
<PerfCounters>
<PerfCounter>
<Select>PercentGuestRuntime</Select>
</PerfCounter>
<PerfCounter>
<Select>PercentHypervisorRuntime</Select>
</PerfCounter>
<PerfCounter>
<Select>PercentTotalRunTime</Select>
</PerfCounter>
<PerfCounter>
<Select>TimeStamp_PerfTime</Select>
</PerfCounter>
<PerfCounter>
<Select>Frequency_PerfTime</Select>
</PerfCounter>
</PerfCounters>
</MgmtObject>
<MgmtObject>
<Namespace>root\cimv2</Namespace>
<From>Win32_Processor </From>
<PerfCounters>
<PerfCounter>
<Select>Name</Select>
</PerfCounter>
<PerfCounter>
<Select>MaxClockSpeed</Select>
</PerfCounter>
<PerfCounter>
<Select>NumberOfCores</Select>
</PerfCounter>
<PerfCounter>
<Select>NumberOfLogicalProcessors</Select>
</PerfCounter>
</PerfCounters>
</MgmtObject>
<MgmtObject>
<Namespace>root\cimv2</Namespace>
<From>Win32_PhysicalMemory</From>
<PerfCounters>
<PerfCounter>
<Select>Capacity</Select>
</PerfCounter>
</PerfCounters>
</MgmtObject>
<MgmtObject>
<Namespace>root\cimv2</Namespace>
<From>Win32_PerfFormattedData_PerfOS_Memory</From>
<PerfCounters>
<PerfCounter>
<Select>AvailableMBytes</Select>
</PerfCounter>
<PerfCounter>
<Select>PagesPersec</Select>
</PerfCounter>
</PerfCounters>
</MgmtObject>
<MgmtObject>
<Namespace>root\cimv2</Namespace>
<From>Win32_PerfFormattedData_HvStats_HyperVHypervisor</From>
<PerfCounters>
<PerfCounter>
<Select>TotalPages</Select>
</PerfCounter>
</PerfCounters>
</MgmtObject>
<MgmtObject SuppressError="true">
<Namespace>root\cimv2</Namespace>
<From>Win32_PerfRawData_ClussvcPerfProvider_ClusterResources</From>
<Where>Name = "Virtual Machine"</Where>
<PerfCounters>
<PerfCounter>
<Select>ResourcesOnline</Select>
</PerfCounter>
</PerfCounters>
</MgmtObject>
<MgmtObject ReturnValue="Single">
<Namespace>root\cimv2</Namespace>
<From>Win32_PerfFormattedData_BalancerStats_HyperVDynamicMemoryBalancer</From>
<PerfCounters>
<PerfCounter>
<Select>AvailableMemory</Select>
</PerfCounter>
</PerfCounters>
</MgmtObject>
<MgmtObject ReturnValue="Single">
<Namespace>root\cimv2</Namespace>
<From>Win32_OperatingSystem</From>
<PerfCounters>
<PerfCounter>
<Select>Version</Select>
</PerfCounter>
<PerfCounter>
<Select>CSDVersion</Select>
</PerfCounter>
<PerfCounter>
<Select>Caption</Select>
</PerfCounter>
</PerfCounters>
</MgmtObject>
<MgmtObject ReturnValue="Single">
<Namespace>root\virtualization\v2</Namespace>
<From>MSVM_ProcessorSettingData</From>
<Where>InstanceId like "%%{0}%%"</Where>
<WhereArgs>
<WhereArg Escape="true">VirtualMachineName</WhereArg>
</WhereArgs>
<PerfCounters>
<PerfCounter>
<Select>VirtualQuantity</Select>
</PerfCounter>
<PerfCounter>
<Select>Reservation</Select>
</PerfCounter>
<PerfCounter>
<Select>Limit</Select>
</PerfCounter>
</PerfCounters>
</MgmtObject>
<MgmtObject ReturnValue="Single">
<Namespace>root\virtualization\v2</Namespace>
<From>MSVM_MemorySettingData</From>
<Where>InstanceId like "%%{0}%%"</Where>
<WhereArgs>
<WhereArg Escape="true">VirtualMachineName</WhereArg>
</WhereArgs>
<PerfCounters>
<PerfCounter>
<Select>Reservation</Select>
</PerfCounter>
<PerfCounter>
<Select>Limit</Select>
</PerfCounter>
<PerfCounter>
<Select>DynamicMemoryEnabled</Select>
</PerfCounter>
<PerfCounter>
<Select>TargetMemoryBuffer</Select>
</PerfCounter>
</PerfCounters>
</MgmtObject>
<MgmtObject ReturnValue="Single" Type="DynamicMemory">
</MgmtObject>
<MgmtObject>
<Namespace>root\cimv2</Namespace>
<From>Win32_PerfRawData_VmmsVirtualMachineStats_HyperVVirtualMachineHealthSummary</From>
<PerfCounters>
<PerfCounter>
<Select>HealthCritical</Select>
</PerfCounter>
<PerfCounter>
<Select>HealthOk</Select>
</PerfCounter>
</PerfCounters>
</MgmtObject>
</MgmtObjects>
</Monitor>

Просмотреть файл

@ -0,0 +1,41 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace EnhancedMonitoring.Configuration
{
[XmlRoot("Kvp")]
public class KvpConfiguration
{
[XmlElement("BatchMode")]
public Boolean BatchMode { get; set; }
[XmlElement("WriteInterval")]
public Int32 WriteInterval { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,76 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace EnhancedMonitoring.Configuration
{
[XmlRoot("MgmtObject")]
public class MgmtObjectConfiguration
{
[XmlAttribute("Type")]
public MgmtObjectType Type { get; set; }
[XmlAttribute("SuppressError")]
public Boolean SuppressError { get; set; }
[XmlAttribute("ReturnValue")]
public MgmtObjectReturnValueType ReturnValueType { get; set; }
[XmlElement("Namespace")]
public String Namespace { get; set; }
[XmlElement("From")]
public String From { get; set; }
[XmlElement("As")]
public String As { get; set; }
[XmlElement("Where")]
public String Where { get; set; }
[XmlArray("WhereArgs")]
[XmlArrayItem("WhereArg")]
public WhereArgList WhereArgs { get; set; }
[XmlArray("PerfCounters")]
[XmlArrayItem("PerfCounter")]
public PerfCounterConfigurationList PerfCounters { get; set; }
}
public class WhereArgList : List<WhereArgConfiguration>
{
}
public class PerfCounterConfigurationList : List<PerfCounterConfiguration>
{
}
}

Просмотреть файл

@ -0,0 +1,36 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EnhancedMonitoring.Configuration
{
public enum MgmtObjectReturnValueType
{
Multiple = 0,
Single
}
}

Просмотреть файл

@ -0,0 +1,36 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EnhancedMonitoring.Configuration
{
public enum MgmtObjectType
{
Query = 0,
DynamicMemory = 1,
}
}

Просмотреть файл

@ -0,0 +1,92 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace EnhancedMonitoring.Configuration
{
[XmlRoot("Monitor")]
public class MonitorConfiguration
{
[XmlElement("RefreshRate")]
public Int64 RefreshRate { get; set; }
[XmlElement("Version")]
public String Version { get; set; }
[XmlElement("MaxValueLength")]
public Int32 MaxValueLength { get; set; }
[XmlElement("Kvp")]
public KvpConfiguration Kvp { get; set; }
[XmlElement("LogLevel")]
public String LogLevel { get; set; }
[XmlElement("LogFilePath")]
public String LogFilePath { get; set; }
[XmlElement("MaxLogRetain")]
public Int32 MaxLogRetention { get; set; }
[XmlElement("LogFileSize")]
public Int64 LogFileSize { get; set; }
public Double EventLogInterval { get; set; }
[XmlElement("DataItemKeyPrefix")]
public string DataItemKeyPrefix { get; set; }
[XmlElement("SupportedVMDetector")]
public SupportedVMDetectorConfiguration SupportedVMDetector { get; set; }
[XmlArray("MgmtObjects")]
[XmlArrayItem("MgmtObject")]
public MgmtObjectConfigurationList MgmtObjects { get; set; }
public static MonitorConfiguration Load(String path)
{
XmlSerializer serializer = new XmlSerializer(typeof(MonitorConfiguration));
using(FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
{
var conf = serializer.Deserialize(fs);
return (MonitorConfiguration)conf;
}
}
}
public class VirtualMachineList : List<String>
{
}
public class MgmtObjectConfigurationList : List<MgmtObjectConfiguration>
{
}
}

Просмотреть файл

@ -0,0 +1,43 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace EnhancedMonitoring.Configuration
{
[XmlRoot("Monitor")]
public class PerfCounterConfiguration
{
[XmlElement("As")]
public String As { get; set; }
[XmlElement("Select")]
public String Select { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,57 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace EnhancedMonitoring.Configuration
{
[XmlRoot("SupportedVMDetector")]
public class SupportedVMDetectorConfiguration
{
[XmlElement("GuestDataItemKey")]
public String GuestDataItemKey { get; set; }
[XmlArray("VirtualMachineProperties")]
[XmlArrayItem("VirtualMachineProperties")]
public VirtualMachineProperties VirtualMachineProperties { get; set; }
}
public class VirtualMachineProperties : List<VirtualMachineProperty>
{
}
[XmlRoot("VirtualMachineProperty")]
public class VirtualMachineProperty
{
[XmlElement("Select")]
public String Select { get; set; }
[XmlElement("As")]
public String As { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,43 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace EnhancedMonitoring.Configuration
{
[XmlRoot("Monitor")]
public class WhereArgConfiguration
{
[XmlAttribute("Escape")]
public Boolean Escape { get; set; }
[XmlText]
public String Name { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,111 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using EnhancedMonitoring.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;
namespace EnhancedMonitoring.DataCollector
{
public class DynamicMemoryMgmtObject : MgmtObject
{
public const String WMI_Namespace = @"root\virtualization\v2";
public const String WMI_Class_Msvm_ComputerSystem = @"Msvm_ComputerSystem";
public const String WMI_Class_Msvm_VirtualSystemManagementService = @"Msvm_VirtualSystemManagementService";
public const String WMI_Class_Msvm_VirtualSystemSettingData = @"Msvm_VirtualSystemSettingData";
public const String WMI_Method_GetSummaryInformation = @"GetSummaryInformation";
public const UInt32 RequestedInformation_MemoryUsage = 103;
public const String KeyName_MemoryUsage = "MemoryUsage";
public const UInt32 RequestedInformation_MemoryAvailable = 112;
public const String KeyName_MemoryAvailable = "MemoryAvailable";
public const UInt32 RequestedInformation_AvaiableMemoryBuffer = 113;
public const String KeyName_AvailableMemoryBuffer = "AvailableMemoryBuffer";
public DynamicMemoryMgmtObject(MgmtObjectConfiguration conf) : base(conf)
{
}
public override Object CollectData(IDictionary<String, Object> args)
{
using (var vmMgmt = WMIHelper.GetFirstInstance(WMI_Namespace, WMI_Class_Msvm_VirtualSystemManagementService))
using (var vm = WMIHelper.QueryFirstInstacne(WMI_Namespace, WMI_Class_Msvm_ComputerSystem,
String.Format("Name='{0}'", args["VirtualMachineName"])))
using (var vmSettings = vm.GetRelated(WMI_Class_Msvm_VirtualSystemSettingData))
using (var inParams = vmMgmt.GetMethodParameters(WMI_Method_GetSummaryInformation))
{
String[] settingDataPath = new String[vmSettings.Count];
int i = 0;
foreach (ManagementObject vmSetting in vmSettings)
{
settingDataPath[i++] = vmSetting.Path.Path;
break;
}
var data = new Dictionary<String, Object>()
{
{KeyName_MemoryUsage, null},
{KeyName_MemoryAvailable, null},
{KeyName_AvailableMemoryBuffer, null},
};
if (settingDataPath.Length != 0)
{
inParams["SettingData"] = settingDataPath;
inParams["RequestedInformation"] = new UInt32[]
{
RequestedInformation_MemoryUsage,
RequestedInformation_MemoryAvailable,
RequestedInformation_AvaiableMemoryBuffer
};
var outParams = vmMgmt.InvokeMethod(WMI_Method_GetSummaryInformation, inParams, null);
if ((UInt32)outParams["ReturnValue"] == 0)//Completed
{
var summaryInfoList = (ManagementBaseObject[])outParams["SummaryInformation"];
var summaryInfo = summaryInfoList.FirstOrDefault();
data[KeyName_MemoryUsage] = summaryInfo[KeyName_MemoryUsage];
data[KeyName_MemoryAvailable] = summaryInfo[KeyName_MemoryAvailable];
data[KeyName_AvailableMemoryBuffer] = summaryInfo[KeyName_AvailableMemoryBuffer];
}
else
{
throw new ManagementException(String.Format("Method {0} returns error:{1}", WMI_Method_GetSummaryInformation,
(UInt32)outParams["ReturnValue"]));
}
}
return data;
}
}
public override String KeyName
{
get
{
return this.conf.As ?? "DynamicMemory";
}
}
}
}

Просмотреть файл

@ -0,0 +1,69 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using EnhancedMonitoring.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading.Tasks;
namespace EnhancedMonitoring.DataCollector
{
public abstract class MgmtObject
{
public static MgmtObject CreateInstance(MgmtObjectConfiguration conf)
{
if(conf == null)
{
throw new ArgumentNullException("conf");
}
if(conf.Type == MgmtObjectType.DynamicMemory)
{
return new DynamicMemoryMgmtObject(conf);
}
return new QueryMgmtObject(conf);
}
protected MgmtObjectConfiguration conf;
protected MgmtObject(MgmtObjectConfiguration conf)
{
this.conf = conf;
}
public abstract Object CollectData(IDictionary<String, Object> args);
public abstract String KeyName { get; }
public bool SuppressError
{
get
{
return this.conf.SuppressError;
}
}
}
}

Просмотреть файл

@ -0,0 +1,168 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using EnhancedMonitoring.Configuration;
using EnhancedMonitoring.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading.Tasks;
namespace EnhancedMonitoring.DataCollector
{
public class QueryMgmtObject : MgmtObject
{
private String[] selectedProperties;
internal QueryMgmtObject(MgmtObjectConfiguration conf) : base(conf)
{
//If specific perf count is given, instead of "*", which means select all,
// we should construct an array of selected properties and parse it through WQL query to improve performance
if (this.conf.PerfCounters != null && this.conf.PerfCounters.Count != 0
&& !this.conf.PerfCounters.Any(counter => !String.IsNullOrEmpty(counter.Select) && counter.Select.Equals("*")))
{
//The properties start with "_" needs to be handled specially.
//Like "_Path", it is not in Properties set, which is by the design of .net's WMI libary.
this.selectedProperties = this.conf.PerfCounters
.Select(counter => counter.Select).Where(p => !String.IsNullOrEmpty(p) && !p.StartsWith("_")).ToArray();
}
}
/// <summary>
///
/// </summary>
/// <param name="args">Named arguments used in "Where" field of WQL query</param>
/// <returns></returns>
public override Object CollectData(IDictionary<String, Object> args)
{
if(args == null)
{
throw new ArgumentNullException("args");
}
if (this.conf.PerfCounters == null)
{
return null;
}
String condition = String.Empty;
condition = NamedArgumentHelper.Resolve(this.conf.Where, this.conf.WhereArgs, args);
if (this.conf.PerfCounters == null || this.conf.PerfCounters.Count == 0)
{
return null;
}
using (var result = WMIHelper.QueryInstacnes(this.conf.Namespace, this.conf.From, condition, this.selectedProperties))
{
var mgmtObjs = result.Cast<ManagementObject>();
if(this.conf.ReturnValueType == MgmtObjectReturnValueType.Single)
{
var mgmtObj = mgmtObjs.FirstOrDefault();
return SelectPerfCounter(mgmtObj, args);
}
else
{
var list = new List<Object>();
foreach (var mgmtObj in mgmtObjs)
{
list.Add(SelectPerfCounter(mgmtObj, args));
}
return list;
}
}
}
private IDictionary<String, Object> SelectPerfCounter(ManagementObject mgmtObj, IDictionary<String, Object> args)
{
IDictionary<String, Object> data = new Dictionary<String, Object>();
this.conf.PerfCounters.ForEach(counter =>
{
if (counter.Select.Equals("*"))
{
foreach (var prop in mgmtObj.Properties)
{
var key = prop.Name;
var val = prop.Value;
if (data.ContainsKey(key))
{
throw new ArgumentException(String.Format("Metric:'{0}' already exists", key));
}
else
{
data.Add(key, val);
}
}
}
else if (counter.Select.Equals("_Path"))
{
var key = counter.As ?? "Path";
var val = mgmtObj.Path;
if (data.ContainsKey(key))
{
throw new ArgumentException(String.Format("Metric:'{0}' already exists", key));
}
else
{
data.Add(key, val);
}
}
else
{
try
{
var property = mgmtObj.Properties[counter.Select.Trim()];
var key = counter.As ?? property.Name;
var val = property.Value;
if (data.ContainsKey(key))
{
throw new ArgumentException(String.Format("Metric:'{0}' already exists", key));
}
else
{
data.Add(key, val);
}
}
catch (ManagementException e)
{
throw new ManagementException(String.Format("Property:'{0}' not found", counter.Select), e);
}
}
});
return data;
}
public override String KeyName
{
get
{
return this.conf.From ?? this.conf.As;
}
}
}
}

Просмотреть файл

@ -0,0 +1,157 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using System.Xml;
using System.Xml.Linq;
namespace EnhancedMonitoring.DataFormat
{
public static class DataFormatHelper
{
public const String ChunkCountKey = "all";
public const String ChunkKey = "data";
public const String TimestampKey = "ts";
public static String ToJSON(IDictionary<String, Object> data)
{
JavaScriptSerializer jsSerializer = new JavaScriptSerializer();
String jsonStr = jsSerializer.Serialize(data);
return jsonStr;
}
public static String ToXml(IDictionary<String, Object> data)
{
return DictionaryToXElement("Data", data).ToString();
}
private static XElement DictionaryToXElement(String nodeName, IDictionary<String, Object> data)
{
nodeName = NormalizeNodeName(nodeName);
XElement node = new XElement(nodeName);
foreach (var entry in data)
{
node.Add(ObjectToXElement(entry.Key, entry.Value));
}
return node;
}
private static XElement ObjectToXElement(String nodeName, Object nodeContent)
{
nodeName = NormalizeNodeName(nodeName);
if (nodeContent is IList)
{
return ListToXElement(nodeName, nodeContent as IList);
}
else if (nodeContent is IDictionary<String, Object>)
{
return DictionaryToXElement(nodeName, nodeContent as IDictionary<String, Object>);
}
else if(nodeContent == null)
{
return new XElement(nodeName, "null");
}
else
{
return new XElement(nodeName, nodeContent);
}
}
private static XElement ListToXElement(String nodeName, IList list)
{
nodeName = NormalizeNodeName(nodeName);
XElement node = new XElement(nodeName);
node.SetAttributeValue("Type", "List");
foreach(var elem in list)
{
node.Add(ObjectToXElement("Item", elem));
}
return node;
}
private static string NormalizeNodeName(string nodeName)
{
if (String.IsNullOrEmpty(nodeName))
{
throw new ArgumentException("Node name can't be null or empty.");
}
return nodeName.Trim().Replace(' ', '_');
}
public static String Base64Encode(String str)
{
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(str);
String encoded = System.Convert.ToBase64String(plainTextBytes);
return encoded;
}
public static IList<String> PackString(String str, int blockLength)
{
var packed = new List<String>();
var textBytes = System.Text.Encoding.UTF8.GetBytes(str);
int i = 0;
while (i < textBytes.Length)
{
packed.Add(System.Text.Encoding.UTF8.GetString(textBytes, i, Math.Min(blockLength, textBytes.Length - i)));
i += blockLength;
}
return packed;
}
public static IDictionary<String, Object> ToChunk(String keyPrefix, IList<String> dataChunks,
Func<Dictionary<String, Object>, String> baseFormater)
{
var packedData = new Dictionary<String, Object>();
var timestamp = GetCurrentTime();
for (int i = 0; i < dataChunks.Count; i++)
{
var dataChunk = new Dictionary<String, Object>();
dataChunk.Add(TimestampKey, timestamp);
dataChunk.Add(ChunkCountKey, dataChunks.Count);
dataChunk.Add(ChunkKey, dataChunks[i]);
packedData.Add(String.Format("{0}{1}", keyPrefix, i), baseFormater(dataChunk));
}
return packedData;
}
public static double GetCurrentTime()
{
//To UNIX like timestamp. Milliseconds since 1970/1/1 00:00:00 UTC
return DateTime.UtcNow
.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc))
.TotalMilliseconds;
}
}
}

Просмотреть файл

@ -0,0 +1,51 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EnhancedMonitoring.DataFormat
{
public class XmlDataFormatter
{
protected const Int32 DEFAULT_VALUE_LENGTH = 800;
private Configuration.MonitorConfiguration conf;
public XmlDataFormatter(Configuration.MonitorConfiguration monitorConfiguration)
{
this.conf = monitorConfiguration;
}
public IDictionary<String, Object> ToXml(IDictionary<String, Object> data)
{
var dataStr = DataFormatHelper.ToXml(data);
dataStr = DataFormatHelper.Base64Encode(dataStr);
var dataChunks = DataFormatHelper.PackString(dataStr, this.conf.MaxValueLength <= 0 ? DEFAULT_VALUE_LENGTH : this.conf.MaxValueLength);
var packedData = DataFormatHelper.ToChunk(this.conf.DataItemKeyPrefix, dataChunks, DataFormatHelper.ToXml);
return packedData;
}
}
}

Просмотреть файл

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7EACC378-2947-4F2E-AB0F-EB57BE7D3680}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>EnhancedMonitoring</RootNamespace>
<AssemblyName>EnhancedMonitoring</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugAndRelease|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\DebugAndRelease\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugAndRelease|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\DebugAndRelease\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data.Linq" />
<Reference Include="System.Management" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.XML" />
<Reference Include="System.Xml.Linq" />
</ItemGroup>
<ItemGroup>
<Compile Include="Configuration\KvpConfiguration.cs" />
<Compile Include="Configuration\MgmtObjectReturnValueType.cs" />
<Compile Include="Configuration\PerfCounterConfiguration.cs" />
<Compile Include="Configuration\SupportedVMDetectorConfiguration.cs" />
<Compile Include="DataCollector\QueryMgmtObject.cs" />
<Compile Include="DataCollector\DynamicMemoryMgmtObject.cs" />
<Compile Include="Configuration\MgmtObjectType.cs" />
<Compile Include="DataFormat\DataFormatHelper.cs" />
<Compile Include="DataFormat\XmlDataFormatter.cs" />
<Compile Include="Logging\EventLogWriter.cs" />
<Compile Include="Logging\FileLogWriter.cs" />
<Compile Include="Logging\Logger.cs" />
<Compile Include="KeyValuePairWriter.cs" />
<Compile Include="Logging\LogLevel.cs" />
<Compile Include="Logging\LogWriter.cs" />
<Compile Include="MonitoringTask.cs" />
<Compile Include="NamedArgumentHelper.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Configuration\MonitorConfiguration.cs" />
<Compile Include="DataCollector\MgmtObject.cs" />
<Compile Include="Configuration\MgmtObjectConfiguration.cs" />
<Compile Include="SupportedVMDetector.cs" />
<Compile Include="Configuration\WhereArgConfiguration.cs" />
<Compile Include="WMIHelper.cs" />
<Compile Include="WMIQueryHelper.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Configuration\EnhancedMonitoringProviderConfig.xml">
<SubType>Designer</SubType>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Просмотреть файл

@ -0,0 +1,166 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using EnhancedMonitoring.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading.Tasks;
namespace EnhancedMonitoring
{
public class KeyValuePairWriter : IDisposable
{
protected const String WMI_Namespace = @"root\virtualization\v2";
protected const String WMI_Class_Msvm_ComputerSystem = @"Msvm_ComputerSystem";
protected const String WMI_Class_Msvm_VirtualSystemManagementService = @"Msvm_VirtualSystemManagementService";
protected const String WMI_Class_Msvm_KvpExchangeDataItem = @"Msvm_KvpExchangeDataItem";
protected const Int32 DEFAULT_WRITE_INTERVAL = 100;
public static KeyValuePairWriter CreateInstance(KvpConfiguration conf)
{
return new KeyValuePairWriter(conf);
}
private bool batchMode = false;
private Int32 writeInterval = DEFAULT_WRITE_INTERVAL;
protected KeyValuePairWriter(KvpConfiguration conf)
{
if(conf != null)
{
this.batchMode = conf.BatchMode;
this.writeInterval = conf.WriteInterval <= 0 ? DEFAULT_WRITE_INTERVAL : conf.WriteInterval;
}
}
public void Remove(IDictionary<String, Object> args, IDictionary<String, Object> data)
{
InvokeKvpOperation(args, data, "RemoveKvpItems");
}
public void Write(IDictionary<String, Object> args, IDictionary<String, Object> data)
{
InvokeKvpOperation(args, data, "AddKvpItems");
}
protected void InvokeKvpOperation(IDictionary<String, Object> args, IDictionary<String, Object> data, String operationName)
{
if (args == null)
{
throw new ArgumentNullException("args");
}
if (data == null)
{
throw new ArgumentNullException("data");
}
if (data.Count() == 0)
{
return;
}
var kvpItems = ToKvpItems(data);
using (var vmMgmt = WMIHelper.GetFirstInstance(WMI_Namespace, WMI_Class_Msvm_VirtualSystemManagementService))
using (var vm = WMIHelper.QueryFirstInstacne(WMI_Namespace, WMI_Class_Msvm_ComputerSystem, String.Format("Name='{0}'", args["VirtualMachineName"])))
{
if(batchMode)
{
InvokeKvpOperation(vmMgmt, vm, operationName, kvpItems);
}
else
{
foreach (var kvpItem in kvpItems)
{
InvokeKvpOperation(vmMgmt, vm, operationName, new String[] { kvpItem });
}
}
}
}
protected void InvokeKvpOperation(ManagementObject vmMgmt, ManagementObject vm, String operationName, String[] kvpItems)
{
using (var inParams = vmMgmt.GetMethodParameters(operationName))
{
inParams["DataItems"] = kvpItems;
inParams["TargetSystem"] = vm;
using (var outParams = vmMgmt.InvokeMethod(operationName, inParams, null))
{
//Delay a small mount of time to avoid overwhelm the KVP VSC in the guest.
Task.Delay(this.writeInterval);
WMIHelper.WaitForAsyncJob(outParams, WMI_Namespace);
}
}
}
protected static String ToKvpItem(KeyValuePair<String, Object> kvp)
{
using (var kvpItem = WMIHelper.CreateInstance(WMI_Namespace, WMI_Class_Msvm_KvpExchangeDataItem))
{
kvpItem["Name"] = kvp.Key;
kvpItem["Data"] = kvp.Value;
kvpItem["Source"] = 0;
return ((ManagementBaseObject)kvpItem).GetText(TextFormat.CimDtd20);
}
}
protected static String[] ToKvpItems(IDictionary<String, Object> data)
{
var dataItems = data.Select((kvp) =>
{
return ToKvpItem(kvp);
}).ToArray();
return dataItems;
}
#region IDisposable
bool disposed = false;
public void Dispose()
{
// Dispose of unmanaged resources.
Dispose(true);
// Suppress finalization.
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
}
disposed = true;
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,89 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EnhancedMonitoring.Logging
{
public class EventLogWriter : LogWriter
{
public const String LogName = "Enhanced Monitoring";
public const String Source = "Enhanced Monitoring Provider Service";
public const String EventLogMsgFormat = "There are {0} error(s), {1} warning(s) during the last {2} minute(s). "
+ "For more information please view the log file, \"{3}\".";
public const double DefaultLogInterval = 60;
private int warningCount;
private int errorCount;
private DateTime lastFlush = DateTime.Now;
private double flushIntervalInMinutes;
private String logFilePath;
public EventLogWriter(Configuration.MonitorConfiguration conf)
{
this.logFilePath = conf.LogFilePath;
this.flushIntervalInMinutes = conf.EventLogInterval <= 0 ? DefaultLogInterval : conf.EventLogInterval;
}
public void Write(LogLevel level, String msg)
{
switch(level)
{
case LogLevel.Warning:
warningCount++;
break;
case LogLevel.Error:
errorCount++;
break;
default:
break;
}
if(errorCount > 0 || warningCount > 0)
{
DateTime now = DateTime.Now;
if (now.Subtract(this.lastFlush).TotalMinutes > this.flushIntervalInMinutes)
{
WriteEventLog();
this.lastFlush = now;
errorCount = 0;
warningCount = 0;
}
}
}
protected virtual void WriteEventLog()
{
String msg = String.Format(EventLogMsgFormat, errorCount, warningCount,
this.flushIntervalInMinutes, this.logFilePath);
using (EventLog log = new EventLog(EventLogWriter.LogName))
{
log.Source = EventLogWriter.Source;
log.WriteEntry(msg, this.errorCount > 0 ? EventLogEntryType.Error : EventLogEntryType.Warning);
}
}
}
}

Просмотреть файл

@ -0,0 +1,103 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace EnhancedMonitoring.Logging
{
public class FileLogWriter : LogWriter
{
public const Int64 DefaultLogFileSize = 4 * 1024 * 1024;
public const Int32 DefaultLogRetention = 10;
private String filePath;
private Int64 logFileSize;
private Int32 maxLogRetention;
private Object writeLock = new Object();
public FileLogWriter(Configuration.MonitorConfiguration conf)
{
this.filePath = conf.LogFilePath;
this.logFileSize = conf.LogFileSize <= 0 ? DefaultLogFileSize : conf.LogFileSize;
this.maxLogRetention = conf.MaxLogRetention <= 0 ? DefaultLogRetention : conf.MaxLogRetention;
Directory.CreateDirectory(Path.GetDirectoryName(this.filePath));
}
public void Write(LogLevel level, String msg)
{
lock(writeLock)
{
FileInfo file = new FileInfo(this.filePath);
if (file.Exists && file.Length > this.logFileSize)
{
RotateLogFile();
}
File.AppendAllLines(this.filePath, new String[] { msg }, Encoding.UTF8);
}
}
/// <summary>
///
/// Rotate the old log to another file. The rule is:
/// 1. log -> log.0
/// 2. log.$(i) -> log.$(i + 1)
/// 3. IF i + 1 == LogRetention: delete log.$(i)
///
/// </summary>
protected void RotateLogFile()
{
int index = 0;
String rotateFilePath = GetRotateFilePath(index);
while(File.Exists(rotateFilePath))
{
//Reaches retention limit, delete the oldest log
if (index == this.maxLogRetention - 1)
{
File.Delete(rotateFilePath);
break;
}
index++;
rotateFilePath = GetRotateFilePath(index);
}
for(int i = index; i > 0; i--)
{
String src = GetRotateFilePath(i - 1);
String dest = GetRotateFilePath(i);
File.Move(src, dest);
}
rotateFilePath = String.Format("{0}.{1}", this.filePath, 0);
File.Move(this.filePath, rotateFilePath);
}
private String GetRotateFilePath(int index)
{
return String.Format("{0}.{1}", this.filePath, index);
}
}
}

Просмотреть файл

@ -0,0 +1,38 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EnhancedMonitoring.Logging
{
public enum LogLevel
{
Verbose = -1,
Info = 0,
Warning = 1,
Error = 2
}
}

Просмотреть файл

@ -0,0 +1,35 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EnhancedMonitoring.Logging
{
public interface LogWriter
{
void Write(LogLevel level, String msg);
}
}

Просмотреть файл

@ -0,0 +1,153 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using EnhancedMonitoring.Configuration;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EnhancedMonitoring.Logging
{
public class Logger
{
private static Object instanceLock = new Object();
private static Logger instance = null;
private const String DateFormat = "yyyy-MM-dd hh:mm:ss.fff";
public static Logger Instance
{
get
{
lock(instanceLock)
{
if (instance == null)
{
throw new NullReferenceException("Log hasn't been initialized");
}
}
return instance;
}
}
public static void Init(MonitorConfiguration conf)
{
Init(conf, new LogWriter[]
{
new FileLogWriter(conf),
new EventLogWriter(conf)
});
}
public static void Init(MonitorConfiguration conf, IList<LogWriter> writers)
{
lock (instanceLock)
{
if (instance == null)
{
instance = new Logger(conf);
instance.AddWriters(writers);
}
}
}
public static void Verbose(String format, params Object[] args)
{
Logger.Instance.Log(LogLevel.Verbose, format, args);
}
public static void Verbose(Exception e)
{
Verbose(ExceptionToString(e));
}
public static void Info(String format, params Object[] args)
{
Logger.Instance.Log(LogLevel.Info, format, args);
}
public static void Info(Exception e)
{
Info(ExceptionToString(e));
}
public static void Warn(String format, params Object[] args)
{
Logger.Instance.Log(LogLevel.Warning, format, args);
}
public static void Warn(Exception e)
{
Warn(ExceptionToString(e));
}
public static void Error(String format, params Object[] args)
{
Logger.Instance.Log(LogLevel.Error, format, args);
}
public static void Error(Exception e)
{
Error(ExceptionToString(e));
}
private static String ExceptionToString(Exception e)
{
return String.Format("{0}\n{1}", e, e.StackTrace);
}
private LogLevel logLevel = LogLevel.Info;
private List<LogWriter> writers = new List<LogWriter>();
private Logger(MonitorConfiguration conf)
{
Enum.TryParse<LogLevel>(conf.LogLevel, out this.logLevel);
}
public void AddWriters(IList<LogWriter> writers)
{
this.writers.AddRange(writers);
}
public void Log(LogLevel level, String format, params Object[] args)
{
if(level < logLevel)
{
return;
}
String logMsg = format;
if(args != null && args.Count() != 0)
{
logMsg = String.Format(format, args);
}
String date = DateTime.Now.ToString(DateFormat);
String msg = String.Format("{0} {1}\t{2}", date, level.ToString().ToUpper(), logMsg);
foreach(var writer in writers)
{
writer.Write(level, msg);
}
}
}
}

Просмотреть файл

@ -0,0 +1,201 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using EnhancedMonitoring.Configuration;
using EnhancedMonitoring.DataFormat;
using EnhancedMonitoring.DataCollector;
using EnhancedMonitoring.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading.Tasks;
namespace EnhancedMonitoring
{
public class MonitoringTask
{
public const String VersionKey = "Version";
public static MonitoringTask CreateInstance(MonitorConfiguration conf)
{
if (conf == null)
{
throw new ArgumentNullException("conf");
}
var instance = new MonitoringTask(conf);
return instance;
}
protected List<MgmtObject> mgmtObjects = new List<MgmtObject>();
protected MonitorConfiguration conf;
protected MonitoringTask(MonitorConfiguration conf)
{
this.conf = conf;
foreach (var mgmtObjConf in conf.MgmtObjects)
{
mgmtObjects.Add(MgmtObject.CreateInstance(mgmtObjConf));
}
}
public void Run()
{
var vms = GetSupportedVM();
if (vms == null || vms.Count == 0)
{
Logger.Info("No supported VM found.");
return;
}
Logger.Info("Detected {0} supported VMs", vms.Count);
List<Task> tasks = new List<Task>();
foreach (var vm in vms)
{
tasks.Add(Task.Run(() =>
{
var data = CollectDataForVM(vm);
var packedData = new XmlDataFormatter(this.conf).ToXml(data);
WriteKVPToVM(vm, packedData);
}));
}
try
{
Task.WaitAll(tasks.ToArray());
}
catch (AggregateException e)
{
foreach (var inner in e.InnerExceptions)
{
Logger.Error(inner);
throw inner;
}
}
}
private void WriteKVPToVM(IDictionary<string, object> vm, IDictionary<string, object> packedData)
{
Logger.Info(String.Format("Write {0} kvps to VM {1}", packedData.Count, vm["VirtualMachineElementName"]));
using (KeyValuePairWriter writer = KeyValuePairWriter.CreateInstance(this.conf.Kvp))
{
try
{
writer.Remove(vm, packedData);
writer.Write(vm, packedData);
}
catch (InvalidOperationException e)
{
Logger.Info("Couldn't write KVP to VM {0}. The VM has been shutdown or removed.",
vm["VirtualMachineElementName"]);
Logger.Verbose(e);
}
catch (ManagementException e)
{
Logger.Error(e);
}
catch (NotImplementedException e)
{
Logger.Info("Couldn't write KVP to VM {0}. The VM has been shutdown or removed.",
vm["VirtualMachineElementName"]);
Logger.Verbose(e);
}
}
}
private Dictionary<string, object> CollectDataForVM(IDictionary<string, object> vm)
{
var data = new Dictionary<String, Object>();
//Add pre-defined argument, VirtualMachine
var args = new Dictionary<String, Object>(vm);
foreach (var mgmtObj in this.mgmtObjects)
{
data.Add(mgmtObj.KeyName, null);
try
{
data[mgmtObj.KeyName] = mgmtObj.CollectData(args);
}
catch (InvalidOperationException e)
{
if (!mgmtObj.SuppressError)
{
Logger.Verbose(e);
}
}
catch (ManagementException e)
{
if (!mgmtObj.SuppressError)
{
Logger.Error(e);
}
}
catch (ArgumentException e)
{
if (!mgmtObj.SuppressError)
{
Logger.Error(e);
}
}
catch (NotImplementedException e)
{
if (!mgmtObj.SuppressError)
{
Logger.Verbose(e);
}
}
}
data.Add(VersionKey, this.conf.Version);
return data;
}
private IList<IDictionary<String, Object>> GetSupportedVM()
{
IList<IDictionary<String, Object>> vms = null;
try
{
vms = SupportedVMDetector.CreateInstance(this.conf.SupportedVMDetector).GetSupportedVM();
}
catch (InvalidOperationException e)
{
Logger.Verbose(e);
}
catch (ManagementException e)
{
Logger.Error(e);
}
catch (NotImplementedException e)
{
Logger.Verbose(e);
}
return vms;
}
}
}

Просмотреть файл

@ -0,0 +1,87 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using EnhancedMonitoring.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EnhancedMonitoring
{
public static class NamedArgumentHelper
{
public static String Resolve(String str, IList<WhereArgConfiguration> whereArgs, IDictionary<String, Object> args)
{
if (String.IsNullOrEmpty(str))
{
return str;
}
if(whereArgs == null || whereArgs.Count == 0)
{
try
{
return String.Format(str, new Object[0]);
}
catch(FormatException e)
{
throw new ArgumentException(String.Format("format={0}, args=NullOrEmpty", str), e);
}
}
if(args == null && whereArgs != null && whereArgs.Count > 0)
{
throw new ArgumentException(String.Format("Can't resolve argument: format={0}, args={1}", str, String.Join(",", whereArgs.Select(a => a.Name))));
}
Object[] argsVal = new Object[args.Count];
for (int i = 0; i < whereArgs.Count; i++)
{
var whereArg = whereArgs[i];
if (args.ContainsKey(whereArg.Name))
{
argsVal[i] = args[whereArg.Name];
if(whereArg.Escape && argsVal[i] != null)
{
argsVal[i] = WMIQueryHelper.EscapeLikeCondition(argsVal[i].ToString());
}
}
else
{
throw new ArgumentException(String.Format("Can't resolve argument format={0}, args={1}", str, whereArgs[i].Name));
}
}
try
{
return String.Format(str, argsVal);
}
catch(FormatException e)
{
throw new ArgumentException(String.Format("Can't resolve argument: format={0}, args={1}", str, String.Join(",", whereArgs)), e);
}
}
}
}

Просмотреть файл

@ -0,0 +1,23 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//


Просмотреть файл

@ -0,0 +1,98 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using EnhancedMonitoring.Configuration;
using EnhancedMonitoring.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace EnhancedMonitoring
{
public class SupportedVMDetector
{
protected const String WMI_Namespace = @"root\virtualization\v2";
protected const String WMI_Class_Msvm_ComputerSystem = @"Msvm_ComputerSystem";
protected const String WMI_Class_Msvm_KvpExchangeComponent = @"Msvm_KvpExchangeComponent";
public static SupportedVMDetector CreateInstance(SupportedVMDetectorConfiguration conf)
{
return new SupportedVMDetector(conf);
}
private String SupportedVMKey;
public SupportedVMDetector(SupportedVMDetectorConfiguration conf)
{
this.SupportedVMKey = conf.GuestDataItemKey;
}
public IList<IDictionary<String, Object>> GetSupportedVM()
{
using (var vms = WMIHelper.QueryInstacnes(WMI_Namespace, WMI_Class_Msvm_ComputerSystem, "EnabledState = 2 and Caption='Virtual Machine'"))
{
var tasks = new List<Task<IDictionary<String, Object>>>();
foreach(var vm in vms.Cast<ManagementObject>())
{
tasks.Add(Task.Run<IDictionary<String, Object>>(() =>
{
var objs = vm.GetRelated(WMI_Class_Msvm_KvpExchangeComponent);
foreach (var obj in objs)
{
var kvps = obj.Properties["GuestExchangeItems"].Value as String[];
if (kvps.Any(kvp => kvp.IndexOf(this.SupportedVMKey) >= 0))
{
var vmdata = new Dictionary<String, Object>();
vmdata.Add("VirtualMachineName", vm.Properties["Name"].Value);
vmdata.Add("VirtualMachineElementName", vm.Properties["ElementName"].Value);
vmdata.Add("VirtualMachinePath", vm.Path);
vmdata.Add("GuestExchangeItems", kvps);
return vmdata;
}
}
return null;
}));
}
try
{
var task = Task.WhenAll<IDictionary<String, Object>>(tasks);
task.Wait();
return task.Result.Where(x => x != null).ToList();
}
catch(AggregateException e)
{
foreach(var inner in e.InnerExceptions)
{
Logger.Error(inner);
throw inner;
}
throw;
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,199 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading.Tasks;
namespace EnhancedMonitoring
{
public static class WMIHelper
{
public static ManagementObject CreateInstance(String scope, String className)
{
if(String.IsNullOrEmpty(scope))
{
throw new ArgumentNullException("scope");
}
if (String.IsNullOrEmpty(className))
{
throw new ArgumentNullException("className");
}
ManagementClass clazz = new ManagementClass(scope, className, null);
return clazz.CreateInstance();
}
public static ManagementObjectCollection GetInstances(String scope, String className)
{
if (String.IsNullOrEmpty(scope))
{
throw new ArgumentNullException("scope");
}
if (String.IsNullOrEmpty(className))
{
throw new ArgumentNullException("className");
}
ManagementClass clazz = new ManagementClass(scope, className, null);
return clazz.GetInstances();
}
public static ManagementObject GetFirstInstance(String scope, String className)
{
if (String.IsNullOrEmpty(scope))
{
throw new ArgumentNullException("scope");
}
if (String.IsNullOrEmpty(className))
{
throw new ArgumentNullException("className");
}
return GetInstances(scope, className).Cast<ManagementObject>().FirstOrDefault();
}
public static ManagementObjectCollection QueryInstacnes(String scope, String className, String condition)
{
if (String.IsNullOrEmpty(scope))
{
throw new ArgumentNullException("scope");
}
if (String.IsNullOrEmpty(className))
{
throw new ArgumentNullException("className");
}
return QueryInstacnes(scope, className, condition, null);
}
public static ManagementObjectCollection QueryInstacnes(String scope, String className, String condition, String[] selectedProperties)
{
if (String.IsNullOrEmpty(scope))
{
throw new ArgumentNullException("scope");
}
if (String.IsNullOrEmpty(className))
{
throw new ArgumentNullException("className");
}
var query = new SelectQuery(className, condition);
if(selectedProperties != null)
{
var collection = new System.Collections.Specialized.StringCollection();
collection.AddRange(selectedProperties);
query.SelectedProperties = collection;
}
using (var search = new ManagementObjectSearcher(new ManagementScope(scope), query))
{
try
{
var result = search.Get();
if (result.Count == 0)
{
throw new NotImplementedException(String.Format("Can't find wmi object: namespace='{0}', class='{1}', condition='{2}'",
scope, className, condition));
}
return result;
}
catch (ManagementException e)
{
throw new ManagementException(String.Format("Wmi query error: namespace='{0}', class='{1}', condition='{2}'\n",
scope, className, condition), e);
}
}
}
public static ManagementObject QueryFirstInstacne(String scope, String className, String condition)
{
if (String.IsNullOrEmpty(scope))
{
throw new ArgumentNullException("scope");
}
if (String.IsNullOrEmpty(className))
{
throw new ArgumentNullException("className");
}
return QueryFirstInstacne(scope, className, condition, null);
}
public static ManagementObject QueryFirstInstacne(String scope, String className, String condition, String[] selectedProperties)
{
if (String.IsNullOrEmpty(scope))
{
throw new ArgumentNullException("scope");
}
if (String.IsNullOrEmpty(className))
{
throw new ArgumentNullException("className");
}
return QueryInstacnes(scope, className, condition, selectedProperties).Cast<ManagementObject>().FirstOrDefault();
}
static class JobState
{
public const UInt16 New = 2;
public const UInt16 Starting = 3;
public const UInt16 Running = 4;
public const UInt16 Suspended = 5;
public const UInt16 ShuttingDown = 6;
public const UInt16 Completed = 7;
public const UInt16 Terminated = 8;
public const UInt16 Killed = 9;
public const UInt16 Exception = 10;
public const UInt16 Service = 11;
}
public static void WaitForAsyncJob(ManagementBaseObject outParams, String scope)
{
if (outParams == null)
{
throw new ArgumentNullException("outParams");
}
if (String.IsNullOrEmpty(scope))
{
throw new ArgumentNullException("scope");
}
//Retrieve msvc_StorageJob path. This is a full wmi path
string JobPath = (string)outParams["Job"];
ManagementObject Job = new ManagementObject(new ManagementScope(scope), new ManagementPath(JobPath), null);
//Try to get storage job information
Job.Get();
while ((UInt16)Job["JobState"] == JobState.Starting
|| (UInt16)Job["JobState"] == JobState.Running)
{
Console.WriteLine("In progress... {0}% completed.", Job["PercentComplete"]);
Task.Delay(1000);
Job.Get();
}
//Figure out if job failed
UInt16 jobState = (UInt16)Job["JobState"];
if (jobState != JobState.Completed)
{
UInt16 jobErrorCode = (UInt16)Job["ErrorCode"];
String jobErrorDescription = (string)Job["ErrorDescription"];
Console.WriteLine("Error Code:{0}", jobErrorCode);
Console.WriteLine("ErrorDescription: {0}", jobErrorDescription);
throw new ManagementException(String.Format("Job didn't complete successfully. Error Code={0}, {1}", jobErrorCode, jobErrorDescription));
}
}
}
}

Просмотреть файл

@ -0,0 +1,47 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EnhancedMonitoring
{
public class WMIQueryHelper
{
public static String EscapeLikeCondition(String condition)
{
if (!String.IsNullOrEmpty(condition))
{
//Need to escape "[", "%", "_"
condition = condition.Replace("[", "[[]");
condition = condition.Replace("%", "[%]");
condition = condition.Replace("_", "[_]");
//No need to escape "]", "^"
}
return condition;
}
}
}

62
src/Service/EnhacedMonitoringProvider.Designer.cs сгенерированный Normal file
Просмотреть файл

@ -0,0 +1,62 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
namespace EnhancedMonitoring.Service
{
partial class EnhacedMonitoring
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
//
// EnhacedMonitoring
//
this.ServiceName = "Enhanced Monitoring Provider Service";
}
#endregion
}
}

Просмотреть файл

@ -0,0 +1,90 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using EnhancedMonitoring.Configuration;
using EnhancedMonitoring.Logging;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace EnhancedMonitoring.Service
{
public partial class EnhacedMonitoring : ServiceBase
{
private const Int64 MIN_REFRESH_RATE = 60; //Default minimal refresh rate is 60 seconds
public EnhacedMonitoring()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
var configFilePath = String.Format(@"{0}\{1}\{2}",
System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData),
"Enhanced Monitoring", "EnhancedMonitoringProviderConfig.xml");
var defaultLogPath = String.Format(@"{0}\{1}\{2}\{3}",
System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData),
"Enhanced Monitoring", "log", "monitor.log");
MonitorConfiguration conf = MonitorConfiguration.Load(configFilePath);
conf.LogFilePath = conf.LogFilePath ?? defaultLogPath;
Logger.Init(conf);
timer = new Timer(_ => this.RunMonitoringTask(conf), null, 0, Timeout.Infinite);
Logger.Info("Monitoring service started");
}
private Timer timer;
private void RunMonitoringTask(MonitorConfiguration conf)
{
Logger.Info("Start monitoring task");
DateTime start = DateTime.Now;
MonitoringTask task = MonitoringTask.CreateInstance(conf);
task.Run();
Logger.Info("Monitoring task finished");
TimeSpan elapsed = DateTime.Now.Subtract(start);
//Substract elapsed time to get the task running exaclty aliging to refresh rate.
long interval = Math.Max(conf.RefreshRate, MIN_REFRESH_RATE) * 1000;
long timeToWait = interval - (long)elapsed.TotalMilliseconds % interval;
//Trigger next task
timer.Change(timeToWait, Timeout.Infinite);
}
protected override void OnStop()
{
if(this.timer != null)
{
this.timer.Dispose();
}
}
}
}

Просмотреть файл

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>

48
src/Service/Program.cs Normal file
Просмотреть файл

@ -0,0 +1,48 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
namespace EnhancedMonitoring.Service
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new EnhacedMonitoring()
};
ServiceBase.Run(ServicesToRun);
}
}
}

Просмотреть файл

@ -0,0 +1,23 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//


116
src/Service/Service.csproj Normal file
Просмотреть файл

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{ED1F3B96-683F-4D16-B4F9-06765E3697C1}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>EnhancedMonitoringProvider.Service</RootNamespace>
<AssemblyName>EnhancedMonitoringProvider.Service</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugAndRelease|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\DebugAndRelease\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugAndRelease|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\DebugAndRelease\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="EnhacedMonitoringProvider.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="EnhacedMonitoringProvider.Designer.cs">
<DependentUpon>EnhacedMonitoringProvider.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="EnhacedMonitoringProvider.resx">
<DependentUpon>EnhacedMonitoringProvider.cs</DependentUpon>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EnhancedMonitoring\EnhancedMonitoring.csproj">
<Project>{7eacc378-2947-4f2e-ab0f-eb57be7d3680}</Project>
<Name>EnhancedMonitoring</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

31
src/Service/app.config Normal file
Просмотреть файл

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
The MIT License (MIT)
Copyright 2015 Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>

Просмотреть файл

@ -0,0 +1,87 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EnhancedMonitoring.DataFormat;
using System.Collections.Generic;
namespace UnitTest
{
[TestClass]
public class DataPackingHelperTest
{
[TestMethod]
public void TestPackString()
{
{
var rawStr = "aaaa";
var result = DataFormatHelper.PackString(rawStr, 1);
Assert.IsNotNull(result);
Assert.AreEqual(4, result.Count);
}
{
var rawStr = "aaaa";
var result = DataFormatHelper.PackString(rawStr, 3);
Assert.IsNotNull(result);
Assert.AreEqual(2, result.Count);
}
{
var rawStr = "aaaa";
var result = DataFormatHelper.PackString(rawStr, 5);
Assert.IsNotNull(result);
Assert.AreEqual(1, result.Count);
}
}
[TestMethod]
public void TestPackData()
{
var data = new Dictionary<String, Object>()
{
{"MaxClockFrequency", 100000},
{"AvailableMemeory", 1024},
};
foreach (var kvp in data)
{
Console.WriteLine(kvp);
}
var dataStr = DataFormatHelper.ToXml(data);
Console.WriteLine(dataStr);
dataStr = DataFormatHelper.Base64Encode(dataStr);
Console.WriteLine(dataStr);
var dataChunks = DataFormatHelper.PackString(dataStr, 50);
var packedData = DataFormatHelper.ToChunk("Part_", dataChunks, DataFormatHelper.ToXml);
foreach(var kvp in packedData)
{
Console.WriteLine(kvp);
}
Assert.AreEqual(3, packedData.Count);
}
}
}

Просмотреть файл

@ -0,0 +1,70 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EnhancedMonitoring.Configuration;
using EnhancedMonitoring.DataCollector;
using EnhancedMonitoring;
using System.Collections.Generic;
using System.Management;
using System.Linq;
namespace UnitTest
{
/// <summary>
/// Summary description for DynamicMemoryMgmtObjectTest
/// </summary>
[TestClass]
public class DynamicMemoryMgmtObjectTest
{
[TestMethod]
public MgmtObject TestDynamicMemoryMgmtObject()
{
MgmtObjectConfiguration conf = new MgmtObjectConfiguration()
{
Type = MgmtObjectType.DynamicMemory,
};
var mgmtObj = MgmtObject.CreateInstance(conf);
Assert.IsNotNull(mgmtObj);
Assert.IsTrue(mgmtObj is DynamicMemoryMgmtObject);
return mgmtObj;
}
[TestMethod]
public void TestDynamicMemoryMgmtObjectCollectData()
{
var mgmtObj = TestDynamicMemoryMgmtObject();
var vmArgs = new SupportedVMDetectorTest().DetectSupportedVM();
var data = mgmtObj.CollectData(vmArgs);
Assert.IsNotNull(data);
var dynamicMemoryData = (data as Dictionary<String, Object>);
Assert.IsNotNull(dynamicMemoryData);
Assert.IsNotNull(dynamicMemoryData[DynamicMemoryMgmtObject.KeyName_MemoryUsage]);
Assert.IsNotNull(dynamicMemoryData[DynamicMemoryMgmtObject.KeyName_MemoryAvailable]);
Assert.IsNotNull(dynamicMemoryData[DynamicMemoryMgmtObject.KeyName_AvailableMemoryBuffer]);
}
}
}

Просмотреть файл

@ -0,0 +1,102 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Diagnostics;
using EnhancedMonitoring.Logging;
using System.Threading;
using EnhancedMonitoring.Configuration;
namespace UnitTest
{
[TestClass]
public class EventLogTest
{
public void TestCreateEventLogSource()
{
EventLog.CreateEventSource(new EventSourceCreationData(EventLogWriter.Source, EventLogWriter.LogName)
{
MachineName = System.Environment.MachineName
});
}
public void TestRemoveEventLogSource()
{
EventLog.DeleteEventSource(EventLogWriter.Source);
}
//[TestMethod]
public void TestEventLogSource()
{
Assert.IsTrue(EventLog.Exists(EventLogWriter.LogName));
//Assert.IsTrue(EventLog.SourceExists(EventLogWriter.Source));
using (EventLog log = new EventLog())
{
log.Log = EventLogWriter.LogName;
log.Source = EventLogWriter.Source;
log.MachineName = System.Environment.MachineName;
log.WriteEntry("Test", EventLogEntryType.Warning);
}
}
[TestMethod]
public void TestEventLogFlushInterval()
{
var writer = new ShimEventLogWriter(new MonitorConfiguration()
{
EventLogInterval = 100.0 / 60000 //100ms
});
//Try to refresh timestamp for last flush.
//A flush will be triggered if required.
//And the timestamp will be reset to NOW
writer.Write(LogLevel.Error, "");
//Clear flushed flag and write a log record.
writer.Flushed = false;
writer.Write(LogLevel.Info, "");
Assert.IsFalse(writer.Flushed);
//Clear flushed flag and wait for 120ms
writer.Flushed = false;
Thread.Sleep(120);
//Trigger a flush and check the flag.
writer.Write(LogLevel.Info, "");
Assert.IsTrue(writer.Flushed);
}
}
class ShimEventLogWriter:EventLogWriter
{
public ShimEventLogWriter(MonitorConfiguration conf) : base(conf) { }
public bool Flushed { get; set; }
protected override void WriteEventLog()
{
this.Flushed = true;
}
}
}

Просмотреть файл

@ -0,0 +1,109 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using EnhancedMonitoring.DataFormat;
using System.Runtime.Serialization;
namespace UnitTest
{
[TestClass]
public class FormatHelperTest
{
[TestMethod]
public void TestToXml()
{
String expected = System.IO.File.ReadAllText(@"..\..\TestToXmlExpectedOutput.xml");
var data = new Dictionary<String, Object>();
data.Add("Name", "Dictionary(JSON object) to Xml Test");
data.Add("TestCases", new String[]
{
"Case1: String as Field",
"Case2: String Array as Field",
"Case3: Dictionary as Field",
"Case4: Object Array as Field",
"Case5: Null"
});
data.Add("ExpectedBehavior", new Dictionary<String, Object>() {
{"ForAll", "Key name as XElement name "},
{"Case1", "String content as XElement content"},
{"Case2", "Each element becomes a child XElement with name 'Item'"},
{"Case3", "Dictionary becomes a child XElement"},
{"Case4", new String[]
{
"1. Each element in the array is a dictionary",
"2. The 1st dictionary itself contains an array field",
"3. The 2nd dictionary itself contains a dictionary"
}
},
{"Case5", "Output 'null'"}
});
data.Add("ObjectArray", new Dictionary<String, Object>[] {
new Dictionary<String, Object>()
{
{"ArrayObject", new String[]{"Element 1", "Element 1"}}
},
new Dictionary<String, Object>()
{
{
"DictionaryObject", new Dictionary<String, Object>()
{
{"ObjectField", "ObjectValue"}
}
}
},
});
data.Add("HandleNull", null);
var xmlStr = DataFormatHelper.ToXml(data);
Console.WriteLine(xmlStr);
Assert.AreEqual(expected, xmlStr);
}
[TestMethod]
public void TestToXmlNegative()
{
var data = new Dictionary<String, Object>();
data.Add("", null);
try
{
DataFormatHelper.ToXml(data);
}
catch (ArgumentException e)
{
Assert.AreEqual("Node name can't be null or empty.", e.Message);
}
data.Clear();
data.Add("Node Name with Space", "Space will be replaced with _");
var xmlStr = DataFormatHelper.ToXml(data);
String expected =
@"<Data>
<Node_Name_with_Space>Space will be replaced with _</Node_Name_with_Space>
</Data>";
Assert.AreEqual(expected, xmlStr);
}
}
}

104
src/UnitTest/JSONHelper.cs Normal file
Просмотреть файл

@ -0,0 +1,104 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UnitTest
{
class JsonHelper
{
private const string INDENT_STRING = " ";
public static string FormatJson(string str)
{
var indent = 0;
var quoted = false;
var sb = new StringBuilder();
for (var i = 0; i < str.Length; i++)
{
var ch = str[i];
switch (ch)
{
case '{':
case '[':
sb.Append(ch);
if (!quoted)
{
sb.AppendLine();
Enumerable.Range(0, ++indent).ForEach(item => sb.Append(INDENT_STRING));
}
break;
case '}':
case ']':
if (!quoted)
{
sb.AppendLine();
Enumerable.Range(0, --indent).ForEach(item => sb.Append(INDENT_STRING));
}
sb.Append(ch);
break;
case '"':
sb.Append(ch);
bool escaped = false;
var index = i;
while (index > 0 && str[--index] == '\\')
escaped = !escaped;
if (!escaped)
quoted = !quoted;
break;
case ',':
sb.Append(ch);
if (!quoted)
{
sb.AppendLine();
Enumerable.Range(0, indent).ForEach(item => sb.Append(INDENT_STRING));
}
break;
case ':':
sb.Append(ch);
if (!quoted)
sb.Append(" ");
break;
default:
sb.Append(ch);
break;
}
}
return sb.ToString();
}
}
static class Extensions
{
public static void ForEach<T>(this IEnumerable<T> ie, Action<T> action)
{
foreach (var i in ie)
{
action(i);
}
}
}
}

Просмотреть файл

@ -0,0 +1,131 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using EnhancedMonitoring;
using System.Management;
using EnhancedMonitoring.Configuration;
namespace UnitTest
{
[TestClass]
public class KVPWriterTest
{
private const String testKey = "TestKVPWriterKey1";
private const String testKey2 = "TestKVPWriterKey2";
//[TestMethod]
public void TestOverloadKVP()
{
var vm = WMIHelper.QueryFirstInstacne(@"root\virtualization\v2", "Msvm_ComputerSystem ", "enabledstate = 2 and caption = 'Virtual Machine'");
Assert.IsNotNull(vm);
var writer = KeyValuePairWriter.CreateInstance(new KvpConfiguration());
var data = new Dictionary<String, Object>();
var chars = new char[1000];
for(int i = 0; i < chars.Length; i++)
{
chars[i] = 'a';
}
var val = new String(chars);
for (int i = 0; i < 1000; i++ )
{
data.Clear();
for (int j = 0; j < 10; j++)
{
data.Add(String.Format("TestKVP_{0}", j), val);
}
var args = new Dictionary<String, Object>() {
{"VirtualMachinePath", vm.Path.ToString()},
{"VirtualMachineName", vm.Properties["Name"].Value},
};
writer.Remove(args, data);
writer.Write(args, data);
}
vm.Dispose();
}
[TestMethod]
public void TestWriteKVP()
{
var vm = WMIHelper.QueryFirstInstacne(@"root\virtualization\v2", "Msvm_ComputerSystem ", "enabledstate = 2 and caption = 'Virtual Machine'");
Assert.IsNotNull(vm);
var writer = KeyValuePairWriter.CreateInstance(new KvpConfiguration());
var data = new Dictionary<String, Object>();
data.Add(testKey, DateTime.Now.ToString());
data.Add(testKey2, DateTime.Now.ToString());
var args = new Dictionary<String, Object>() {
{"VirtualMachinePath", vm.Path.ToString()},
{"VirtualMachineName", vm.Properties["Name"].Value},
};
writer.Remove(args, data);
writer.Write(args, data);
vm.Dispose();
}
//Uncomment the following line to cleanup kvp
//[TestMethod]
public void CleanupKVP()
{
using (var vm = WMIHelper.QueryFirstInstacne(@"root\virtualization\v2", "Msvm_ComputerSystem ", "enabledstate = 2 and caption = 'Virtual Machine'"))
{
Assert.IsNotNull(vm);
Console.WriteLine("Clean up kvp for: " + vm.Properties["ElementName"].Value);
var writer = KeyValuePairWriter.CreateInstance(new KvpConfiguration());
var NULL = new Object();
var data = new Dictionary<String, Object>();
data.Add(testKey, NULL);
data.Add(testKey2, NULL);
var args = new Dictionary<String, Object>()
{
{"VirtualMachinePath", vm.Path.ToString()},
{"VirtualMachineName", vm.Properties["Name"].Value},
};
writer.Remove(args, data);
data.Clear();
for (int i = 0; i < 50; i++)
{
data.Add("Enhanced_Monitoring_Metric_Data_Item_Part_" + i, NULL);
}
writer.Remove(args, data);
}
}
}
}

111
src/UnitTest/LoggerTest.cs Normal file
Просмотреть файл

@ -0,0 +1,111 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using EnhancedMonitoring.Logging;
using EnhancedMonitoring.Configuration;
using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTest
{
/// <summary>
/// Summary description for LoggerTest
/// </summary>
[TestClass]
public class LoggerTest
{
[TestMethod]
public void TestLog()
{
var conf = new MonitorConfiguration()
{
LogLevel = "Info"
};
var logWriter = new TestLogWriter();
Logger.Init(conf, new LogWriter[] { logWriter });
Logger.Verbose("Trival");
Assert.IsNull(logWriter.Msg);
Logger.Info("Formated information: {0}", "Nothing");
Assert.IsTrue(logWriter.Msg.Contains("Formated information"));
Assert.AreEqual(LogLevel.Info, logWriter.Level);
Console.WriteLine(logWriter.Msg);
try
{
RaiseException();
}
catch(Exception e)
{
Logger.Error(e);
//Check call stack is logged.
Assert.IsTrue(logWriter.Msg.Contains("at UnitTest.LoggerTest.TestLog()"));
Console.WriteLine(logWriter.Msg);
}
}
[TestMethod]
public void TestLogLevelConfigure()
{
var conf = new MonitorConfiguration()
{
LogLevel = "Infoasdfasdf"
};
var logWriter = new TestLogWriter();
Logger.Init(conf, new LogWriter[] { logWriter });
Logger.Info("Test");
Assert.AreEqual(LogLevel.Info, logWriter.Level);
}
[TestMethod]
public void TestZeroLogWriter()
{
var conf = new MonitorConfiguration()
{
LogLevel = "Infoasdfasdf"
};
Logger.Init(conf, new LogWriter[0]);
Logger.Info("Test");
}
private void RaiseException()
{
throw new NotImplementedException();
}
}
class TestLogWriter : LogWriter
{
public LogLevel Level { get; set; }
public String Msg { get; set; }
public void Write(LogLevel level, String msg)
{
this.Level = level;
this.Msg = msg;
}
}
}

127
src/UnitTest/MetricTest.cs Normal file
Просмотреть файл

@ -0,0 +1,127 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EnhancedMonitoring.Configuration;
using EnhancedMonitoring.DataFormat;
using EnhancedMonitoring.DataCollector;
using EnhancedMonitoring;
using System.Collections.Generic;
namespace UnitTest
{
[TestClass]
public class MetricTest
{
[TestMethod]
public void TestMetricJSON()
{
MonitorConfiguration conf = MonitorConfiguration.Load(@"..\..\..\EnhancedMonitoring\Configuration\EnhancedMonitoringProviderConfig.xml");
List<MgmtObject> mgmtObjects = new List<MgmtObject>();
foreach (var mgmtObjConf in conf.MgmtObjects)
{
mgmtObjects.Add(MgmtObject.CreateInstance(mgmtObjConf));
}
Assert.AreNotEqual(0, mgmtObjects.Count);
var data = new Dictionary<String, Object>();
var vms = SupportedVMDetector.CreateInstance(conf.SupportedVMDetector).GetSupportedVM();
Assert.AreNotEqual(0, vms.Count);
var vm = vms.FirstOrDefault();
var args = new Dictionary<String, Object>(vm);
foreach (var mgmtObj in mgmtObjects)
{
var watch = System.Diagnostics.Stopwatch.StartNew();
try
{
data.Add(mgmtObj.KeyName, mgmtObj.CollectData(args));
}
catch (Exception e)
{
if (!mgmtObj.SuppressError)
{
Console.WriteLine(e);
Console.WriteLine(e.StackTrace);
Assert.Fail(e.Message);
}
data.Add(mgmtObj.KeyName, null);
}
Console.WriteLine(String.Format("{0}\t{1}", watch.ElapsedMilliseconds, mgmtObj.KeyName));
}
Assert.IsNotNull(data);
Assert.AreNotEqual(0, data.Count);
var xmlStr = DataFormatHelper.ToXml(data);
Console.WriteLine(xmlStr);
//var jsonStr = DataFormatHelper.ToJSON(data);
//var encodedStr = DataFormatHelper.Base64Encode(jsonStr);
//var dataChunks = DataFormatHelper.PackString(jsonStr, 900);
//var packedData = DataFormatHelper.ToChunk("", dataChunks);
//var encodedDataChunks = DataFormatHelper.PackString(encodedStr, 900);
//var encodedPackedData = DataFormatHelper.ToChunk("", encodedDataChunks);
//Console.WriteLine(JsonHelper.FormatJson(jsonStr));
//Console.WriteLine(String.Format("Original JSON string length: {0}", jsonStr.Length));
//Console.WriteLine(String.Format("Encoded JSON string length: {0}", encodedStr.Length));
//Console.WriteLine(String.Format("Packed JSON string length: {0}", packedData.Select(d => d.Value.ToString().Length).Sum()));
//Console.WriteLine(String.Format("Packed encoded JSON string length: {0}", encodedPackedData.Select(d => d.Value.ToString().Length).Sum()));
}
//[TestMethod]
public void TestWMIPerformanceCache()
{
Console.WriteLine("First time query");
TestMetricJSON();
System.Threading.Thread.Sleep(60 * 1000);
Console.WriteLine("----------------------------------------------------------------------");
Console.WriteLine("Second time query, after 60seconds");
TestMetricJSON();
}
//[TestMethod]
public void TestWMIPerformanceMultiple()
{
for(int i= 0; i < 10; i++)
{
var watch = System.Diagnostics.Stopwatch.StartNew();
TestMetricJSON();
Console.WriteLine(String.Format("Elapsed: {0}ms \t Total", watch.ElapsedMilliseconds));
Console.WriteLine("----------------------------------------------------------------------");
}
}
}
}

Просмотреть файл

@ -0,0 +1,220 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EnhancedMonitoring.Configuration;
using EnhancedMonitoring.DataCollector;
using EnhancedMonitoring;
using System.Collections.Generic;
using System.Management;
using System.Linq;
namespace UnitTest
{
[TestClass]
public class MgmtObjectTest
{
[TestMethod]
public void TestMgmtObjectSelectAll()
{
MgmtObjectConfiguration conf = new MgmtObjectConfiguration()
{
Namespace = @"root\cimv2",
From = @"WIN32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor",
Where = @"Name='_Total'",
PerfCounters = new PerfCounterConfigurationList()
};
conf.PerfCounters.Add(new PerfCounterConfiguration()
{
Select = "*"
});
var mgmtObj = MgmtObject.CreateInstance(conf);
var data = mgmtObj.CollectData(new Dictionary<String, Object>()) as IList<Object>;
Assert.IsNotNull(data);
}
[TestMethod]
public void TestMgmtObjectSelectPath()
{
MgmtObjectConfiguration conf = new MgmtObjectConfiguration()
{
Namespace = @"root\cimv2",
From = @"WIN32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor",
Where = @"Name='_Total'",
PerfCounters = new PerfCounterConfigurationList()
};
conf.PerfCounters.Add(new PerfCounterConfiguration()
{
Select = "*"
});
var mgmtObj = MgmtObject.CreateInstance(conf);
var data = mgmtObj.CollectData(new Dictionary<String, Object>()) as IList<Object>;
Assert.IsNotNull(data);
}
[TestMethod]
public void TestMgmtObjectCollectData()
{
MgmtObjectConfiguration conf = new MgmtObjectConfiguration()
{
Namespace = @"root\cimv2",
From = @"WIN32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor",
Where = @"Name='_Total'",
PerfCounters = new PerfCounterConfigurationList()
};
conf.PerfCounters.Add(new PerfCounterConfiguration() {
As = "PercentHypervisorRuntime",
Select = "PercentHypervisorRuntime"
});
var mgmtObj = MgmtObject.CreateInstance(conf);
var data = mgmtObj.CollectData(new Dictionary<String,Object>());
var list = (List<Object>) data;
Assert.IsNotNull(list);
var jsonObj = (IDictionary<String, Object>) list.FirstOrDefault();
Assert.IsNotNull(jsonObj["PercentHypervisorRuntime"]);
//Prevent PropertyData object is returned
//The value in PropertyData should be returned not the container
Assert.IsFalse(jsonObj["PercentHypervisorRuntime"] is PropertyData);
}
//[TestMethod]
public void TestMgmtObjectUnicode()
{
MgmtObjectConfiguration conf = new MgmtObjectConfiguration()
{
Namespace = @"root\cimv2",
From = @"Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor",
Where = (@"Name like '%%虚拟机%%'"),
PerfCounters = new PerfCounterConfigurationList()
};
conf.PerfCounters.Add(new PerfCounterConfiguration()
{
As = "PercentHypervisorRuntime",
Select = "PercentHypervisorRuntime"
});
var mgmtObj = MgmtObject.CreateInstance(conf);
var data = mgmtObj.CollectData(new Dictionary<String, Object>());
var list = (List<Object>)data;
Assert.IsNotNull(list);
var jsonObj = (IDictionary<String, Object>)list.FirstOrDefault();
Assert.IsNotNull(jsonObj["PercentHypervisorRuntime"]);
//Prevent PropertyData object is returned
//The value in PropertyData should be returned not the container
Assert.IsFalse(jsonObj["PercentHypervisorRuntime"] is PropertyData);
}
[TestMethod]
public void TestMgmtObjectErrorHandling()
{
//Test namespace wrong
try
{
MgmtObjectConfiguration conf = new MgmtObjectConfiguration()
{
Namespace = @"root\FALSE_NAMESPACE",
From = "WIN32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor",
PerfCounters = new PerfCounterConfigurationList() {
new PerfCounterConfiguration()
}
};
var mgmtObj = MgmtObject.CreateInstance(conf);
var data = mgmtObj.CollectData(new Dictionary<String, Object>());
Assert.Fail("ManagementException expected");
}
catch(ManagementException e)
{
Console.WriteLine(e);
Console.WriteLine();
}
//Test class name wrong
try
{
MgmtObjectConfiguration conf = new MgmtObjectConfiguration()
{
Namespace = @"root\cimv2",
From = @"FALSE_CLASS",
PerfCounters = new PerfCounterConfigurationList(){
new PerfCounterConfiguration()
}
};
var mgmtObj = MgmtObject.CreateInstance(conf);
var data = mgmtObj.CollectData(new Dictionary<String, Object>());
Assert.Fail("ManagementException expected");
}
catch (ManagementException e)
{
Console.WriteLine(e);
Console.WriteLine();
}
//Test no instance found
try
{
MgmtObjectConfiguration conf = new MgmtObjectConfiguration()
{
Namespace = @"root\cimv2",
From = @"WIN32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor",
Where = @"Name='FALSE_NAME'",
PerfCounters = new PerfCounterConfigurationList(){
new PerfCounterConfiguration()
}
};
var mgmtObj = MgmtObject.CreateInstance(conf);
var data = mgmtObj.CollectData(new Dictionary<String, Object>());
Assert.Fail("ManagementException expected");
}
catch (NotImplementedException e)
{
Console.WriteLine(e);
Console.WriteLine();
}
//Test null perf count
{
MgmtObjectConfiguration conf = new MgmtObjectConfiguration()
{
Namespace = @"root\cimv2",
From = @"WIN32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor",
Where = @"Name='_Total'",
};
var mgmtObj = MgmtObject.CreateInstance(conf);
var data = mgmtObj.CollectData(new Dictionary<String, Object>());
Assert.IsNull(data);
}
}
}
}

Просмотреть файл

@ -0,0 +1,72 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EnhancedMonitoring.Configuration;
namespace UnitTest
{
[TestClass]
public class MonitorConfigurationTest
{
[TestMethod]
public void TestLoadConfiguration()
{
var conf = MonitorConfiguration.Load(@"..\..\SampleMonitor.xml");
Assert.IsNotNull(conf);
Assert.IsNotNull(conf.Version);
Console.WriteLine(conf.Version);
Assert.AreEqual(60, conf.RefreshRate);
Assert.AreEqual(700, conf.MaxValueLength);
Assert.IsNotNull(conf.Kvp);
Assert.AreEqual(200, conf.Kvp.WriteInterval);
Assert.IsTrue(conf.Kvp.BatchMode);
Assert.IsNotNull(conf.SupportedVMDetector);
Assert.IsNotNull(conf.SupportedVMDetector.GuestDataItemKey);
Assert.IsNotNull(conf.MgmtObjects);
var mgmtObj = conf.MgmtObjects.FirstOrDefault();
Assert.IsNotNull(mgmtObj);
Assert.IsTrue(mgmtObj.SuppressError);
Assert.IsNotNull(mgmtObj.Namespace);
Assert.IsNotNull(mgmtObj.Where);
Assert.IsNotNull(mgmtObj.From);
Assert.IsNotNull(mgmtObj.WhereArgs);
Assert.IsTrue(mgmtObj.WhereArgs.FirstOrDefault().Escape);
Assert.IsNotNull(mgmtObj.WhereArgs.FirstOrDefault());
Assert.IsNotNull(mgmtObj.PerfCounters);
var counter = mgmtObj.PerfCounters.FirstOrDefault();
Assert.IsNotNull(counter);
Assert.IsNotNull(counter.Select);
Assert.IsNotNull(counter.As);
var dynamicMemMgmtObj = conf.MgmtObjects.Where(m => m.Type == MgmtObjectType.DynamicMemory).FirstOrDefault();
Assert.IsNotNull(dynamicMemMgmtObj);
Assert.AreEqual(MgmtObjectReturnValueType.Single, dynamicMemMgmtObj.ReturnValueType);
}
}
}

Просмотреть файл

@ -0,0 +1,47 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EnhancedMonitoring.Configuration;
using EnhancedMonitoring;
using EnhancedMonitoring.Logging;
namespace UnitTest
{
[TestClass]
public class MonitorTaskTest
{
[TestMethod]
public void TestMonitorTask()
{
var watcher = System.Diagnostics.Stopwatch.StartNew();
MonitorConfiguration conf = MonitorConfiguration.Load(@"..\..\..\EnhancedMonitoring\Configuration\EnhancedMonitoringProviderConfig.xml");
conf.LogFilePath = @"C:\ProgramData\Enhanced Monitoring\log\monitor.log";
conf.LogLevel = "Verbose";
Logger.Init(conf);
MonitoringTask task = MonitoringTask.CreateInstance(conf as MonitorConfiguration);
task.Run();
Console.WriteLine(String.Format("Elapsed: {0}ms", watcher.ElapsedMilliseconds));
}
}
}

Просмотреть файл

@ -0,0 +1,108 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using EnhancedMonitoring;
using EnhancedMonitoring.Configuration;
namespace UnitTest
{
[TestClass]
public class NamedArgumentHelperTest
{
[TestMethod]
public void TestResolveNamedArgument()
{
var str = "MaxClockSpeed_{0}_{1}";
var expected = "MaxClockSpeed_ubuntu_0";
var argsName = new List<WhereArgConfiguration>(){
new WhereArgConfiguration(){ Name ="VirtualMachine"},
new WhereArgConfiguration(){Name = "ProcessorId" }
};
var args = new Dictionary<String, Object>()
{
{"VirtualMachine", "ubuntu"},
{"ProcessorId", 0}
};
Assert.AreEqual(expected, NamedArgumentHelper.Resolve(str, argsName, args));
}
[TestMethod]
public void TestResolveNamedArgumentNagativeCase()
{
var str = "MaxClockSpeed_{0}_{1}";
var argsName = new List<WhereArgConfiguration>(){
new WhereArgConfiguration(){ Name ="VirtualMachine"},
new WhereArgConfiguration(){Name = "ProcessorId" }
};
var args = new Dictionary<String, Object>(){ {"VirtualMachine", "ubuntu"}};
//Argument name is null
try
{
NamedArgumentHelper.Resolve(str, null, args);
Assert.Fail("FormatException is expected");
}
catch (ArgumentException e)
{
Console.WriteLine(e);
}
//Argument names are less than cells
try
{
NamedArgumentHelper.Resolve(str, new List<WhereArgConfiguration>() {
new WhereArgConfiguration(){Name = "VirtualMachine"} }, args);
Assert.Fail("FormatException is expected");
}
catch (ArgumentException e)
{
Console.WriteLine(e);
}
//Name argument map is null
try
{
NamedArgumentHelper.Resolve(str, argsName, null);
Assert.Fail("ArgumentException is expected");
}
catch (ArgumentException e)
{
Console.WriteLine(e);
}
//Named argument not found
try
{
NamedArgumentHelper.Resolve(str, argsName, args);
Assert.Fail("ArgumentException is expected");
}
catch (ArgumentException e)
{
Console.WriteLine(e);
}
}
}
}

Просмотреть файл

@ -0,0 +1,58 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("UnitTest")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("UnitTest")]
[assembly: AssemblyCopyright("Copyright © 2014")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("5a308b21-7d9c-49d0-a903-88001f52deac")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Просмотреть файл

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
The MIT License (MIT)
Copyright 2015 Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<Monitor>
<!-- Refresh interval in seconds -->
<!-- Mandatory -->
<RefreshRate>60</RefreshRate>
<!-- Mandatory -->
<Version>1.0.0</Version>
<!-- Mandatory -->
<DataItemKeyPrefix>Enhanced_Monitoring_Metric_Data_Item_Part_</DataItemKeyPrefix>
<!-- Optional -->
<MaxValueLength>700</MaxValueLength>
<Kvp>
<BatchMode>true</BatchMode>
<WriteInterval>200</WriteInterval>
</Kvp>
<!-- Detect supported VMs through WMI-->
<SupportedVMDetector>
<!-- Mandatory -->
<!-- A key name that host uses to identify VMs supported-->
<GuestDataItemKey>Enhanced_Monitoring_Supported</GuestDataItemKey>
<!-- Select WMI properties as arguments passed to future WMI Query -->
<!-- The following properties are selected by default: -->
<!-- 1. Name as VirtualMachineName -->
<!-- 2. ElementName as VirtualMachineElementName -->
<!-- 3. Path as VirtualMachinePath -->
<!-- Optional -->
<VirtualMachineProperties>
<VirtualMachineProperty>
<Select>Status</Select>
<As>VirtualMachineStatus</As>
</VirtualMachineProperty>
</VirtualMachineProperties>
</SupportedVMDetector>
<MgmtObjects>
<MgmtObject SuppressError="true">
<!-- WMI Namespace -->
<!-- Mandatory -->
<Namespace>root\cimv2</Namespace>
<!-- WMI class name -->
<!-- Mandatory -->
<From>WIN32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor</From>
<!-- Query condition, {0} is an argument specified by the 1st WhereArg-->
<!-- Optional -->
<Where>Name like "%%{0}%%"</Where>
<!-- Arguments to construct "Where"-->
<!-- Optional -->
<WhereArgs>
<!-- '{0}' in 'Where' statement will be replaced by the bellow argument-->
<WhereArg Escape="true">VirtualMachineElementName</WhereArg>
</WhereArgs>
<PerfCounters>
<PerfCounter>
<!-- Metric name, if not specified property name will be used-->
<!-- Optional -->
<As>VirtualProcessor_PercentHypervisorRuntime</As>
<!-- Property name of WMI object-->
<!-- Mandatory -->
<Select>PercentHypervisorRuntime</Select>
</PerfCounter>
<PerfCounter>
<!-- We also support "select *".-->
<!-- In this case, the orignial property name will be used as perfcountname-->
<Select>*</Select>
</PerfCounter>
</PerfCounters>
</MgmtObject>
<MgmtObject ReturnValue = "Single" Type="DynamicMemory">
</MgmtObject>
</MgmtObjects>
</Monitor>

Просмотреть файл

@ -0,0 +1,95 @@
<Data>
<WIN32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor>
<Item>
<PercentHypervisorRuntime>331819225422</PercentHypervisorRuntime>
<PercentTotalRunTime>4627899239734</PercentTotalRunTime>
<TimeStamp_PerfTime>2294591080835</TimeStamp_PerfTime>
<Frequency_PerfTime>3312782</Frequency_PerfTime>
</Item>
</WIN32_PerfRawData_HvStats_HyperVHypervisorLogicalProcessor>
<WIN32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor>
<Item>
<PercentHypervisorRuntime>5956484</PercentHypervisorRuntime>
<PercentTotalRunTime>51824588</PercentTotalRunTime>
<TimeStamp_PerfTime>2294591203786</TimeStamp_PerfTime>
<Frequency_PerfTime>3312782</Frequency_PerfTime>
</Item>
<Item>
<PercentHypervisorRuntime>5436843</PercentHypervisorRuntime>
<PercentTotalRunTime>48668457</PercentTotalRunTime>
<TimeStamp_PerfTime>2294591203786</TimeStamp_PerfTime>
<Frequency_PerfTime>3312782</Frequency_PerfTime>
</Item>
<Item>
<PercentHypervisorRuntime>7695515</PercentHypervisorRuntime>
<PercentTotalRunTime>63962088</PercentTotalRunTime>
<TimeStamp_PerfTime>2294591203786</TimeStamp_PerfTime>
<Frequency_PerfTime>3312782</Frequency_PerfTime>
</Item>
<Item>
<PercentHypervisorRuntime>14605031</PercentHypervisorRuntime>
<PercentTotalRunTime>72549008</PercentTotalRunTime>
<TimeStamp_PerfTime>2294591203786</TimeStamp_PerfTime>
<Frequency_PerfTime>3312782</Frequency_PerfTime>
</Item>
</WIN32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor>
<WIN32_PROCESSOR>
<Item>
<Name>Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz</Name>
<MaxClockSpeed>3392</MaxClockSpeed>
<NumberOfCores>4</NumberOfCores>
<NumberOfLogicalProcessors>8</NumberOfLogicalProcessors>
</Item>
</WIN32_PROCESSOR>
<Win32_PerfFormattedData_PerfOS_Memory>
<Item>
<AvailableMBytes>2031</AvailableMBytes>
<PagesPersec>0</PagesPersec>
</Item>
</Win32_PerfFormattedData_PerfOS_Memory>
<Win32_PhysicalMemory>
<Item>
<Capacity>4294967296</Capacity>
</Item>
<Item>
<Capacity>4294967296</Capacity>
</Item>
</Win32_PhysicalMemory>
<WIN32_PerfFormattedData_HvStats_HyperVHypervisor>
<Item>
<TotalPages>11640</TotalPages>
</Item>
</WIN32_PerfFormattedData_HvStats_HyperVHypervisor>
<Win32_PerfFormattedData_BalancerStats_HyperVDynamicMemoryBalancer>
<Item>
<AvailableMemory>1526</AvailableMemory>
</Item>
</Win32_PerfFormattedData_BalancerStats_HyperVDynamicMemoryBalancer>
<WIN32_OPERATINGSYSTEM>
<Item>
<Version>6.3.9600</Version>
<CSDVersion>null</CSDVersion>
<Caption>Microsoft Windows 8.1 Enterprise</Caption>
</Item>
</WIN32_OPERATINGSYSTEM>
<MSVM_ComputerSystem>
<Item>
<Name>96BFA00A-46E3-4F7E-9169-6F39485BAC52</Name>
</Item>
</MSVM_ComputerSystem>
<MSVM_ProcessorSettingData>
<Item>
<VirtualQuantity>4</VirtualQuantity>
<Reservation>0</Reservation>
<Limit>100000</Limit>
</Item>
</MSVM_ProcessorSettingData>
<MSVM_MemorySettingData>
<Item>
<Reservation>512</Reservation>
<Limit>1048576</Limit>
<DynamicMemoryEnabled>true</DynamicMemoryEnabled>
<TargetMemoryBuffer>20</TargetMemoryBuffer>
</Item>
</MSVM_MemorySettingData>
</Data>

Просмотреть файл

@ -0,0 +1,67 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EnhancedMonitoring;
using EnhancedMonitoring.Configuration;
using System.Collections.Generic;
namespace UnitTest
{
[TestClass]
public class SupportedVMDetectorTest
{
/// <summary>
/// This test requires the host has at least one virtual machine to pass.
/// </summary>
[TestMethod]
public void TestDetectSupportedVM()
{
DetectSupportedVM();
}
public IDictionary<String, Object> DetectSupportedVM()
{
var detector = SupportedVMDetector.CreateInstance(new SupportedVMDetectorConfiguration()
{
GuestDataItemKey = "Enhanced_Monitoring_Supported",
});
var watcher = System.Diagnostics.Stopwatch.StartNew();
var vms = detector.GetSupportedVM();
Console.WriteLine(String.Format("Elapsed: {0}ms\t Detect supported VM", watcher.ElapsedMilliseconds));
Assert.IsNotNull(vms);
Assert.AreNotEqual(0, vms.Count);
var vm = vms.FirstOrDefault();
Assert.IsNotNull(vm);
Assert.IsNotNull(vm["VirtualMachineName"]);
Assert.IsNotNull(vm["VirtualMachineElementName"]);
Assert.IsNotNull(vm["VirtualMachinePath"]);
Console.WriteLine("Found: " + vm["VirtualMachineElementName"]);
return vm;
}
}
}

Просмотреть файл

@ -0,0 +1,158 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EnhancedMonitoring.Configuration;
using EnhancedMonitoring.Logging;
using System.IO;
using System.Threading.Tasks;
using System.Diagnostics;
namespace UnitTest
{
/// <summary>
/// Summary description for TestFileLogWriter
/// </summary>
[TestClass]
public class TestFileLogWriter
{
[TestMethod]
public void TestWriteToLogFile()
{
var tmpFolder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData)
+ @"\" + Guid.NewGuid().ToString();
var conf = new MonitorConfiguration()
{
LogLevel = "Info",
LogFilePath = tmpFolder + @"\test.log"
};
var logWriter = new FileLogWriter(conf);
String logContent = Guid.NewGuid().ToString();
logWriter.Write(LogLevel.Info, logContent);
Assert.IsTrue(File.Exists(conf.LogFilePath));
String log = File.ReadAllText(conf.LogFilePath);
Assert.IsTrue(log.Contains(logContent));
Directory.Delete(tmpFolder, true);
}
[TestMethod]
public void TestMultithreadWriteToLogFile()
{
var tmpFolder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData)
+ @"\" + Guid.NewGuid().ToString();
var conf = new MonitorConfiguration()
{
LogLevel = "Info",
LogFilePath = tmpFolder + @"\test.log"
};
var logWriter = new FileLogWriter(conf);
Task[] tasks = new Task[100];
for(int i = 0; i < tasks.Length; i++)
{
tasks[i] = Task.Run(() =>
{
Console.WriteLine(Process.GetCurrentProcess().Threads.Count);
String logContent = Guid.NewGuid().ToString();
logWriter.Write(LogLevel.Info, logContent);
});
}
Task.WaitAll(tasks);
Directory.Delete(tmpFolder, true);
}
[TestMethod]
public void TestRotateLog()
{
var tmpFolder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData)
+ @"\" + Guid.NewGuid().ToString();
Console.WriteLine(tmpFolder);
Directory.CreateDirectory(tmpFolder);
var conf = new MonitorConfiguration()
{
LogLevel = "Info",
LogFilePath = tmpFolder + @"\test.log",
LogFileSize = 1,
MaxLogRetention = 2
};
var logWriter = new FileLogWriter(conf);
String[] logContent = new String[4]
{
"Test 0","Test 1","Test 2","Test 3",
};
//echo "Test 0" > test.log
logWriter.Write(LogLevel.Info, logContent[0]);
//mv test.log test.log.0
//echo "Test 1" > test.log
logWriter.Write(LogLevel.Info, logContent[1]);
Assert.IsTrue(File.Exists(conf.LogFilePath));
String log = File.ReadAllText(conf.LogFilePath);
Assert.IsTrue(log.Contains(logContent[1]));
Assert.IsTrue(File.Exists(conf.LogFilePath + @".0"));
log = File.ReadAllText(conf.LogFilePath + @".0");
Assert.IsTrue(log.Contains(logContent[0]));
//mv test.log.0 test.log.1
//mv test.log test.log.0
//echo "Test 2" > test.log
logWriter.Write(LogLevel.Info, logContent[2]);
//rm test.log.1
//mv test.log.0 test.log.1
//mv test.log test.log.0
//echo "Test 3" test.log
logWriter.Write(LogLevel.Info, logContent[3]);
Assert.IsTrue(File.Exists(conf.LogFilePath + @".0"));
Assert.IsTrue(File.Exists(conf.LogFilePath + @".1"));
Assert.IsFalse(File.Exists(conf.LogFilePath + @".2"));
log = File.ReadAllText(conf.LogFilePath);
Assert.IsTrue(log.Contains(logContent[3]));
log = File.ReadAllText(conf.LogFilePath + @".1");
Assert.IsTrue(log.Contains(logContent[1]));
Directory.Delete(tmpFolder, true);
}
}
}

Просмотреть файл

@ -0,0 +1,61 @@
<Data>
<!--
The MIT License (MIT)
Copyright 2015 Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<Name>Dictionary(JSON object) to Xml Test</Name>
<TestCases Type="List">
<Item>Case1: String as Field</Item>
<Item>Case2: String Array as Field</Item>
<Item>Case3: Dictionary as Field</Item>
<Item>Case4: Object Array as Field</Item>
<Item>Case5: Null</Item>
</TestCases>
<ExpectedBehavior>
<ForAll>Key name as XElement name </ForAll>
<Case1>String content as XElement content</Case1>
<Case2>Each element becomes a child XElement with name 'Item'</Case2>
<Case3>Dictionary becomes a child XElement</Case3>
<Case4 Type="List">
<Item>1. Each element in the array is a dictionary</Item>
<Item>2. The 1st dictionary itself contains an array field</Item>
<Item>3. The 2nd dictionary itself contains a dictionary</Item>
</Case4>
<Case5>Output 'null'</Case5>
</ExpectedBehavior>
<ObjectArray Type="List">
<Item>
<ArrayObject Type="List">
<Item>Element 1</Item>
<Item>Element 1</Item>
</ArrayObject>
</Item>
<Item>
<DictionaryObject>
<ObjectField>ObjectValue</ObjectField>
</DictionaryObject>
</Item>
</ObjectArray>
<HandleNull>null</HandleNull>
</Data>

Просмотреть файл

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{0B568E5B-3796-47CC-B934-C4684CBE241C}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>UnitTest</RootNamespace>
<AssemblyName>UnitTest</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
<IsCodedUITest>False</IsCodedUITest>
<TestProjectType>UnitTest</TestProjectType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugAndRelease|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\DebugAndRelease\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data.Linq" />
<Reference Include="System.Management" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml.Serialization" />
</ItemGroup>
<Choose>
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
</ItemGroup>
</When>
<Otherwise>
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework" />
</ItemGroup>
</Otherwise>
</Choose>
<ItemGroup>
<Compile Include="DataPackingHelperTest.cs" />
<Compile Include="DynamicMemoryMgmtObjectTest.cs" />
<Compile Include="JSONHelper.cs" />
<Compile Include="KVPWriterTest.cs" />
<Compile Include="LoggerTest.cs" />
<Compile Include="MetricTest.cs" />
<Compile Include="MgmtObjectTest.cs" />
<Compile Include="MonitorConfigurationTest.cs" />
<Compile Include="MonitorTaskTest.cs" />
<Compile Include="NamedArgumentHelperTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SupportedVMDetectorTest.cs" />
<Compile Include="EventLogTest.cs" />
<Compile Include="FormatHelperTest.cs" />
<Compile Include="TestFileLogWriter.cs" />
<Compile Include="WMIQueryHelperTest.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="SampleMonitor.xml" />
<Content Include="SampleResult.xml">
<SubType>Designer</SubType>
</Content>
<Content Include="TestToXmlExpectedOutput.xml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\EnhancedMonitoring\EnhancedMonitoring.csproj">
<Project>{7eacc378-2947-4f2e-ab0f-eb57be7d3680}</Project>
<Name>EnhancedMonitoring</Name>
</ProjectReference>
</ItemGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">
<ItemGroup>
<Reference Include="Microsoft.VisualStudio.QualityTools.CodedUITestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITest.Extension, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.TestTools.UITesting, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<Private>False</Private>
</Reference>
</ItemGroup>
</When>
</Choose>
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

Просмотреть файл

@ -0,0 +1,63 @@
//The MIT License (MIT)
//
//Copyright 2015 Microsoft Corporation
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
//
using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using EnhancedMonitoring;
namespace UnitTest
{
[TestClass]
public class WMIQueryHelperTest
{
[TestMethod]
public void TestEscapeQuery()
{
var condition = WMIQueryHelper.EscapeLikeCondition(@"[");
Assert.AreEqual(@"[[]", condition);
condition = WMIQueryHelper.EscapeLikeCondition(@"_");
Assert.AreEqual(@"[_]", condition);
condition = WMIQueryHelper.EscapeLikeCondition(@"%");
Assert.AreEqual(@"[%]", condition);
condition = WMIQueryHelper.EscapeLikeCondition(@"^");
Assert.AreEqual(@"^", condition);
condition = WMIQueryHelper.EscapeLikeCondition(@"]");
Assert.AreEqual(@"]", condition);
condition = WMIQueryHelper.EscapeLikeCondition(@"[[[][]]]");
Assert.AreEqual(@"[[][[][[]][[]]]]", condition);
condition = WMIQueryHelper.EscapeLikeCondition(@"[_]");
Assert.AreEqual(@"[[][_]]", condition);
condition = WMIQueryHelper.EscapeLikeCondition(@"");
Assert.AreEqual(@"", condition);
condition = WMIQueryHelper.EscapeLikeCondition(null);
Assert.AreEqual(null, condition);
}
}
}