Saturday, February 11, 2012

Why classes are so important

Classes are important for a wide variety of reasons. They create blank open tables in SQL Server. You populate them in a variety of ways, the most popular is the use of a discovery. Hardly the only way, even a rule can fire off a DataSourceModule and the code within can populate the table.

But for that rule to work,  indeed, for anything to happen inside a managementpack, a certain kind of binding must occur. 

So, the combination of a class and a means by which that class's tables get populated creates this kind of binding and enables the rules and monitors to work on the machine where the agent resides and has added the mp to the agent's mangementpack cache.

Ever wondered why every agent has almost every managementpack imported into it on every machine?

That's because the mangementpack has to decide whether or not it should run on that type of machine. For example, the two classes that create the relationship between the 2003 computer and the group are the two below:

<ClassType ID="Microsoft.Windows.Server.2003.Computer" Abstract="false" Accessibility="Public" Base="Windows!Microsoft.Windows.Server.Computer" Hosted="false" Singleton="false" />       
<ClassType ID="Microsoft.Windows.Server.2003.ComputerGroup" Abstract="false" Accessibility="Public" Base="SC!Microsoft.SystemCenter.ComputerGroup" Hosted="false" Singleton="true" />

Notice that neither one has any properties. Again, this is because the two produce the binding between the computer group and the discovered computer.

     
<Discovery ID="Microsoft.Windows.Server.2003.Computer.Discovery" Enabled="onEssentialMonitoring" Target="Windows!Microsoft.Windows.Server.Computer">
<Category>Discovery</Category>
<DiscoveryTypes>
<DiscoveryClass TypeID="Microsoft.Windows.Server.2003.Computer" />
</DiscoveryTypes>
<DataSource ID="DiscoveryDataSource" TypeID="Windows!Microsoft.Windows.FilteredRegistryDiscoveryProvider">
<ComputerName>$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$</ComputerName>
<RegistryAttributeDefinitions>
<RegistryAttributeDefinition>
<AttributeName>WindowsCurrentVersion</AttributeName>
<Path>SOFTWARE\Microsoft\Windows NT\CurrentVersion\CurrentVersion</Path>
<PathType>1</PathType>
<AttributeType>1</AttributeType>
</RegistryAttributeDefinition>
</RegistryAttributeDefinitions>
<Frequency>3604</Frequency>
<ClassId>$MPElement[Name="Microsoft.Windows.Server.2003.Computer"]$</ClassId>
<InstanceSettings>
<Settings>
<Setting>
<Name>$MPElement[Name="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Name>
<Value>$Target/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Value>
</Setting>
</Settings>
</InstanceSettings>
<Expression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery>Values/WindowsCurrentVersion</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value>5.2</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<Value>$Target/Property[Type="Windows!Microsoft.Windows.Server.Computer"]/IsVirtualNode$</Value>
</ValueExpression>
<Operator>NotEqual</Operator>
<ValueExpression>
<Value>True</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</And>
</Expression>
</DataSource>
</Discovery>

The above discoveres the computer. The discovery below populates that discover with the group:

<Discovery ID="Microsoft.Windows.Server.2003.AllServersComputerGroupDiscovery" Enabled="onEssentialMonitoring" Target="Microsoft.Windows.Server.2003.ComputerGroup">
<Category>Discovery</Category>
<DiscoveryTypes />
<DataSource ID="DiscoveryDataSource" TypeID="SC!Microsoft.SystemCenter.GroupPopulator">
<RuleId>$MPElement$</RuleId>
<GroupInstanceId>$Target/Id$</GroupInstanceId>
<MembershipRules>
<MembershipRule>
<MonitoringClass>$MPElement[Name="Microsoft.Windows.Server.2003.Computer"]$</MonitoringClass>
<RelationshipClass>$MPElement[Name="SC!Microsoft.SystemCenter.ComputerGroupContainsComputer"]$</RelationshipClass>
</MembershipRule>
</MembershipRules>
</DataSource>
</Discovery>

But this only binds the computer to the group.  What makes the rules work? Just about every other class in the mangementpack does.

The very first rule tells you what class and discover needs to be created and discovered to make it work:
<Rule ID="Microsoft.Windows.Server.2003.OperatingSystem.PerfCounterDataRequestTimeOut.Alert" Enabled="onEssentialMonitoring" Target="Microsoft.Windows.Server.2003.OperatingSystem">

So, this begs, couldn't we have simply started the managementpack from there and not had to worry about the group population?

The answer is both yes and no.  Yes, you can if your managementpack was simply looking for a specific application.  However, in the case of the Windows.Server.2003.mp, no. There is a one to many relationship here with the mp's classes and discoveries.  For example, other classes depend on this class and discovery combination to make the rest of the mp to work and the discovery itself relies on the discovery of  the class: Windows!Microsoft.Windows.Server.Computer.

Meaning, its discovery logic is exactly the same as the Microsoft.Windows.Server.2003.Computer.Discovery:

<Discovery ID="Microsoft.Windows.Server.2003.OperatingSystem.Discovery" Enabled="onEssentialMonitoring" Target="Windows!Microsoft.Windows.Server.Computer">

So, why have both?  Simple, one helps to populate the Group Discovery.  The other binds the rules, monitors and other related targets to Windows!Microsoft.Windows.Server.Computer through the OperatingSystem Discovery.

But it is not the only one:

<ClassType ID="Microsoft.Windows.Server.2003.NetworkAdapter" Abstract="false" Accessibility="Public" Base="WindowsServer!Microsoft.Windows.Server.NetworkAdapter" Hosted="true" Singleton="false" />
<ClassType ID="Microsoft.Windows.Server.2003.Processor" Abstract="false" Accessibility="Public" Base="WindowsServer!Microsoft.Windows.Server.Processor" Hosted="true" Singleton="false" />
<ClassType ID="Microsoft.Windows.Server.2003.PhysicalDisk" Abstract="false" Accessibility="Public" Base="WindowsServer!Microsoft.Windows.Server.PhysicalDisk" Hosted="true" Singleton="false" />
<ClassType ID="Microsoft.Windows.Server.2003.LogicalDisk" Abstract="false" Accessibility="Public" Base="WindowsServer!Microsoft.Windows.Server.LogicalDisk" Hosted="true" Singleton="false" />
<ClassType ID="Microsoft.Windows.Server.2003.DiskPartition" Abstract="false" Accessibility="Public" Base="WindowsServer!Microsoft.Windows.Server.DiskPartition" Hosted="true" Singleton="false" />

Each one gets discovered and the target is:  "Microsoft.Windows.Server.2003.OperatingSystem"

Why spend so much time explaining this?

Because you can create an identity class from the following:

  1. Computer
  2. Server.Computer
  3. Service
    1. Registry
    2. File
  4. Application
    1. Registry
    2. File
  5. Role
    1. Registry
    2. File






No comments:

Post a Comment