Udostępnij za pośrednictwem


log_reduce_fl()

Funkcja log_reduce_fl() znajduje typowe wzorce w częściowo ustrukturyzowanych kolumnach tekstowych, takich jak wiersze dziennika i klastruje wiersze zgodnie z wyodrębnionym wzorcem. Zwraca ona tabelę podsumowania zawierającą znalezione wzorce posortowane od góry według odpowiedniej częstotliwości.

Wymagania wstępne

  • Wtyczka języka Python musi być włączona w klastrze. Jest to wymagane w przypadku wbudowanego języka Python używanego w funkcji .
  • Wtyczka języka Python musi być włączona w bazie danych. Jest to wymagane w przypadku wbudowanego języka Python używanego w funkcji .

Składnia

T|invokelog_reduce_fl(reduce_col [,use_logram [,use_drain [,custom_regexes [,custom_regexes_policy [,ograniczniki [,similarity_th [,tree_depth [trigram_th [,,bigram_th ]]]]]]]]])

Dowiedz się więcej o konwencjach składniowych.

Parametry

Poniższy opis parametrów jest podsumowaniem. Aby uzyskać więcej informacji, zobacz sekcję Więcej informacji na temat algorytmu .

Nazwa Typ Wymagane Opis
reduce_col string ✔️ Nazwa kolumny ciągu, do których jest stosowana funkcja.
use_logram bool Włącz lub wyłącz algorytm Logramu. Wartość domyślna to true.
use_drain bool Włącz lub wyłącz algorytm opróżniania. Wartość domyślna to true.
custom_regexes dynamic Tablica dynamiczna zawierająca pary wyrażeń regularnych i symboli zastępczych, które mają być przeszukiwane w każdym wierszu wejściowym, i zastąpiona odpowiednim symbolem dopasowania. Wartość domyślna to dynamic([]). Domyślna tabela wyrażeń regularnych zastępuje liczby, adresy IP i identyfikatory GUID.
custom_regexes_policy string Albo "prepend", "append" lub "replace". Określa, czy custom_regexes są prepend/append/replace domyślnych. Wartość domyślna to "prepend".
Ograniczniki dynamic Tablica dynamiczna zawierająca ciągi ograniczników. Wartość domyślna to dynamic([" "]), definiując spację jako jedyny ogranicznik pojedynczego znaku.
similarity_th real Próg podobieństwa używany przez algorytm opróżniania. Zwiększenie similarity_th powoduje zwiększenie udoskonaleń klastrów. Wartość domyślna to 0,5. Jeśli opróżnianie jest wyłączone, ten parametr nie ma efektu.
tree_depth int Zwiększenie tree_depth poprawia środowisko uruchomieniowe algorytmu opróżniania, ale może zmniejszyć jego dokładność. Wartość domyślna to 4. Jeśli opróżnianie jest wyłączone, ten parametr nie ma efektu.
trigram_th int Zmniejszenie trigram_th zwiększa prawdopodobieństwo, że Logram zastąpi tokeny symbolami wieloznacznymi. Wartość domyślna to 10. Jeśli Logram jest wyłączony, ten parametr nie ma efektu.
bigram_th int Zmniejszenie bigram_th zwiększa prawdopodobieństwo, że Logram zastąpi tokeny symbolami wieloznacznymi. Wartość domyślna to 15. Jeśli Logram jest wyłączony, ten parametr nie ma efektu.

Więcej informacji o algorytmie

