using System;
using System.Collections.Generic;
using System.Threading;
///
/// Microsoft System Insights namespaces
///
using Microsoft.SystemInsights.Common;
using Microsoft.SystemInsights.Capability;
namespace Microsoft.SystemInsights.Samples
{
///
/// Creates a sample System Insights capability.
/// This capability demonstrates:
/// 1. How to register data sources.
/// 2. How to parse the capability input to make a prediction.
/// 3. How to cancel the prediction.
///
/// A DLL should have only one type that implements the ICapability interface.
///
public class SampleInsightsCapability : ICapability, IDisposable
{
private CancellationTokenSource cts = new CancellationTokenSource();
///
/// The assembly version is used if Version is left null.
///
public Version Version => new Version("1.0");
public string Publisher => "Contoso Corporation";
///
/// Method to register the data sources required for the capability.
/// This method registers a performance counter, an ETW event, and a well-known series.
///
///
public CapabilityInformation GetCapabilityInformation()
{
DataSource wellKnownSeriesVolume = new DataSource
{
SourceType = DataSourceType.WellKnownSeries,
WellKnownSeries = new WellKnownSeriesDataSource
{
WellKnownSeriesType = WellKnownSeriesType.Volume
},
SeriesContext = "WellKnownSeriesVolume"
};
DataSource perfCounter = new DataSource
{
SourceType = DataSourceType.PerfCounter,
PerformanceCounter = new PerformanceCounterDataSource
{
CounterPath = "PhysicalDisk",
CounterName = "Disk Bytes/sec",
InstanceName = "*" // All instances
},
AggregationType = DataAggregationType.Sum,
SeriesContext = "PhysicalDiskPerfCounters"
};
DataSource etwSource = new DataSource
{
SourceType = DataSourceType.EventLog,
Event = new EventDataSource
{
ChannelName = "System",
EventId = 12 // System start event after a reboot
},
SeriesContext = "SystemStartEvent"
};
return new CapabilityInformation(CapabilityPredictionType.Generic,
new List { wellKnownSeriesVolume, perfCounter, etwSource },
"Sample System Insights capability that analyzes data from a well-known series, performance counters, and an ETW event.");
}
///
/// Method to write the prediction logic for the capability.
///
/// This sample capability doesn't contain any prediction logic.
/// This only shows how to parse the data sources
/// and return a prediction status.
///
///
/// The prediction request object.
/// Dictionary of data containing the data sources specified above.
///
///
public InvokeResult Invoke(InvokeRequest invokeRequest)
{
cts.Token.Register(() => OnCancel());
///
/// The InvokeRequest object is a dictionary containing all of data sources that the capability registered
/// during the method.
/// The dictionary uses the SeriesContext that's defined above as they key for each data source.
///
foreach (var data in invokeRequest.RequestData)
{
///
/// Each data source registered above maps directly to a DataSeries object.
/// You can use the SeriesContext to identify the data source.
///
/// An individual data source might record data for multiple instances.
/// For example, the well-known volume series has data for all volumes.
/// Or, a performance counter data source can record data for 'all instances'.
/// The DataSeries object contains structures to help you properly identify
/// the data you specified.
///
/// For more details about DataSeries, you can refer to the online documentation,
/// which shows you how the DataSeries is constructed for
/// each type of data source.
///
string seriesContext = data.Key;
IReadOnlyList dataSeries = data.Value;
foreach (DataSeries series in dataSeries)
{
///
/// The Identifier property identifies each instance in the data series.
///
string identifier = series.Identifier;
///
/// Each instance may have additional metadata information associated with it,
/// which is contained in the SeriesProperties property.
/// For example, the volume well-known series contains the GUID, drive letter, and friendly name
/// of each volume.
///
IReadOnlyDictionary seriesProperties = series.SeriesProperties;
///
/// Each DataRecord might contain multiple data points for a given timestamp,
/// such as BytesInbound and BytesOutbound for the networking well-known series.
/// The SeriesName object maps the data to the index in the list.
///
/// If you aren't using well-known series, you can ignore this object, as the DataRecord
/// only contains one entry per timestamp.
///
IReadOnlyDictionary seriesNames = series.SeriesNames;
///
/// The data is contained as a list of .
/// An individual DataRecord contains the data for a given timestamp.
/// If the DataRecord contains multiple data points for each timestamp,
/// use the object to determine the ordering of the
/// data points.
///
IReadOnlyList dataRecords = series.DataRecords;
///
/// You can now use the data from the to make a prediction.
///
}
}
///
/// Each prediction must return a status, status description, and any associated prediction data.
///
/// When returning the associated data, a capability can use different constructors and classes
/// depending on the prediction type. For example, you can use the ForecastingResult structure to output
/// strongly typed data that's associated with a forecasting prediction.
/// The advantage of using these types is that the prediction data will be
/// displayed nicely in Windows Admin Center, as Windows Admin Center knows how
/// to interpret the strongly typed output for each of the prediction types.
///
/// The three different constructors are shown below. Use the one associated with your
/// prediction type, which you defined in .
/// Because this example is a "Generic" prediction type, this example uses the generic result constructor.
///
/// Refer to the documentation to see more information about the
/// ForecastingResult and AnomalyDetectionResult classes.
///
// return new InvokeResult(PredictionStatus.Ok, "Everything looks good.", new List());
// return new InvokeResult(PredictionStatus.Ok, "Everything looks good.", new List());
return new InvokeResult(PredictionStatus.Ok, "Everything looks good.", "[Your prediction JSON blob goes here]");
}
///
/// Method to cancel all inprogress predictions
///
public void Cancel()
{
cts.Cancel();
}
private void OnCancel()
{
///
/// Cancellation logic goes here
///
}
public void Dispose()
{
cts.Dispose();
}
}
}