Oktatóanyag: Anomáliák észlelése és elemzése KQL gépi tanulási képességek használatával az Azure Monitorban
A Kusto lekérdezésnyelv (KQL) gépi tanulási operátorokat, függvényeket és beépülő modulokat tartalmaz az idősorozat-elemzéshez, az anomáliadetektáláshoz, az előrejelzéshez és a kiváltó okok elemzéséhez. Ezekkel a KQL-képességekkel fejlett adatelemzést végezhet az Azure Monitorban anélkül, hogy az adatok külső gépi tanulási eszközökbe való exportálása többletterhelést okozna.
Ebben az oktatóanyagban az alábbiakkal fog megismerkedni:
- Idősor létrehozása
- Idősor rendellenességeinek azonosítása
- Anomáliadetektálási beállítások finomítása az eredmények finomításához
- Az anomáliák kiváltó okának elemzése
Feljegyzés
Ez az oktatóanyag egy Log Analytics-bemutatókörnyezetre mutató hivatkozásokat tartalmaz, amelyekben a KQL-lekérdezési példákat futtathatja. A demókörnyezet adatai dinamikusak, így a lekérdezés eredményei nem ugyanazok, mint a cikkben bemutatott lekérdezési eredmények. Azonban ugyanazokat a KQL-lekérdezéseket és -tagokat implementálhatja a saját környezetében és az összes KQL-t használó Azure Monitor-eszközben.
Előfeltételek
- Egy Azure-fiók, aktív előfizetéssel. Fiók ingyenes létrehozása.
- Naplóadatokat tartalmazó munkaterület.
A szükséges engedélyek
Engedélyekkel kell rendelkeznie Microsoft.OperationalInsights/workspaces/query/*/read
a lekérdezett Log Analytics-munkaterületekhez, például a Log Analytics-olvasó beépített szerepkörének megfelelően.
Idősor létrehozása
A KQL-operátor make-series
használatával hozzon létre egy idősort.
Hozzunk létre egy idősort a Használati táblában lévő naplók alapján, amely információkat tartalmaz arról, hogy a munkaterület egyes táblái mennyi adatot töltnek be óránként, beleértve a számlázható és a nem számlázható adatokat is.
Ez a lekérdezés a munkaterület egyes táblái által naponta betöltött számlázható adatok teljes mennyiségét ábrázolja make-series
az elmúlt 21 napban:
Kattintson ide a lekérdezés futtatásához
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
Az eredményül kapott diagramon jól látható néhány anomália – például az adattípusok és SecurityEvent
az AzureDiagnostics
adattípusok:
Ezután egy KQL-függvény használatával listázzuk az idősorok összes rendellenességét.
Feljegyzés
A szintaxissal és a használattal kapcsolatos make-series
további információkért tekintse meg a sorozat operátorát.
Anomáliák keresése idősorokban
A series_decompose_anomalies()
függvény bemenetként értéksorozatot vesz fel, és anomáliákat nyer ki.
Adja meg az idősoros lekérdezés eredményhalmazát a series_decompose_anomalies()
függvény bemeneteként:
Kattintson ide a lekérdezés futtatásához
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
Ez a lekérdezés az elmúlt három hét összes táblájának összes használati rendellenességét visszaadja:
A lekérdezés eredményeit tekintve láthatja, hogy a függvény:
- Kiszámítja az egyes táblák várható napi használatát.
- Összehasonlítja a tényleges napi használatot a várt használattal.
- Minden adatponthoz hozzárendel egy anomáliapontot, amely a tényleges használat és a várt használat közötti eltérés mértékét jelzi.
- Az egyes táblák pozitív (
1
) és negatív (-1
) anomáliáit azonosítja.
Feljegyzés
A szintaxissal és a használattal kapcsolatos series_decompose_anomalies()
további információkért lásd: series_decompose_anomalies().
Anomáliadetektálási beállítások finomítása az eredmények finomításához
Célszerű áttekinteni a kezdeti lekérdezési eredményeket, és szükség esetén módosítani a lekérdezést. A bemeneti adatokban lévő kiugró értékek hatással lehetnek a függvény tanulására, és előfordulhat, hogy a függvény anomáliadetektálási beállításait módosítania kell a pontosabb eredmények eléréséhez.
Szűrje a lekérdezés eredményeit az series_decompose_anomalies()
adattípus rendellenességeihez AzureDiagnostics
:
Az eredmények két rendellenességet mutatnak június 14-én és június 15-én. Hasonlítsa össze ezeket az eredményeket az első make-series
lekérdezésünk diagramjával, ahol más rendellenességeket is láthat május 27-én és 28-án:
Az eredmények közötti különbség azért fordul elő, mert a függvény a series_decompose_anomalies()
várt használati értékhez képest anomáliákat ad vissza, amelyet a függvény a bemeneti adatsor értékeinek teljes tartománya alapján számít ki.
Ha pontosabb eredményeket szeretne kapni a függvényből, zárja ki a június 15-i használatot – ami a sorozat többi értékéhez képest kiugró érték – a függvény tanulási folyamatából.
A függvény szintaxisa series_decompose_anomalies()
a következő:
series_decompose_anomalies (Series[Threshold,Seasonality,Trend,Test_points,AD_method,Seasonality_threshold])
Test_points
a sorozat végén található azon pontok számát határozza meg, amelyeket ki szeretne zárni a tanulási (regressziós) folyamatból.
Az utolsó adatpont kizárásához állítsa a Test_points
következőre 1
:
Kattintson ide a lekérdezés futtatásához
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
Az adattípus eredményeinek szűrése AzureDiagnostics
:
Az első make-series
lekérdezésből származó diagram összes rendellenessége megjelenik az eredményhalmazban.
Az anomáliák kiváltó okának elemzése
A várt értékek és a rendellenes értékek összehasonlítása segít megérteni a két halmaz közötti különbségek okát.
A KQL diffpatterns()
beépülő modul két azonos szerkezetű adatkészletet hasonlít össze, és olyan mintákat keres, amelyek a két adatkészlet közötti különbségeket jellemzik.
Ez a lekérdezés összehasonlítja AzureDiagnostics
a június 15-i használatot, a példánkban szereplő szélsőséges kiugró értékeket a táblahasználattal a többi napon:
Kattintson ide a lekérdezés futtatásához
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
A lekérdezés azonosítja a táblában lévő összes bejegyzést az AnomalyDate (június 15.) vagy OtherDates szerint. A diffpatterns()
beépülő modul ezután felosztja ezeket az adatkészleteket – a példánkban A (Példánkban az OtherDates ) és a B (AnomalyDate a példában) – és visszaad néhány mintát, amelyek hozzájárulnak a két csoport közötti különbségekhez:
A lekérdezés eredményeit tekintve a következő különbségek láthatók:
- A CH1-GEARAMAAKS erőforrásból 24 892 147 betöltési példány található a lekérdezési időtartomány minden más napján, és június 15-én nem történt adatbetöltés ebből az erőforrásból. A CH1-GEARAMAAKS erőforrás adatai a lekérdezési időtartományban a többi napon a teljes betöltés 73,36%-át, június 15-én pedig a teljes betöltés 0%-át ják.
- A lekérdezési időtartományban az NSG-TESTSQLMI519 erőforrásból 2 168 448 betöltési példány, június 15-én pedig 110 544 betöltési példány található ebből az erőforrásból. Az NSG-TESTSQLMI519 erőforrás adatai a lekérdezési időtartományban a többi napon a teljes betöltés 6,39%-át, június 15-én pedig a betöltés 25,61%-át foglalják el.
Figyelje meg, hogy az NSG-TESTSQLMI519 erőforrásból átlagosan 108 422 betöltési példány van a többi napot alkotó 20 nap alatt (2 168 448 osztva 20-tal). Ezért az NSG-TESTSQLMI519 erőforrás június 15-i betöltése nem különbözik jelentősen az erőforrás más napokon történő betöltésétől. Mivel azonban június 15-én nem történt betöltés a CH1-GEARAMAAKS-ből , az NSG-TESTSQLMI519 betöltése a többi naphoz képest jelentősen nagyobb százalékot tesz ki az anomáliában.
A PercentDiffAB oszlop az A és B (|PercentA – PercentB|), amely a két halmaz közötti különbség fő mértéke. A beépülő modul alapértelmezés szerint diffpatterns()
több mint 5%-os különbséget ad vissza a két adathalmaz között, de ezt a küszöbértéket módosíthatja. Ha például csak 20%-os vagy annál nagyobb különbségeket szeretne visszaadni a két adathalmaz között, a fenti lekérdezésben állíthatja be | evaluate diffpatterns(AnomalyDate, "OtherDates", "AnomalyDate", "~", 0.20)
. A lekérdezés most csak egy eredményt ad vissza:
Feljegyzés
A szintaxissal és a használattal kapcsolatos diffpatterns()
további információkért lásd a diff patterns beépülő modult.
Következő lépések
További információk: