Share via


Zelfstudie: Afwijkingen detecteren en analyseren met behulp van KQL-machine learning-mogelijkheden in Azure Monitor

De Kusto-querytaal (KQL) bevat machine learning-operators, functies en invoegtoepassingen voor tijdreeksanalyse, anomaliedetectie, prognoses en analyse van hoofdoorzaak. Gebruik deze KQL-mogelijkheden om geavanceerde gegevensanalyse uit te voeren in Azure Monitor zonder de overhead van het exporteren van gegevens naar externe machine learning-hulpprogramma's.

In deze zelfstudie leert u het volgende:

  • Een tijdreeks maken
  • Afwijkingen in een tijdreeks identificeren
  • Instellingen voor anomaliedetectie aanpassen om resultaten te verfijnen
  • De hoofdoorzaak van afwijkingen analyseren

Notitie

Deze zelfstudie bevat koppelingen naar een Log Analytics-demoomgeving waarin u de KQL-queryvoorbeelden kunt uitvoeren. U kunt echter dezelfde KQL-query's en -principals implementeren in alle Azure Monitor-hulpprogramma's die gebruikmaken van KQL.

Vereisten

Machtigingen vereist

U moet machtigingen hebben Microsoft.OperationalInsights/workspaces/query/*/read voor de Log Analytics-werkruimten die u opvraagt, zoals opgegeven door de ingebouwde rol Log Analytics-lezer.

Een tijdreeks maken

Gebruik de KQL-operator make-series om een tijdreeks te maken.

We gaan een tijdreeks maken op basis van logboeken in de tabel Gebruik, die informatie bevat over de hoeveelheid gegevens die elke tabel in een werkruimte elk uur opneemt, inclusief factureerbare en niet-factureerbare gegevens.

Deze query gebruikt make-series om de totale hoeveelheid factureerbare gegevens in kaart te brengen die elke dag door elke tabel in de werkruimte is opgenomen, in de afgelopen 21 dagen:

Klik om de query uit te voeren

let starttime = 21d; // The start date of the time series, counting back from the current date
let endtime = 0d; // The end date of the time series, counting back from the current date
let timeframe = 1d; // How often to sample data
Usage // The table we’re analyzing
| where TimeGenerated between (startofday(ago(starttime))..startofday(ago(endtime))) // Time range for the query, beginning at 12:00 AM of the first day and ending at 12:00 AM of the last day in the time range
| where IsBillable == "true" // Include only billable data in the result set
| make-series ActualUsage=sum(Quantity) default = 0 on TimeGenerated from startofday(ago(starttime)) to startofday(ago(endtime)) step timeframe by DataType // Creates the time series, listed by data type 
| render timechart // Renders results in a timechart

In de resulterende grafiek ziet u duidelijk enkele afwijkingen, bijvoorbeeld in de AzureDiagnostics gegevenstypen en SecurityEvent :

Een GIF-animatie met een grafiek van de totale gegevens die elke dag gedurende 21 dagen door elke tabel in de werkruimte worden opgenomen. De cursor wordt verplaatst om drie gebruiksafwijkingen in de grafiek te markeren.

Vervolgens gebruiken we een KQL-functie om alle afwijkingen in een tijdreeks weer te geven.

Notitie

Zie operator make-series voor meer informatie over make-series de syntaxis en het gebruik.

Afwijkingen in een tijdreeks zoeken

De series_decompose_anomalies() functie gebruikt een reeks waarden als invoer en extraheert afwijkingen.

We geven de resultatenset van onze tijdreeksquery als invoer voor de series_decompose_anomalies() functie:

Klik om de query uit te voeren

let starttime = 21d; // Start date for the time series, counting back from the current date
let endtime = 0d; // End date for the time series, counting back from the current date
let timeframe = 1d; // How often to sample data
Usage // The table we’re analyzing
| where TimeGenerated between (startofday(ago(starttime))..startofday(ago(endtime))) // Time range for the query, beginning at 12:00 AM of the first day and ending at 12:00 AM of the last day in the time range
| where IsBillable == "true" // Includes only billable data in the result set
| make-series ActualUsage=sum(Quantity) default = 0 on TimeGenerated from startofday(ago(starttime)) to startofday(ago(endtime)) step timeframe by DataType // Creates the time series, listed by data type
| extend(Anomalies, AnomalyScore, ExpectedUsage) = series_decompose_anomalies(ActualUsage) // Scores and extracts anomalies based on the output of make-series 
| mv-expand ActualUsage to typeof(double), TimeGenerated to typeof(datetime), Anomalies to typeof(double),AnomalyScore to typeof(double), ExpectedUsage to typeof(long) // Expands the array created by series_decompose_anomalies()
| where Anomalies != 0  // Returns all positive and negative deviations from expected usage
| project TimeGenerated,ActualUsage,ExpectedUsage,AnomalyScore,Anomalies,DataType // Defines which columns to return 
| sort by abs(AnomalyScore) desc // Sorts results by anomaly score in descending ordering

Deze query retourneert alle gebruiksafwijkingen voor alle tabellen in de afgelopen drie weken:

Een schermopname van een tabel met een lijst met afwijkingen in het gebruik voor alle tabellen in de werkruimte.

Als u de queryresultaten bekijkt, ziet u dat de functie:

  • Berekent het verwachte dagelijkse gebruik voor elke tabel.
  • Vergelijkt het werkelijke dagelijkse gebruik met het verwachte gebruik.
  • Wijst een anomaliescore toe aan elk gegevenspunt, waarmee de mate van de afwijking van het werkelijke gebruik ten opzichte van het verwachte gebruik wordt aangegeven.
  • Identificeert positieve (1) en negatieve (-1) afwijkingen in elke tabel.

Notitie

Zie series_decompose_anomalies() voor meer informatie over series_decompose_anomalies() syntaxis en gebruik.

Instellingen voor anomaliedetectie aanpassen om resultaten te verfijnen

Het is raadzaam om de eerste queryresultaten te bekijken en de query zo nodig aan te passen. Uitbijters in invoergegevens kunnen van invloed zijn op het leren van de functie en mogelijk moet u de instellingen voor anomaliedetectie van de functie aanpassen om nauwkeurigere resultaten te krijgen.

Filter de resultaten van de series_decompose_anomalies() query op afwijkingen in het AzureDiagnostics gegevenstype:

Een tabel met de resultaten van de anomaliedetectiequery, gefilterd op resultaten van het gegevenstype Azure Diagnostics.

De resultaten tonen twee afwijkingen op 14 en 15 juni. Vergelijk deze resultaten met de grafiek uit onze eerste make-series query, waar u andere afwijkingen kunt zien op 27 en 28 mei:

Een schermopname van een grafiek met het totale aantal gegevens dat is opgenomen door de Azure Diagnostics tabel met afwijkingen gemarkeerd.

Het verschil in resultaten treedt op omdat de series_decompose_anomalies() functie scores afwijkingen ten opzichte van de verwachte gebruikswaarde, die de functie berekent op basis van het volledige bereik van waarden in de invoerreeks.

Als u meer verfijnde resultaten van de functie wilt krijgen, sluit u het gebruik op 15 juni uit van het leerproces van de functie, wat een uitbijter is ten opzichte van de andere waarden in de reeks.

De syntaxis van de series_decompose_anomalies() functie is:

series_decompose_anomalies (Series[Threshold,Seasonality,Trend,Test_points,AD_method,Seasonality_threshold])

Test_points geeft het aantal punten aan het einde van de reeks op dat moet worden uitgesloten van het leerproces (regressie).

Als u het laatste gegevenspunt wilt uitsluiten, stelt u in Test_points op 1:

Klik om de query uit te voeren

let starttime = 21d; // Start date for the time series, counting back from the current date
let endtime = 0d; // End date for the time series, counting back from the current date
let timeframe = 1d; // How often to sample data
Usage // The table we’re analyzing
| where TimeGenerated between (startofday(ago(starttime))..startofday(ago(endtime))) // Time range for the query, beginning at 12:00 AM of the first day and ending at 12:00 AM of the last day in the time range
| where IsBillable == "true" // Includes only billable data in the result set
| make-series ActualUsage=sum(Quantity) default = 0 on TimeGenerated from startofday(ago(starttime)) to startofday(ago(endtime)) step timeframe by DataType // Creates the time series, listed by data type
| extend(Anomalies, AnomalyScore, ExpectedUsage) = series_decompose_anomalies(ActualUsage,1.5,-1,'avg',1) // Scores and extracts anomalies based on the output of make-series, excluding the last value in the series - the Threshold, Seasonality, and Trend input values are the default values for the function 
| mv-expand ActualUsage to typeof(double), TimeGenerated to typeof(datetime), Anomalies to typeof(double),AnomalyScore to typeof(double), ExpectedUsage to typeof(long) // Expands the array created by series_decompose_anomalies()
| where Anomalies != 0  // Returns all positive and negative deviations from expected usage
| project TimeGenerated,ActualUsage,ExpectedUsage,AnomalyScore,Anomalies,DataType // Defines which columns to return 
| sort by abs(AnomalyScore) desc // Sorts results by anomaly score in descending ordering

Filter de resultaten op het AzureDiagnostics gegevenstype:

Een tabel met de resultaten van de gewijzigde anomaliedetectiequery, gefilterd op resultaten van het gegevenstype Azure Diagnostics. De resultaten tonen nu dezelfde afwijkingen als de grafiek die aan het begin van de zelfstudie is gemaakt.

Alle afwijkingen in de grafiek van onze eerste make-series query worden nu weergegeven in de resultatenset.

De hoofdoorzaak van afwijkingen analyseren

Als u verwachte waarden vergelijkt met afwijkende waarden, krijgt u inzicht in de oorzaak van de verschillen tussen de twee sets.

De KQL-invoegtoepassing diffpatterns() vergelijkt twee gegevenssets met dezelfde structuur en vindt patronen die verschillen tussen de twee gegevenssets kenmerken.

Met deze query wordt het gebruik op 15 juni, de extreme uitbijter in ons voorbeeld, vergeleken AzureDiagnostics met het tabelgebruik op andere dagen:

Klik om de query uit te voeren

let starttime = 21d; // Start date for the time series, counting back from the current date
let endtime = 0d; // End date for the time series, counting back from the current date
let anomalyDate = datetime_add('day',-1, make_datetime(startofday(ago(endtime)))); // Start of day of the anomaly date, which is the last full day in the time range in our example (you can replace this with a specific hard-coded anomaly date)
AzureDiagnostics	
| extend AnomalyDate = iff(startofday(TimeGenerated) == anomalyDate, "AnomalyDate", "OtherDates") // Adds calculated column called AnomalyDate, which splits the result set into two data sets – AnomalyDate and OtherDates
| where TimeGenerated between (startofday(ago(starttime))..startofday(ago(endtime))) // Defines the time range for the query
| project AnomalyDate, Resource // Defines which columns to return
| evaluate diffpatterns(AnomalyDate, "OtherDates", "AnomalyDate") // Compares usage on the anomaly date with the regular usage pattern

De query identificeert elke vermelding in de tabel als op AnomalyDate (15 juni) of OtherDates. De diffpatterns() invoegtoepassing splitst vervolgens deze gegevenssets ( A (OtherDates in ons voorbeeld) en B (AnomalyDate in ons voorbeeld) genoemd - en retourneert enkele patronen die bijdragen aan de verschillen in de twee sets:

Een schermopname van een tabel met drie rijen. Elke rij toont een verschil tussen het gebruik op het afwijkende gebruik en het basislijngebruik.

Als u de queryresultaten bekijkt, ziet u de volgende verschillen:

  • Er zijn 24.892.147 exemplaren van opname van de CH1-GEARAMAAKS-resource op alle andere dagen in het querytijdbereik en geen gegevens opgenomen uit deze resource op 15 juni. Gegevens van de CH1-GEARAMAAKS-resource zijn goed voor 73,36% van de totale opname op andere dagen in het tijdsbereik van de query en 0% van de totale opname op 15 juni.
  • Er zijn 2.168.448 exemplaren van opname uit de NSG-TESTSQLMI519-resource op alle andere dagen in het querytijdbereik en 110.544 exemplaren van opname uit deze resource op 15 juni. Gegevens van de NSG-TESTSQLMI519-resource zijn goed voor 6,39% van de totale opname op andere dagen in het bereik van de querytijd en 25,61% van de opname op 15 juni.

U ziet dat er gemiddeld 108.422 exemplaren van opname zijn van de NSG-TESTSQLMI519-resource gedurende de 20 dagen waaruit de andere dagenperiode bestaat (deel 2.168.448 door 20). Daarom verschilt de opname van de NSG-TESTSQLMI519-resource op 15 juni niet significant van de opname van deze resource op andere dagen. Omdat er echter geen opname is van CH1-GEARAMAAKS op 15 juni, vormt de opname van NSG-TESTSQLMI519 een aanzienlijk hoger percentage van de totale opname op de anomaliedatum in vergelijking met andere dagen.

De kolom PercentDiffAB toont het absolute procentpuntverschil tussen A en B (|PercentA - PercentB|), de belangrijkste maateenheid voor het verschil tussen de twee sets. Standaard retourneert de diffpatterns() invoegtoepassing een verschil van meer dan 5% tussen de twee gegevenssets, maar u kunt deze drempelwaarde aanpassen. Als u bijvoorbeeld alleen verschillen van 20% of meer tussen de twee gegevenssets wilt retourneren, kunt u instellen | evaluate diffpatterns(AnomalyDate, "OtherDates", "AnomalyDate", "~", 0.20) in de bovenstaande query. De query retourneert nu slechts één resultaat:

Een schermopname van een tabel met één rij waarin een verschil wordt weergegeven tussen het gebruik op het afwijkende gebruik en het basislijngebruik. Deze keer heeft de query geen verschillen van minder dan 20 procent tussen de twee gegevenssets geretourneerd.

Notitie

Zie de invoegtoepassing voor diffpatronen voor meer informatie over diffpatterns() de syntaxis en het gebruik.

Volgende stappen

Meer informatie over: