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(); } } }