Wprowadzenie do zapytań dotyczących dzienników w usłudze Azure Monitor

Uwaga

Jeśli zbierasz dane z co najmniej jednej maszyny wirtualnej, możesz wykonać to ćwiczenie we własnym środowisku. W przypadku innych scenariuszy użyj naszego środowiska demonstracyjnego, które zawiera wiele przykładowych danych.

Jeśli wiesz już, jak wykonywać zapytania w język zapytań Kusto, ale musisz szybko tworzyć przydatne zapytania na podstawie typów zasobów, zobacz zapisane przykładowe okienko zapytań w artykule Korzystanie z zapytań w usłudze Azure Monitor Log Analytics.

Z tego samouczka dowiesz się, jak pisać zapytania dzienników w usłudze Azure Monitor. Ten artykuł zawiera omówienie następujących czynności:

  • Omówienie struktury zapytań.
  • Sortowanie wyników zapytania.
  • Filtruj wyniki zapytania.
  • Określ zakres czasu.
  • Wybierz pola do uwzględnienia w wynikach.
  • Definiowanie i używanie pól niestandardowych.
  • Agregowanie i grupowanie wyników.

Aby zapoznać się z samouczkiem dotyczącym używania usługi Log Analytics w Azure Portal, zobacz Wprowadzenie z usługą Azure Monitor Log Analytics.

Aby uzyskać więcej informacji na temat zapytań dzienników w usłudze Azure Monitor, zobacz Omówienie zapytań dzienników w usłudze Azure Monitor.

Oto wersja wideo tego samouczka:

Pisanie nowego zapytania

Zapytania mogą rozpoczynać się od nazwy tabeli lub polecenia wyszukiwania . Dobrym pomysłem jest rozpoczęcie od nazwy tabeli, ponieważ definiuje jasny zakres zapytania i poprawia zarówno wydajność zapytań, jak i istotność wyników.

Uwaga

W języku zapytań Kusto używanym przez usługę Azure Monitor jest uwzględniana wielkość liter. Słowa kluczowe języka są zwykle pisane małymi literami. W przypadku używania nazw tabel lub kolumn w zapytaniu należy użyć poprawnego przypadku, jak pokazano w okienku schematu.

Zapytania oparte na tabelach

Usługa Azure Monitor organizuje dane dzienników w postaci tabel, z których każda składa się z wielu kolumn. Wszystkie tabele i kolumny są wyświetlane w okienku schematu w usłudze Log Analytics w portalu analizy. Zidentyfikuj tabelę, którą cię interesuje, a następnie przyjrzyj się trochę danych:

SecurityEvent
| take 10

Powyższe zapytanie zwraca 10 wyników z tabeli SecurityEvent bez określonej kolejności. Jest to typowy sposób, aby spojrzeć na tabelę i zrozumieć jej strukturę i zawartość. Przyjrzyjmy się, jak jest ona zbudowana:

  • Zapytanie rozpoczyna się od nazwy tabeli SecurityEvent, która definiuje zakres zapytania.
  • Znak potoku (|) oddziela polecenia, więc dane wyjściowe pierwszego polecenia są danymi wejściowymi następnego. Możesz dodać dowolną liczbę elementów potokowych.
  • Po potoku jest polecenie take , które zwraca określoną liczbę dowolnych rekordów z tabeli.

Możemy uruchomić zapytanie nawet bez dodawania | take 10elementu . Polecenie nadal będzie prawidłowe, ale może zwrócić maksymalnie 10 000 wyników.

Zapytania wyszukiwania

Zapytania wyszukiwania są mniej ustrukturyzowane i zazwyczaj lepiej nadają się do znajdowania rekordów zawierających określoną wartość w dowolnej z ich kolumn:

search in (SecurityEvent) "Cryptographic"
| take 10

To zapytanie wyszukuje w tabeli SecurityEvent rekordy zawierające frazę "Kryptograficzne". Spośród tych rekordów zostanie zwróconych i wyświetlonych 10 rekordów. Jeśli pominiesz in (SecurityEvent) część i uruchomisz tylko search "Cryptographic"element , wyszukiwanie przejdzie do wszystkich tabel, co zajmie więcej czasu i będzie mniej wydajne.