Funkcja uruchamia wiele przejść przez wiersze, które mają zostać zredukowane do typowych wzorców. Poniższa lista zawiera opis przebiegów:

  • Zamiany wyrażeń regularnych: w tym przebiegu każdy wiersz jest niezależnie dopasowywany do zestawu wyrażeń regularnych, a każde dopasowane wyrażenie jest zastępowane symbolem zastępczym. Domyślne wyrażenia regularne zastępują adresy IP, liczby i identyfikatory GUID /<IP>, <GUID> i /<NUM>. Użytkownik może prepend/append więcej wyrażeń regularnych do tych lub zastąpić je nowymi lub pustymi listami, modyfikując custom_regexes i custom_regexes_policy. Aby na przykład zastąpić liczby całkowite zestawem <WNUM> custom_regexes=pack_array('/^\d+$/', '<WNUM>'); aby anulować zestaw zastępczy wyrażeń regularnych custom_regexes_policy='replace'". Dla każdego wiersza funkcja przechowuje listę oryginalnych wyrażeń (przed zamianami) jako parametry ogólnych tokenów zastępczych.

  • Tokenizacja: podobnie jak w poprzednim kroku, każdy wiersz jest przetwarzany niezależnie i podzielony na tokeny na podstawie zestawu ograniczników. Aby na przykład zdefiniować niezgodność dla tokenów przez przecinek, kropkę lub średnik, ograniczniki zestawu średników=pack_array(", ".", ";").

  • Zastosuj algorytm Logramu: to przekazanie jest opcjonalne, oczekujące use_logram jest prawdziwe. Zalecamy używanie Logramu, gdy jest wymagana duża skala, a parametry mogą pojawiać się w pierwszych tokenach wpisu dziennika. OtoH, wyłącz go, gdy wpisy dziennika są krótkie, ponieważ algorytm zwykle zastępuje tokeny symbolami wieloznacznymi zbyt często w takich przypadkach. Algorytm Logramu uwzględnia 3 krotki i 2 krotki tokenów. Jeśli 3 krotki tokenów są wspólne w wierszach dziennika (wydaje się to więcej niż trigram_th razy), prawdopodobnie wszystkie trzy tokeny są częścią wzorca. Jeśli krotka 3 jest rzadka, prawdopodobnie zawiera zmienną, która powinna zostać zastąpiona symbolem wieloznacznymi. W przypadku rzadkich 3 krotki uważamy częstotliwość, z jaką pojawiają się krotki 2-krotki zawarte w krotki 3. Jeśli 2 krotka jest powszechna (występuje więcej niż bigram_th razy), pozostały token prawdopodobnie będzie parametrem, a nie częścią wzorca.
    Algorytm Logramu jest łatwy do zrównania. Wymaga dwóch przechodzi do korpusu dziennika: pierwszy, aby zliczyć częstotliwość każdej krotki 3 i 2 krotki, a drugi do zastosowania logiki opisanej wcześniej do każdego wpisu. Aby zrównoleglizować algorytm, musimy podzielić wpisy dziennika tylko na partycje i ujednolicić liczbę częstotliwości różnych procesów roboczych.

  • Zastosuj algorytm opróżniania: to przekazanie jest opcjonalne, oczekujące use_drain ma wartość true. Opróżnianie jest algorytmem analizowania dzienników na podstawie obcinanego drzewa prefiksu głębokości. Komunikaty dziennika są dzielone zgodnie z ich długością, a dla każdej długości pierwsze tree_depth tokeny komunikatu dziennika są używane do tworzenia drzewa prefiksów. Jeśli nie znaleziono dopasowania dla tokenów prefiksu, zostanie utworzona nowa gałąź. Jeśli znaleziono dopasowanie dla prefiksu, wyszukujemy najbardziej podobny wzorzec wśród wzorców zawartych w liściu drzewa. Podobieństwo wzorca jest mierzone przez współczynnik dopasowanych tokenów niewildcard ze wszystkich tokenów. Jeśli podobieństwo najbardziej podobnego wzorca przekracza próg podobieństwa (parametr similarity_th), wpis dziennika jest dopasowywany do wzorca. Dla tego wzorca funkcja zastępuje wszystkie niepasujące tokeny przez symbole wieloznaczne. Jeśli podobieństwo najbardziej podobnego wzorca jest poniżej progu podobieństwa, zostanie utworzony nowy wzorzec zawierający wpis dziennika.
    Ustawiliśmy domyślną tree_depth na 4 na podstawie testowania różnych dzienników. Zwiększenie tej głębokości może poprawić środowisko uruchomieniowe, ale może zmniejszyć dokładność wzorców; zmniejszenie jest dokładniejsze, ale wolniejsze, ponieważ każdy węzeł wykonuje o wiele więcej testów podobieństwa.
    Zwykle opróżnianie skutecznie uogólnia i zmniejsza wzorce (choć trudno je zrównać). Jednak ponieważ opiera się on na drzewie prefiksów, może nie być optymalny w wpisach dziennika zawierających parametry w pierwszych tokenach. Można to rozwiązać w większości przypadków, stosując najpierw Logram.

Definicja funkcji

Funkcję można zdefiniować, osadzając jej kod jako funkcję zdefiniowaną przez zapytanie lub tworząc ją jako funkcję przechowywaną w bazie danych w następujący sposób:

Zdefiniuj funkcję przy użyciu następującej instrukcji let. Nie są wymagane żadne uprawnienia.

Ważne

Instrukcja let nie może być uruchamiana samodzielnie. Należy po nim wykonać instrukcję wyrażenia tabelarycznego. Aby uruchomić działający przykład programu log_reduce_fl(), zobacz Przykład.

let log_reduce_fl=(tbl:(*), reduce_col:string,
              use_logram:bool=True, use_drain:bool=True, custom_regexes: dynamic = dynamic([]), custom_regexes_policy: string = 'prepend',
              delimiters:dynamic = dynamic(' '), similarity_th:double=0.5, tree_depth:int = 4, trigram_th:int=10, bigram_th:int=15)
{
    let default_regex_table = pack_array('(/|)([0-9]+\\.){3}[0-9]+(:[0-9]+|)(:|)', '<IP>', 
                                         '([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})', '<GUID>', 
                                         '(?<=[^A-Za-z0-9])(\\-?\\+?\\d+)(?=[^A-Za-z0-9])|[0-9]+$', '<NUM>');
    let kwargs = bag_pack('reduced_column', reduce_col, 'delimiters', delimiters,'output_column', 'LogReduce', 'parameters_column', '', 
                          'trigram_th', trigram_th, 'bigram_th', bigram_th, 'default_regexes', default_regex_table, 
                          'custom_regexes', custom_regexes, 'custom_regexes_policy', custom_regexes_policy, 'tree_depth', tree_depth, 'similarity_th', similarity_th, 
                          'use_drain', use_drain, 'use_logram', use_logram, 'save_regex_tuples_in_output', True, 'regex_tuples_column', 'RegexesColumn', 
                          'output_type', 'summary');
    let code = ```if 1:
        from log_cluster import log_reduce
        result = log_reduce.log_reduce(df, kargs)
    ```;
    tbl
    | extend LogReduce=''
    | evaluate python(typeof(Count:int, LogReduce:string, example:string), code, kwargs)
};
// Write your query to use the function here.

Przykład

W poniższym przykładzie użyto operatora invoke do uruchomienia funkcji. W tym przykładzie użyto rozproszonych dzienników systemu plików Apache Hadoop.

Aby użyć funkcji zdefiniowanej przez zapytanie, wywołaj ją po osadzonej definicji funkcji.

let log_reduce_fl=(tbl:(*), reduce_col:string,
              use_logram:bool=True, use_drain:bool=True, custom_regexes: dynamic = dynamic([]), custom_regexes_policy: string = 'prepend',
              delimiters:dynamic = dynamic(' '), similarity_th:double=0.5, tree_depth:int = 4, trigram_th:int=10, bigram_th:int=15)
{
    let default_regex_table = pack_array('(/|)([0-9]+\\.){3}[0-9]+(:[0-9]+|)(:|)', '\<IP>', 
                                         '([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})', '<GUID>', 
                                         '(?<=[^A-Za-z0-9])(\\-?\\+?\\d+)(?=[^A-Za-z0-9])|[0-9]+$', '\<NUM>');
    let kwargs = bag_pack('reduced_column', reduce_col, 'delimiters', delimiters,'output_column', 'LogReduce', 'parameters_column', '', 
                          'trigram_th', trigram_th, 'bigram_th', bigram_th, 'default_regexes', default_regex_table, 
                          'custom_regexes', custom_regexes, 'custom_regexes_policy', custom_regexes_policy, 'tree_depth', tree_depth, 'similarity_th', similarity_th, 
                          'use_drain', use_drain, 'use_logram', use_logram, 'save_regex_tuples_in_output', True, 'regex_tuples_column', 'RegexesColumn', 
                          'output_type', 'summary');
    let code = ```if 1:
        from log_cluster import log_reduce
        result = log_reduce.log_reduce(df, kargs)
    ```;
    tbl
    | extend LogReduce=''
    | evaluate python(typeof(Count:int, LogReduce:string, example:string), code, kwargs)
};
//
// Finding common patterns in HDFS logs, a commonly used benchmark for log parsing
//
HDFS_log
| take 100000
| invoke log_reduce_fl(reduce_col="data")

Dane wyjściowe

Liczba LogReduce Przykład
55356 081110 <NUM><> INFO dfs. FSNamesystem: BLOCK* NameSystem.delete: blk_<NUM> jest dodawany do nieprawidłowego zestawu adresów <IP> 081110 220623 26 dfs INFO. FSNamesystem: BLOCK* NameSystem.delete: blk_1239016582509138045 jest dodawany do nieprawidłowego zestawu 10.251.123.195:50010
10278 081110 <NUM><> INFO dfs. FSNamesystem: BLOCK* NameSystem.addStoredBlock: blockMap zaktualizowano: <adres IP> jest dodawany do< blk_NUM> size <NUM> 081110 215858 27 INFO dfs. FSNamesystem: BLOCK* NameSystem.addStoredBlock: blockMap zaktualizowano: 10.250.11.85:50010 jest dodawany do rozmiaru blk_5080254298708411681 67108864
10256 081110 <NUM><> INFO dfs. DataNode$PacketResponder: PacketResponder <NUM> dla bloków blk_<NUM> kończących 081110 215858 15496 INFO dfs. DataNode$PacketResponder: PacketResponder 2 dla blk_-7746692545918257727 zakończenia bloku
10256 081110 <NUM><> INFO dfs. DataNode$PacketResponder: Odebrano blok blk_<NUM rozmiaru <NUM>> z <adresu IP> 081110 215858 15485 INFO dfs. DataNode$PacketResponder: Odebrano blk_5080254298708411681 rozmiaru 67108864 z /10.251.43.21
9140 081110 <NUM><> INFO dfs. DataNode$DataXceiver: Odbieranie bloku blk_<NUM> src: <dest IP: <IP>> 081110 215858 15494 INFO dfs. DataNode$DataXceiver: odbieranie bloku blk_-7037346755429293022 src: /10.251.43.21:45933 dest: /10.251.43.21:50010
3047 081110 <NUM><> INFO dfs. FSNamesystem: BLOCK* NameSystem.allocateBlock: /user/root/rand3/temporary/task<NUM><<> m NUM>_<NUM/part-NUM><>. <> 081110 215858 26 INFO dfs. FSNamesystem: BLOCK NameSystem.allocateBlock: /user/root/rand3/_temporary/task_200811101024_0005_m_001805_0/part-01805. blk-7037346755429293022
1402 081110 <NUM><> INFO <>: <> block blk_<NUM<>> <> 081110 215957 15556 INFO dfs. DataNode$DataTransfer: 10.250.15.198:50010:Przetransferowany blok blk_-3782569120714539446 do /10.251.203.129:50010
177 081110 <NUM><> INFO <>: <>><<> <*> 081110 215859 13 INFO dfs. DataBlockScanner: weryfikacja zakończyła się pomyślnie dla blk_-7244926816084627474
36 081110 <NUM><> INFO <>: <><>> <for block <*> 081110 215924 15636 INFO dfs. DataNode$BlockReceiver: odbieranie pustego pakietu dla blk_3991288654265301939 bloku
12 081110 <NUM><> INFO dfs. FSNamesystem: BLOCK* <>><> <> <> <><><> <081110 215953 19 INFO dfs. FSNamesystem: BLOCK* ask 10.250.15.198:50010 do replikacji blk_-3782569120714539446 do węzłów danych 10.251.203.129:50010
12 081110 <INFORMACJE < O NUMERZE NUM>><: <>>>> <<><> <blok blk_<NUM><> <> 081110 215955 18 INFORMACJI dfs. DataNode: 10.250.15.198:50010 Wątek początkowy do transferu bloku blk_-3782569120714539446 do 10.251.203.129:50010
12 081110 <NUM><> INFO dfs. DataNode$DataXceiver: Odebrano blok blk_<NUM> src: <dest IP>> o <rozmiarze <NUM> 081110 215957 15226 INFO dfs. DataNode$DataXceiver: Odebrano blok blk_-3782569120714539446 src: /10.250.15.198:51013 odst: /10.250.15.198:50010 rozmiaru 14474705
6 081110 <NUM NUM><><> dfs. FSNamesystem: BLOCK NameSystem.addStoredBlock: <>> <<><> <<> <> <>>size <NUM> 081110 215924 27 WARN dfs. FSNamesystem: BLOCK* NameSystem.addStoredBlock: Nadmiarowe żądanie addStoredBlock odebrane dla blk_2522553781740514003 w dniu 10.251.202.134:50010 rozmiar 67108864
6 081110 <NUM><> INFO dfs. DataNode$DataXceiver: <>> <<> <<>>: <><><> <>> <081110 215936 15714 INFO dfs. DataNode$DataXceiver: writeBlock blk_720939897861061328 odebrano wyjątek java.io.IOException: Nie można odczytać ze strumienia
3 081110 <NUM><> INFO dfs. FSNamesystem: BLOCK* NameSystem.addStoredBlock: <>><> <<> <<> <>> size <NUM><>><> <<><> <<> <>>. 081110 220635 28 INFO dfs. FSNamesystem: BLOCK NameSystem.addStoredBlock: addStoredBlock żądanie odebrane dla blk_-81196479666306310 w dniu 10.250.17.177:50010 rozmiar 53457811 Ale nie należy do żadnego pliku.
1 081110 <Liczba NUM>>>> <<<:><<>> <> <<><<>> < . .><> <><> <> 081110 220631 19 WARN dfs. FSDataset: Nieoczekiwany błąd podczas próby usunięcia bloku blk_-2012154052725261337. Nie można odnaleźć elementu BlockInfo w woluminieMap.

Ta funkcja nie jest obsługiwana.