Leitura e interpretação de arquivos provenientes do log do Webfilter e arquivos JSON

Objetivo

Avaliar performance utilizando como base arquivos de logs já consolidados e testar as libs disponíveis para a leitura e interpretação de arquivos JSON.

O script

Os seguintes ítens foram analisados a partir de logs consolidados do webfilter:

1)Testar leitura de arquivo com 250MB SEM compactação

file_path = "webfilter.log-20220930"

 with open(file_path, encoding="utf-8") as log_file:
   for line in log_file.readlines():
       pass

2)Testar leitura de arquivo com 250MB COM compactação

 import gzip
 file_path = "webfilter.log-20220930.gz"

 with gzip.open(file_path, mode = "rb") as log_file:
   for line in log_file.readlines():
     pass

3)Analisar tempos e performance em cada caso:

Para isso rodamos o time python3 (nome do arquivo) para cada uma das situações.

4)Filtros:

-Criar filtro AÇÃO (accept, deny)

-Criar filtro TOP 10 sites acessados (accept)

-Criar filtro TOP 10 sites negados (deny)

-Criar filtro TOP 10 usuários/IPs de mais acessos (accept)

-Criar filtro TOP 10 usuários/IPs de mais acessos (deny)

import json
import re

file_path = "webfilter.log-20220930"

with open(file_path, encoding="utf-8") as log_file:
    count = {"accept": 0, "deny": 0}
    site = {"accept": {}, "deny": {}}
    users = {"accept": {}, "deny": {}}

    for line in log_file.readlines():
        m = re.search("Ação: (accept|deny)", line)
        if m:
            action = m.group(1)
            count[action] += 1
            m = re.search("Domínio: https*://([^/]+)/", line)
            if m:
                s = m.group(1)
                if s in site[action]:
                    site[action][s] += 1
                else:
                    site[action][s] = 1

            u = re.search("Usuário: (\S+)", line)
            ip = re.search("IP de origem: (\S+)", line)
            if ip:
                i = ip.group(1)
                user = u.group(1)
                i = i + " " + user
                if i in users[action]:
                    users[action][i] += 1
                else:
                    users[action][i] = 1

    for a in ["accept", "deny"]:
        for c in [site, users]:
            ascending_order = {
                k: v for k, v in sorted(c[a].items(), key=lambda i: i[1], reverse=True)
            }
            print(a)
            top = 1
            for k, v in ascending_order.items():
                print(k, v)
                if top == 10:
                    break
                top += 1

    print(count)

Os dados

No link abaixo constam os arquivos que foram utilizados para a análise.

Link dos arquivos: https://drive.google.com/drive/folders/16xESvl7lWOyJaEGhHNzE3Ebk86vHez_O?usp=sharing

Os resultados

Tempos e performance da leitura do arquivo SEM compactação:

0,34s user 0,23s system 98% cpu 0,578 total

Tempos e performance da leitura do arquivo COM compactação:

0,83s user 0,09s system 99% cpu 0,915 total

Tempos e performance dos filtros:

2,05s user 0,16s system 98% cpu 2,236 total

Estudo das libs mais utilizadas no python

Para ler um arquivo JSON via Pandas, é utilizado o método read_json() e passamos o caminho para o arquivo que gostaríamos de ler.

cars_df = pd.read_json('E:/datasets/cars.json')
cars_df.head()

O método retorna um Pandas DataFrame que armazena dados na forma de colunas e linhas. O que não é interessante para o nosso caso específico pois, apenas precisamos organizar e filtrar determinados dados do json e enviar para o front. O mesmo acontece com outras bibliotecas do Python cujo o foco é o gráfico , como matplotlib, Seaborn e Bokeh. Isso ocorre justamente porque o Python suporta JSON nativamente e vem com um pacote embutido chamado json para codificar e decodificar dados JSON. No caso do webfilter especificamente precisamos nos atentar as questões de performance, é necessário otimizar o código e deixa-lo o mais pythonico possível.

Estudo de libs auxiliam na criação de gráficos utilizadas no javascript

Atualmente no webfilter utilizamos o vue-chartjs, que é um pacote para Chart.js no Vue. Com ele podemos criar facilmente componentes de ​gráficos reutilizáveis. É ideal para o nosso produto que precisa de gráficos simples e dinâmicos. Chart.js não fornece uma atualização ao vivo se você alterar os conjuntos de dados. No entanto, vue-chartjs fornece dois mixins para atingir esse objetivo:

reactiveProp reactiveData

Que já estão sendo utilizados no nosso produto. Segue o link da documentação do vue-chartjs: https://vue-chartjs.org/pt-br/guide/#personalizados-novos-graficos

Aqui estão alguns recursos, como tutoriais, sobre como usar vue-chartjs: https://hackernoon.com/creating-stunning-charts-with-vue-js-and-chart-js-28af584adc0a

Para exemplos de como utilizamos o vue-chartjs no front podemos consultar: frontend/admin/src/pages/webfilter/reports/consolidated/components