Ważne

Zapytania wyszukiwania są zwykle wolniejsze niż zapytania oparte na tabelach, ponieważ muszą przetwarzać więcej danych.

Sortowanie i góra

Chociaż pobieranie kilku rekordów jest przydatne, wyniki są wybierane i wyświetlane w żadnej określonej kolejności. Aby uzyskać uporządkowany widok, można sortować według preferowanej kolumny:

SecurityEvent	
| sort by TimeGenerated desc

Powyższe zapytanie może jednak zwrócić zbyt wiele wyników i może zająć trochę czasu. Zapytanie sortuje całą tabelę SecurityEvent według kolumny TimeGenerated . Następnie portal analizy ogranicza wyświetlanie tylko do 10 000 rekordów. Takie podejście nie jest oczywiście optymalne.

Najlepszym sposobem uzyskania tylko 10 najnowszych rekordów jest użycie góry, która sortuje całą tabelę po stronie serwera, a następnie zwraca pierwsze rekordy:

SecurityEvent
| top 10 by TimeGenerated

Malejąco jest domyślną kolejnością sortowania, więc zwykle pomija się argument desc . Dane wyjściowe wyglądają następująco:

Screenshot of the top 10 records, sorted in descending order.

Operator where: filtrowanie według warunku

Filtry, zgodnie z ich nazwą, filtrują dane według określonego warunku. Jest to najbardziej typowy sposób ograniczania wyników zapytania do odpowiednich informacji.

Aby dodać filtr do zapytania, użyj operatora where , po którym następuje co najmniej jeden warunki. Na przykład następujące zapytanie zwraca tylko rekordy SecurityEvent , gdzie poziom jest równy 8:

SecurityEvent
| where Level == 8

Podczas pisania warunków filtrowania można użyć następujących wyrażeń:

Wyrażenie Opis Przykład
== Sprawdzanie równości
(z uwzględnieniem wielkości liter)
Level == 8
=~ Sprawdzanie równości
(bez uwzględniania wielkości liter)
EventSourceName =~ "microsoft-windows-security-auditing"
!=, <> Sprawdzanie nierówności
(oba wyrażenia są identyczne)
Level != 4
oraz, lub Wymagane między warunkami Level == 16 or CommandLine != ""

Aby filtrować według wielu warunków, można użyć jednej z następujących metod:

Użyj polecenia i, jak pokazano poniżej:

SecurityEvent
| where Level == 8 and EventID == 4672

Potok wielokrotny , gdzie elementy po drugim, jak pokazano poniżej:

SecurityEvent
| where Level == 8 
| where EventID == 4672

Uwaga

Wartości mogą mieć różne typy, więc może być konieczne rzutowanie ich w celu przeprowadzenia porównań dla poprawnego typu. Na przykład kolumna SecurityEvent Level jest typu Ciąg, więc należy rzutować ją na typ liczbowy, taki jak int lub long, zanim będzie można na nim użyć operatorów liczbowych, jak pokazano poniżej: SecurityEvent | where toint(Level) >= 10

Określanie zakresu czasu

Użyj selektora czasu

Selektor czasu jest wyświetlany obok przycisku Uruchom i wskazuje, że wykonujesz zapytania dotyczące rekordów tylko z ostatnich 24 godzin. Jest to domyślny zakres czasu stosowany do wszystkich zapytań. Aby pobrać rekordy tylko z ostatniej godziny, wybierz pozycję Ostatnia godzina, a następnie ponownie uruchom zapytanie.

Screenshot of the time picker and its list of time-range commands.

Dodawanie filtru czasu do zapytania

Możesz również zdefiniować własny zakres czasu, dodając filtr czasu do zapytania. Najlepiej umieścić filtr czasu bezpośrednio po nazwie tabeli:

SecurityEvent
| where TimeGenerated > ago(30m) 
| where toint(Level) >= 10

W poprzednim filtrze czasu oznacza "30 minut temu", co oznacza, ago(30m) że to zapytanie zwraca rekordy tylko z ostatnich 30 minut (wyrażone na przykład 30 m). Inne jednostki czasu obejmują dni (na przykład 2d) i sekundy (na przykład 10 s).

