import pandas as pd
import re


with open('C:\\Users\\User\\Desktop\\Extending Power BI\\kod\\Extending-Power-BI-with-Python-and-R-main\\Chapter05\\loading-complex-log-files-using-regex\\apache_logs.txt', 'r') as f:
    access_log_lines = f.readlines()

# Zdefiniuj regex dla informacji (zmiennych) zawartych w każdym wierszu logu
regex_parts = [
    r'(?P<hostName>\S+)',                               # nazwa zdalnego hosta (adres IP)
    r'\S+',                                             # zdalna nazwa loga (myślnik, jeśli jest pusty; nie jest używany w przykładowym pliku)
    r'(?P<userName>\S+)',                               # użytkownik zdalny, jeśli żądanie zostało uwierzytelnione (myślnik jeśli jest pusty)
    r'\[(?P<requestDateTime>[\w:/]+\s[+\-]\d{4})\]',    # datetime reprezentujący datę otrzymania żądania w formacie [18/Sep/2011:19:18:28 -0400]
    r'"(?P<requestContent>(\S+)\s?(\S+)?\s?(\S+)?)"',   # pierwszy wiersz żądania wysłanego do serwera między podwójnymi cudzysłowami "%r"
    r'(?P<requestStatus>\d{3}|-)',                      # Kod stanu HTTP dla żądania
    r'(?P<responseSizeBytes>\d+|-)',                    # rozmiar odpowiedzi w bajtach, z wyłączeniem nagłówków HTTP (może być '-')
    r'"(?P<requestReferrer>[^"]*)"',                    # Nagłówek żądania HTTP Referer, który zawiera bezwzględny lub częściowy adres strony wysyłającej żądanie
    r'"(?P<requestAgent>[^"]*)?"',                      # Nagłówek żądania HTTP User-Agent, który zawiera ciąg identyfikujący aplikację, system operacyjny, dostawcę i(lub) wersję żądającego klienta użytkownika
]

# Połącz wszystkie części regex za pomocą '\s+' jako separatora i
# dodaj '$' na końcu
pattern = re.compile(r'\s+'.join(regex_parts) + r'$')

# Odzyskaj dane z każdego wiersza logu do strukturalnego słownika i
# zapisz wszystkie słowniki do listy.
# Zapamiętaj również indeks wiersza w przypadku błędu
log_data = []
lines_error = []

num_errors = 0
num_line = 1

for line in access_log_lines:    
    try:
        # dopasuj wzorzec do wiersza i dołącz do log_data słownik
        # z nazwą grupy jako kluczem i dopasowanym ciągiem jako wartością
        log_data.append(pattern.match(line).groupdict())
    except:
        num_errors += 1
        lines_error.append(num_line)
    
    num_line += 1

# # W przypadku debugowania
# print(f'Błędy: {num_errors}')

# for err_line in lines_error:
#     print(f'Błędy w wierszu: {err_line}')

# Stwórz ramkę danych pandas, zaczynając od listy log_data
df = pd.DataFrame(log_data)
