ChristianSardo commited on
Commit
b51df68
·
verified ·
1 Parent(s): 35ae1e9

Upload 7 files

Browse files
Files changed (7) hide show
  1. Dockerfile +0 -0
  2. README +15 -0
  3. Script.py +35 -0
  4. app.py +29 -9
  5. bimboca.csv +51 -0
  6. requirements.txt +7 -0
  7. train.py +51 -0
Dockerfile ADDED
File without changes
README ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🚀 API de Detecção de Anomalias - JMeter
2
+
3
+ Este Space implementa uma **API FastAPI** para detectar anomalias em testes de carga.
4
+
5
+ ## ▶ Funcionalidades
6
+
7
+ - Treina baseline com `resultados_carga_normal.csv`
8
+ - Valida com `resultados_carga_anomala.csv`
9
+ - API `/upload` para classificar novos CSVs
10
+ - Retorna:
11
+ - % de anomalias
12
+ - se disparou alerta (>5%)
13
+
14
+ ## ▶ Como rodar treinamento no Space
15
+
Script.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from huggingface_hub import HfApi, create_repo, upload_file
2
+
3
+ # -------------------------------------------
4
+ # CONFIGURAÇÕES
5
+ # -------------------------------------------
6
+
7
+
8
+ REPO_NAME = "ChristianSardo/bimboca-dataset" # Ex: christian-sardo/bimboca-dataset
9
+ LOCAL_FILE_PATH = r"C:\Users\christian_sardo\Documents\ra\bimboca.csv"
10
+ REMOTE_PATH = "bimboca.csv" # Nome do arquivo no hub
11
+
12
+ # -------------------------------------------
13
+ # EXECUÇÃO
14
+ # -------------------------------------------
15
+
16
+ api = HfApi()
17
+
18
+ # Criar repo se não existir
19
+ try:
20
+ create_repo(repo_id=REPO_NAME, token=HF_TOKEN, repo_type="dataset")
21
+ print(f"Repositório criado: https://huggingface.co/datasets/{REPO_NAME}")
22
+ except Exception as e:
23
+ print(f"Repo já existe ou outro aviso: {e}")
24
+
25
+ # Upload do arquivo
26
+ upload_file(
27
+ token=HF_TOKEN,
28
+ path_or_fileobj=LOCAL_FILE_PATH,
29
+ repo_id=REPO_NAME,
30
+ repo_type="dataset",
31
+ path_in_repo=REMOTE_PATH
32
+ )
33
+
34
+ print("Upload completo!")
35
+ print(f"Dataset disponível em: https://huggingface.co/datasets/{REPO_NAME}")
app.py CHANGED
@@ -3,27 +3,47 @@ import pandas as pd
3
  import joblib
4
  from io import BytesIO
5
 
6
- app = FastAPI()
 
 
 
 
 
 
 
 
 
 
 
7
 
8
- model = joblib.load("modelo_anomalia.pkl")
9
 
10
  @app.get("/")
11
  def home():
12
- return {"status": "API FastAPI rodando no Hugging Face!"}
 
 
 
 
13
 
14
- @app.post("/classify")
15
- async def classify_csv(file: UploadFile = File(...)):
 
16
  content = await file.read()
17
  df = pd.read_csv(BytesIO(content))
18
 
19
- X = df[["elapsed", "success"]]
20
  preds = model.predict(X)
21
 
 
 
22
  percent_anom = (preds == -1).mean() * 100
23
 
 
 
24
  return {
25
- "anomalias": int((preds == -1).sum()),
26
  "total": len(df),
27
- "percentual": percent_anom,
28
- "limite": percent_anom > 5
 
 
29
  }
 
3
  import joblib
4
  from io import BytesIO
5
 
6
+ app = FastAPI(title="Detecção de Anomalias JMeter")
7
+
8
+ MODEL_PATH = "modelo_anomalia.pkl"
9
+
10
+ # Carrega o modelo na inicialização
11
+ model = joblib.load(MODEL_PATH)
12
+
13
+
14
+ def preprocess(df):
15
+ if df["success"].dtype == object:
16
+ df["success"] = df["success"].map(lambda x: 1 if str(x).lower() == "true" else 0)
17
+ return df[["elapsed", "success"]]
18
 
 
19
 