Używanie projektu i rozszerzanie w celu wybierania i obliczania kolumn

Użyj projektu , aby wybrać określone kolumny do uwzględnienia w wynikach:

SecurityEvent 
| top 10 by TimeGenerated 
| project TimeGenerated, Computer, Activity

Powyższy przykład generuje następujące dane wyjściowe:

Screenshot of the query

Możesz również użyć projektu , aby zmienić nazwy kolumn i zdefiniować nowe. W następnym przykładzie użyto projektu do wykonania następujących czynności:

  • Wybierz tylko kolumny Computer (Komputer) i TimeGenerated (Czasogenerowane ).
  • Wyświetl kolumnę Działanie jako EventDetails.
  • Utwórz nową kolumnę o nazwie EventCode. Funkcja substring() służy do pobierania tylko pierwszych czterech znaków z pola Działanie.
SecurityEvent
| top 10 by TimeGenerated 
| project Computer, TimeGenerated, EventDetails=Activity, EventCode=substring(Activity, 0, 4)

Możesz użyć rozszerzenia , aby zachować wszystkie oryginalne kolumny w zestawie wyników i zdefiniować dodatkowe. Poniższe zapytanie używa rozszerzenia w celu dodania kolumny EventCode . Ta kolumna może nie być wyświetlana na końcu wyników tabeli. W takim przypadku należy rozwinąć szczegóły rekordu, aby go wyświetlić.

SecurityEvent
| top 10 by TimeGenerated
| extend EventCode=substring(Activity, 0, 4)

Używanie podsumowania do agregowania grup wierszy

Użyj podsumowania , aby zidentyfikować grupy rekordów zgodnie z co najmniej jedną kolumną i zastosować do nich agregacje. Najczęstszym zastosowaniem podsumowania jest liczba, która zwraca liczbę wyników w każdej grupie.

Następujące zapytanie przegląda wszystkie rekordy wydajności z ostatniej godziny, grupuje je według objectName i zlicza rekordy w każdej grupie:

Perf
| where TimeGenerated > ago(1h)
| summarize count() by ObjectName

Czasami warto zdefiniować grupy według wielu wymiarów. Każda unikatowa kombinacja tych wartości definiuje oddzielną grupę:

Perf
| where TimeGenerated > ago(1h)
| summarize count() by ObjectName, CounterName

Innym typowym zastosowaniem jest wykonywanie obliczeń matematycznych lub statystycznych w każdej grupie. Poniższy przykład oblicza średnią wartość CounterValue dla każdego komputera:

Perf
| where TimeGenerated > ago(1h)
| summarize avg(CounterValue) by Computer

Niestety wyniki tego zapytania są bez znaczenia, ponieważ mieszamy ze sobą różne liczniki wydajności. Aby wyniki bardziej zrozumiałe, oblicz średnią oddzielnie dla każdej kombinacji CounterName i Computer:

Perf
| where TimeGenerated > ago(1h)
| summarize avg(CounterValue) by Computer, CounterName

Podsumowywanie według kolumny czasowej

Grupowanie wyników może być również oparte na kolumnie czasowej lub innej wartości ciągłej. Po prostu podsumowywał by TimeGenerated, jednak tworzyłoby grupy dla każdego milisekundy w zakresie czasu, ponieważ są to unikatowe wartości.

Aby utworzyć grupy oparte na wartościach ciągłych, najlepiej podzielić zakres na możliwe do zarządzania jednostki przy użyciu pojemnika. Poniższe zapytanie analizuje rekordy wydajności , które mierzą ilość wolnej pamięci (dostępne bajty MBytes) na określonym komputerze. Oblicza średnią wartość każdego okresu 1-godzinnego w ciągu ostatnich 7 dni:

Perf 
| where TimeGenerated > ago(7d)
| where Computer == "ContosoAzADDS2" 
| where CounterName == "Available MBytes" 
| summarize avg(CounterValue) by bin(TimeGenerated, 1h)

Aby wyczyszczać dane wyjściowe, możesz wybrać, aby wyświetlić go jako wykres czasu, który pokazuje dostępną pamięć w czasie:

Screenshot displaying the values of a query memory over time.

Następne kroki