Как вставить данные о производительности в базу данных DW с помощью SCOM SDK?
Мы создали Inbound Connector и пользовательский пакет управления.
Мы отправляем данные на наш сервер SCOM, используя примеры.NET SDK.
Мы можем увидеть данные о производительности и события на консоли SCOM.
Но когда мы создаем отчет о производительности (Reporting> Microsoft Generic Report Library> Performance), мы не видим наши счетчики производительности.
Кажется, у нас проблемы с вставкой данных о производительности в базу данных DW.
Пожалуйста, спросите меня о любой дополнительной информации, которую я могу предоставить для решения проблемы.
ОБНОВИТЬ
Исходный код нашего пакета управления:
<?xml version="1.0" encoding="utf-8"?><ManagementPack ContentReadable="true" SchemaVersion="2.0" OriginalSchemaVersion="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<Manifest>
<Identity>
<ID>CloudMonix.ResourceMonitoring</ID>
<Version>1.0.0.0</Version>
</Identity>
<Name>CloudMonix Resource Monitoring Pack</Name>
<References>
<Reference Alias="System">
<ID>System.Library</ID>
<Version>7.5.8501.0</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
<Reference Alias="Health">
<ID>System.Health.Library</ID>
<Version>7.0.8438.6</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
<Reference Alias="SystemCenter">
<ID>Microsoft.SystemCenter.Library</ID>
<Version>7.0.8438.6</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
</References>
</Manifest>
<TypeDefinitions>
<EntityTypes>
<ClassTypes>
<ClassType ID="CloudMonix.ResourceMonitoring.Resource" Accessibility="Public" Abstract="false" Base="System!System.Entity" Hosted="false" Singleton="false" Extension="false">
<Property ID="ResourceId" Type="string" AutoIncrement="false" Key="true" CaseSensitive="false" MaxLength="256" MinLength="1" Required="false" Scale="0" />
<Property ID="ResourceType" Type="string" AutoIncrement="false" Key="false" CaseSensitive="false" MaxLength="256" MinLength="1" Required="false" Scale="0" />
<Property ID="ResourceGroups" Type="string" AutoIncrement="false" Key="false" CaseSensitive="false" MaxLength="1024" MinLength="1" Required="false" Scale="0" />
</ClassType>
</ClassTypes>
</EntityTypes>
<ModuleTypes>
<WriteActionModuleType ID="CloudMonix.ResourceMonitoring.SetStateAction" Accessibility="Internal" Batching="false">
<Configuration>
<IncludeSchemaTypes>
<SchemaType>Health!System.Health.AlertSchema</SchemaType>
</IncludeSchemaTypes>
<xsd:element name="ManagementGroupId" type="xsd:string" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
<xsd:element name="MonitorId" type="xsd:string" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
<xsd:element name="ManagedEntityId" type="xsd:string" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
<xsd:element name="HealthState" type="System.Health.AlertHealthState" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
</Configuration>
<ModuleImplementation Isolation="Any">
<Native>
<ClassID>44cbc334-8b5f-4cb6-bee0-6bdcbc80e8d5</ClassID>
</Native>
</ModuleImplementation>
<InputType>System!System.BaseData</InputType>
</WriteActionModuleType>
<WriteActionModuleType ID="CloudMonix.ResourceMonitoring.TargetSetStateAction" Accessibility="Internal" Batching="false">
<Configuration>
<IncludeSchemaTypes>
<SchemaType>Health!System.Health.AlertSchema</SchemaType>
</IncludeSchemaTypes>
<xsd:element name="MonitorId" type="xsd:string" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
<xsd:element name="HealthState" type="System.Health.AlertHealthState" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
</Configuration>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<WriteAction ID="WA" TypeID="CloudMonix.ResourceMonitoring.SetStateAction">
<ManagementGroupId>$Target/ManagementGroup/Id$</ManagementGroupId>
<MonitorId>$Config/MonitorId$</MonitorId>
<ManagedEntityId>$Data/ManagedEntityId$</ManagedEntityId>
<HealthState>$Config/HealthState$</HealthState>
</WriteAction>
</MemberModules>
<Composition>
<Node ID="WA" />
</Composition>
</Composite>
</ModuleImplementation>
<InputType>System!System.BaseData</InputType>
</WriteActionModuleType>
<WriteActionModuleType ID="CloudMonix.ResourceMonitoring.TargetSetSuccessAction" Accessibility="Public" Batching="false">
<Configuration>
<xsd:element name="MonitorId" type="xsd:string" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
</Configuration>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<WriteAction ID="WA" TypeID="CloudMonix.ResourceMonitoring.TargetSetStateAction">
<MonitorId>$Config/MonitorId$</MonitorId>
<HealthState>Success</HealthState>
</WriteAction>
</MemberModules>
<Composition>
<Node ID="WA" />
</Composition>
</Composite>
</ModuleImplementation>
<InputType>System!System.BaseData</InputType>
</WriteActionModuleType>
<WriteActionModuleType ID="CloudMonix.ResourceMonitoring.TargetSetWarningAction" Accessibility="Public" Batching="false">
<Configuration>
<xsd:element name="MonitorId" type="xsd:string" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
</Configuration>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<WriteAction ID="WA" TypeID="CloudMonix.ResourceMonitoring.TargetSetStateAction">
<MonitorId>$Config/MonitorId$</MonitorId>
<HealthState>Warning</HealthState>
</WriteAction>
</MemberModules>
<Composition>
<Node ID="WA" />
</Composition>
</Composite>
</ModuleImplementation>
<InputType>System!System.BaseData</InputType>
</WriteActionModuleType>
<WriteActionModuleType ID="CloudMonix.ResourceMonitoring.TargetSetErrorAction" Accessibility="Public" Batching="false">
<Configuration>
<xsd:element name="MonitorId" type="xsd:string" xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
</Configuration>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<WriteAction ID="WA" TypeID="CloudMonix.ResourceMonitoring.TargetSetStateAction">
<MonitorId>$Config/MonitorId$</MonitorId>
<HealthState>Error</HealthState>
</WriteAction>
</MemberModules>
<Composition>
<Node ID="WA" />
</Composition>
</Composite>
</ModuleImplementation>
<InputType>System!System.BaseData</InputType>
</WriteActionModuleType>
</ModuleTypes>
</TypeDefinitions>
<Monitoring>
<Rules>
<Rule ID="CloudMonix.ResourceMonitoring.Monitor.Success" Enabled="true" Target="CloudMonix.ResourceMonitoring.Resource" ConfirmDelivery="false" Remotable="true" Priority="Normal" DiscardLevel="100">
<Category>StateCollection</Category>
<DataSources>
<DataSource ID="DataSource" TypeID="SystemCenter!Microsoft.SystemCenter.SdkEventProvider" />
</DataSources>
<ConditionDetection ID="ConditionDetection" TypeID="System!System.ExpressionFilter">
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery>EventNumber</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value>1</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</ConditionDetection>
<WriteActions>
<WriteAction ID="WriteAction" TypeID="CloudMonix.ResourceMonitoring.TargetSetSuccessAction">
<MonitorId>$MPElement[Name="CloudMonix.ResourceMonitoring.Monitor"]$</MonitorId>
</WriteAction>
</WriteActions>
</Rule>
<Rule ID="CloudMonix.ResourceMonitoring.Monitor.Warning" Enabled="true" Target="CloudMonix.ResourceMonitoring.Resource" ConfirmDelivery="false" Remotable="true" Priority="Normal" DiscardLevel="100">
<Category>StateCollection</Category>
<DataSources>
<DataSource ID="DataSource" TypeID="SystemCenter!Microsoft.SystemCenter.SdkEventProvider" />
</DataSources>
<ConditionDetection ID="ConditionDetection" TypeID="System!System.ExpressionFilter">
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery>EventNumber</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value>2</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</ConditionDetection>
<WriteActions>
<WriteAction ID="WriteAction" TypeID="CloudMonix.ResourceMonitoring.TargetSetWarningAction">
<MonitorId>$MPElement[Name="CloudMonix.ResourceMonitoring.Monitor"]$</MonitorId>
</WriteAction>
</WriteActions>
</Rule>
<Rule ID="CloudMonix.ResourceMonitoring.Monitor.Error" Enabled="true" Target="CloudMonix.ResourceMonitoring.Resource" ConfirmDelivery="false" Remotable="true" Priority="Normal" DiscardLevel="100">
<Category>StateCollection</Category>
<DataSources>
<DataSource ID="DataSource" TypeID="SystemCenter!Microsoft.SystemCenter.SdkEventProvider" />
</DataSources>
<ConditionDetection ID="ConditionDetection" TypeID="System!System.ExpressionFilter">
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery>EventNumber</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value>3</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</ConditionDetection>
<WriteActions>
<WriteAction ID="WriteAction" TypeID="CloudMonix.ResourceMonitoring.TargetSetErrorAction">
<MonitorId>$MPElement[Name="CloudMonix.ResourceMonitoring.Monitor"]$</MonitorId>
</WriteAction>
</WriteActions>
</Rule>
</Rules>
<Monitors>
<AggregateMonitor ID="CloudMonix.ResourceMonitoring.Monitor" Accessibility="Public" Enabled="true" Target="CloudMonix.ResourceMonitoring.Resource" ParentMonitorID="Health!System.Health.EntityState" Remotable="true" Priority="Normal">
<Category>StateCollection</Category>
<Algorithm>WorstOf</Algorithm>
</AggregateMonitor>
</Monitors>
</Monitoring>
<Presentation>
<Views>
<View ID="CloudMonix.ResourceMonitoring.MainView" Accessibility="Public" Enabled="true" Target="CloudMonix.ResourceMonitoring.Resource" TypeID="SystemCenter!Microsoft.SystemCenter.StateViewType" Visible="true">
<Category>Operations</Category>
<Criteria>
<InMaintenanceMode>false</InMaintenanceMode>
</Criteria>
<Presentation>
<ColumnInfo Index="0" SortIndex="-1" Width="100" Grouped="false" Sorted="true" IsSortable="true" Visible="true" SortOrder="Ascending">
<Name>State</Name>
<Id>CloudMonix.ResourceMonitoring.Resource</Id>
</ColumnInfo>
<ColumnInfo Index="1" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
<Name>Resource Type</Name>
<Id>ResourceType</Id>
</ColumnInfo>
<ColumnInfo Index="2" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
<Name>Resource Name</Name>
<Id>DisplayName</Id>
</ColumnInfo>
<ColumnInfo Index="3" SortIndex="-1" Width="100" Grouped="false" Sorted="false" IsSortable="true" Visible="true" SortOrder="Ascending">
<Name>Resource Groups</Name>
<Id>ResourceGroups</Id>
</ColumnInfo>
</Presentation>
<Target />
</View>
</Views>
<Folders>
<Folder ID="CloudMonix.ResourceMonitoring.MainFolder" Accessibility="Public" ParentFolder="SystemCenter!Microsoft.SystemCenter.Monitoring.ViewFolder.Root" />
</Folders>
<FolderItems>
<FolderItem ElementID="CloudMonix.ResourceMonitoring.MainView" ID="CloudMonix.ResourceMonitoring.MainView" Folder="CloudMonix.ResourceMonitoring.MainFolder" />
</FolderItems>
</Presentation>
<LanguagePacks>
<LanguagePack ID="ENU" IsDefault="false">
<DisplayStrings>
<DisplayString ElementID="CloudMonix.ResourceMonitoring">
<Name>CloudMonix Resource Monitoring</Name>
</DisplayString>
<DisplayString ElementID="CloudMonix.ResourceMonitoring.MainFolder">
<Name>CloudMonix Folder</Name>
</DisplayString>
<DisplayString ElementID="CloudMonix.ResourceMonitoring.MainView">
<Name>CloudMonix Resource View</Name>
</DisplayString>
<DisplayString ElementID="CloudMonix.ResourceMonitoring.Monitor">
<Name>CloudMonix Health State Monitor</Name>
</DisplayString>
<DisplayString ElementID="CloudMonix.ResourceMonitoring.Resource">
<Name>CloudMonix Resource</Name>
</DisplayString>
<DisplayString ElementID="CloudMonix.ResourceMonitoring.Resource" SubElementID="ResourceId">
<Name>Resource Id</Name>
</DisplayString>
<DisplayString ElementID="CloudMonix.ResourceMonitoring.Resource" SubElementID="ResourceType">
<Name>Resource Type</Name>
</DisplayString>
<DisplayString ElementID="CloudMonix.ResourceMonitoring.Resource" SubElementID="ResourceGroups">
<Name>Resource Groups</Name>
</DisplayString>
</DisplayStrings>
</LanguagePack>
</LanguagePacks>
</ManagementPack>
ОБНОВЛЕНИЕ 2
Наш исходный код очень прост:
var customMonitoringPerformanceDatas = performanceDatas
.Select(n => new CustomMonitoringPerformanceData("CloudMonix", n.MetricName, n.Value)
{
TimeSampled = n.TimeStamp
})
.OrderBy(n => n.TimeSampled)
.ToList();
monitoringObject.InsertCustomMonitoringPerformanceData(customMonitoringPerformanceDatas);
ОБНОВЛЕНИЕ 3
Я реализовал следующее правило:
<Rule ID="CloudMonix.ResourceMonitoring.PerformanceData" Enabled="true" Target="CloudMonix.ResourceMonitoring.Resource" ConfirmDelivery="false" Remotable="true" Priority="Normal" DiscardLevel="100">
<Category>PerformanceCollection</Category>
<DataSources>
<DataSource ID="DataSource" TypeID="SystemCenter!Microsoft.SystemCenter.SdkPerformanceDataProvider" />
</DataSource>
</DataSources>
<WriteActions>
<WriteAction ID="WriteToDB" TypeID="SystemCenter!Microsoft.SystemCenter.CollectPerformanceData" />
<WriteAction ID="WriteToDW" TypeID="SystemCenterDataWarehouse!Microsoft.SystemCenter.DataWarehouse.PublishPerformanceDataCustomChannel">
<ChannelId>69173604-6F23-4F98-3383-F3500BA26228</ChannelId>
</WriteAction>
</WriteActions>
</Rule>
Я использовал свой собственный идентификатор коннектора для ChannelId
в правиле. Но я не вижу счетчиков производительности, к сожалению.
ОБНОВЛЕНИЕ 4
Я исследовал SCOM DB и увидел мою проблему. Наши данные были собраны в базу данных DW.
Но все наши данные были собраны с одним правилом ID.
Поскольку SCOM использует только один идентификатор правила для всех данных, мы видим только одно имя счетчика производительности.
Как нам нужно правильно собирать данные о производительности с помощью SDK?
1 ответ
Мы исправили нашу проблему!
Я просмотрел базу данных SCOM DW и увидел, что нам нужно реализовать отдельное правило для каждой метрики.
Мы можем найти похожую проблему и описание в блоге Мишеля Кэмпа.
Мы использовали SCOM SDK для создания динамических правил и добавления этих правил в наш пакет управления.
Подробный пример кода здесь:
const string conditionName = "System.ExpressionFilter";
const string dataSourceName = "Microsoft.SystemCenter.SdkPerformanceDataProvider";
const string writeActionName = "Microsoft.SystemCenter.DataWarehouse.PublishPerformanceData";
var managementClass = GetManagementPackClass(managementGroup, ManagementPackClass);
var criteria = new ManagementPackModuleTypeCriteria($"Name = '{conditionName}' OR Name = '{dataSourceName}' OR Name = '{writeActionName}'");
var moduleTypes = managementGroup.Monitoring.GetModuleTypes(criteria).ToList();
var conditionType = moduleTypes.Single(n => n.Name == conditionName);
var dataSourceType = moduleTypes.Single(n => n.Name == dataSourceName);
var writeActionType = moduleTypes.Single(n => n.Name == writeActionName);
foreach (var ruleName in missingRuleNames)
{
var counterName = ruleName.Replace(MonitoringRulePrefix, string.Empty);
var rule = new ManagementPackRule(managementPack, ruleName)
{
Target = managementClass,
Category = ManagementPackCategoryType.PerformanceCollection,
Enabled = ManagementPackMonitoringLevel.@true,
ConfirmDelivery = false
};
rule.ConditionDetection = new ManagementPackConditionDetectionModule(rule, "ConditionDetection")
{
TypeID = (ManagementPackConditionDetectionModuleType) conditionType,
Configuration = $@"
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery>CounterName</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value>{counterName}</Value>
</ValueExpression>
</SimpleExpression>
</Expression>"
};
var dataSource = new ManagementPackDataSourceModule(rule, "DataSource")
{
TypeID = (ManagementPackDataSourceModuleType) dataSourceType
};
rule.DataSourceCollection.Add(dataSource);
var action = new ManagementPackWriteActionModule(rule, "WriteToDataWarehouse")
{
TypeID = (ManagementPackWriteActionModuleType) writeActionType
};
rule.WriteActionCollection.Add(action);
}
managementPack.Verify();
managementPack.AcceptChanges();