20
  @app.get("/")
21
  def home():
22
+ return {
23
+ "status": "online",
24
+ "msg": "API de detecção de anomalias está funcionando!",
25
+ "rota_upload": "/upload"
26
+ }
27
 
28
+
29
+ @app.post("/upload")
30
+ async def classify(file: UploadFile = File(...)):
31
  content = await file.read()
32
  df = pd.read_csv(BytesIO(content))
33
 
34
+ X = preprocess(df)
35
  preds = model.predict(X)
36
 
37
+ df["anomalia"] = preds
38
+
39
  percent_anom = (preds == -1).mean() * 100
40
 
41
+ alerta = percent_anom > 5
42
+
43
  return {
 
44
  "total": len(df),
45
+ "anomalias": int((preds == -1).sum()),
46
+ "percentual_anomalias": percent_anom,
47
+ "alerta": alerta,
48
+ "limite": "Ultrapassado (>5%)" if alerta else "Normal",
49
  }
bimboca.csv ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect
2
+ 1764196174810,1401,transacao,200,OK,Thread Group 1-1,text,true,,3612,0,3,3,https://dev-finance.netlify.app/#,0,0,0
3
+ 1764196174810,1443,transacao,200,OK,Thread Group 1-2,text,true,,3612,0,4,4,https://dev-finance.netlify.app/#,0,0,0
4
+ 1764196175715,855,transacao,200,OK,Thread Group 1-3,text,true,,3612,0,4,4,https://dev-finance.netlify.app/#,0,0,0
5
+ 1764196177358,879,transacao,200,OK,Thread Group 1-4,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
6
+ 1764196178046,696,transacao,200,OK,Thread Group 1-5,text,true,,3612,0,3,3,https://dev-finance.netlify.app/#,0,0,0
7
+ 1764196179305,679,transacao,200,OK,Thread Group 1-6,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
8
+ 1764196180452,673,transacao,200,OK,Thread Group 1-7,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
9
+ 1764196181669,723,transacao,200,OK,Thread Group 1-8,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
10
+ 1764196182884,651,transacao,200,OK,Thread Group 1-9,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
11
+ 1764196184104,641,transacao,200,OK,Thread Group 1-10,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
12
+ 1764196185225,659,transacao,200,OK,Thread Group 1-11,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
13
+ 1764196186443,1161,transacao,200,OK,Thread Group 1-12,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
14
+ 1764196187686,1295,transacao,200,OK,Thread Group 1-13,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
15
+ 1764196188907,674,transacao,200,OK,Thread Group 1-14,text,true,,3612,0,3,3,https://dev-finance.netlify.app/#,0,0,0
16
+ 1764196190084,699,transacao,200,OK,Thread Group 1-15,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
17
+ 1764196191306,826,transacao,200,OK,Thread Group 1-16,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
18
+ 1764196192438,645,transacao,200,OK,Thread Group 1-17,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
19
+ 1764196193641,656,transacao,200,OK,Thread Group 1-18,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
20
+ 1764196194834,629,transacao,200,OK,Thread Group 1-19,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
21
+ 1764196196019,675,transacao,200,OK,Thread Group 1-20,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
22
+ 1764196197254,723,transacao,200,OK,Thread Group 1-21,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
23
+ 1764196198436,681,transacao,200,OK,Thread Group 1-22,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
24
+ 1764196199617,645,transacao,200,OK,Thread Group 1-23,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
25
+ 1764196200852,674,transacao,200,OK,Thread Group 1-24,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
26
+ 1764196202089,1465,transacao,200,OK,Thread Group 1-25,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
27
+ 1764196203203,707,transacao,200,OK,Thread Group 1-26,text,true,,3612,0,3,3,https://dev-finance.netlify.app/#,0,0,0
28
+ 1764196204435,671,transacao,200,OK,Thread Group 1-27,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
29
+ 1764196205768,727,transacao,200,OK,Thread Group 1-28,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
30
+ 1764196206851,752,transacao,200,OK,Thread Group 1-29,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
31
+ 1764196208034,654,transacao,200,OK,Thread Group 1-30,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
32
+ 1764196209262,660,transacao,200,OK,Thread Group 1-31,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
33
+ 1764196210451,668,transacao,200,OK,Thread Group 1-32,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
34
+ 1764196211703,668,transacao,200,OK,Thread Group 1-33,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
35
+ 1764196212885,733,transacao,200,OK,Thread Group 1-34,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
36
+ 1764196214036,676,transacao,200,OK,Thread Group 1-35,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
37
+ 1764196215251,634,transacao,200,OK,Thread Group 1-36,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
38
+ 1764196216437,666,transacao,200,OK,Thread Group 1-37,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
39
+ 1764196217656,655,transacao,200,OK,Thread Group 1-38,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
40
+ 1764196218821,662,transacao,200,OK,Thread Group 1-39,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
41
+ 1764196220034,672,transacao,200,OK,Thread Group 1-40,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
42
+ 1764196221288,684,transacao,200,OK,Thread Group 1-41,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
43
+ 1764196222450,697,transacao,200,OK,Thread Group 1-42,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
44
+ 1764196223620,780,transacao,200,OK,Thread Group 1-43,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
45
+ 1764196224886,628,transacao,200,OK,Thread Group 1-44,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
46
+ 1764196226102,690,transacao,200,OK,Thread Group 1-45,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
47
+ 1764196227301,685,transacao,200,OK,Thread Group 1-46,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
48
+ 1764196228484,822,transacao,200,OK,Thread Group 1-47,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
49
+ 1764196229637,708,transacao,200,OK,Thread Group 1-48,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
50
+ 1764196230817,645,transacao,200,OK,Thread Group 1-49,text,true,,3612,0,2,2,https://dev-finance.netlify.app/#,0,0,0
51
+ 1764196232037,625,transacao,200,OK,Thread Group 1-50,text,true,,3612,0,1,1,https://dev-finance.netlify.app/#,0,0,0
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ pandas
4
+ scikit-learn
5
+ joblib
6
+ python-multipart
7
+ matplotlib
train.py ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ from sklearn.ensemble import IsolationForest
3
+ from sklearn.preprocessing import LabelEncoder
4
+ import joblib
5
+
6
+ # ARQUIVOS
7
+ CSV_NORMAL = "resultados_carga_normal.csv"
8
+ CSV_ANORMAL = "resultados_carga_anomala.csv"
9
+ OUTPUT_MODEL = "modelo_anomalia.pkl"
10
+
11
+
12
+ def preprocess(df):
13
+ # Converte success TRUE/FALSE para 1/0 se necessário
14
+ if df["success"].dtype == object:
15
+ df["success"] = df["success"].map(lambda x: 1 if str(x).lower() == "true" else 0)
16
+
17
+ # Apenas colunas importantes
18
+ return df[["elapsed", "success"]]
19
+
20
+
21
+ def train_baseline():
22
+ print("🔵 Treinando baseline com resultados normais...")
23
+
24
+ df = pd.read_csv(CSV_NORMAL)
25
+ X = preprocess(df)
26
+
27
+ model = IsolationForest(contamination=0.05, random_state=42)
28
+ model.fit(X)
29
+
30
+ joblib.dump(model, OUTPUT_MODEL)
31
+ print("✅ Modelo salvo como", OUTPUT_MODEL)
32
+
33
+
34
+ def validate_anomalies():
35
+ print("🔴 Validando com dados anômalos...")
36
+
37
+ df = pd.read_csv(CSV_ANORMAL)
38
+ X = preprocess(df)
39
+
40
+ model = joblib.load(OUTPUT_MODEL)
41
+
42
+ preds = model.predict(X)
43
+
44
+ percent_anom = (preds == -1).mean() * 100
45
+
46
+ print(f"🚨 Percentual de anomalias detectadas: {percent_anom:.2f}%")
47
+
48
+
49
+ if __name__ == "__main__":
50
+ train_baseline()
51
+ validate_anomalies()