SlackReporter / app.py
k96beni's picture
Update app.py
e917c55 verified
# slack_reporter/app.py – nyckeltal från nystartad JSONL-logg
import os
import time
import schedule
import pandas as pd
import requests
import logging
import re
from datetime import datetime, timedelta
from huggingface_hub import hf_hub_download
import gradio as gr
# --- Loggning ---
logging.basicConfig(
filename="slack_reporter.log",
level=logging.INFO,
format="%(asctime)s %(levelname)s %(message)s"
)
# --- Konfiguration ---
REPO_ID = "ChargeNodeEurope/logfiles"
LOG_FILENAME = "logs_v2/conversation_log_v2.txt"
WEBHOOK_URL = os.environ.get("SLACK_WEBHOOK_URL")
HF_TOKEN = os.environ.get("HF_TOKEN")
# --- Funktion: Skicka Slack-meddelande med nyckeltal ---
def send_summary_to_slack(summary_text):
payload = {"text": f"📊 Daglig sammanställning:\n{summary_text}"}
try:
response = requests.post(WEBHOOK_URL, json=payload)
logging.info(f"Slack response status: {response.status_code}")
logging.info(f"Slack response text: {response.text}")
response.raise_for_status()
logging.info("Slack-meddelande postat.")
except Exception as e:
logging.error(f"Fel vid Slack-post: {e}", exc_info=True)
raise
# --- Funktion: Bygg nyckeltalstext ---
def generate_summary(df):
now = datetime.now()
yesterday = now - timedelta(days=1)
last_14 = now - timedelta(days=14)
# Konvertera timestamp till datetime
df["timestamp"] = pd.to_datetime(df["timestamp"], errors="coerce")
# Filtrera loggar för senaste 24h och 14 dagar
df_day = df[df["timestamp"] >= yesterday.replace(hour=0, minute=0, second=0)]
df_14 = df[df["timestamp"] >= last_14]
summary = []
summary.append(f"📅 Datum: {now.strftime('%Y-%m-%d')}")
summary.append(f"🗨️ Antal meddelanden senaste 24h: {len(df_day)}")
summary.append(f"👥 Unika sessioner senaste 24h: {df_day['session_id'].nunique()}")
# Beräkna snitt antal meddelanden per session (om minst en session finns)
unique_sessions = df_day['session_id'].nunique()
avg_messages_per_session = round(len(df_day) / unique_sessions, 2) if unique_sessions > 0 else 0
summary.append(f"📊 Meddelanden per session (snitt): {avg_messages_per_session}")
# Snittsvarstid (om kolumnen finns och har giltiga värden)
if "response_time" in df_day.columns and not df_day["response_time"].empty:
avg_response_time = round(df_day["response_time"].mean(), 2)
summary.append(f"🕒 Snittsvarstid senaste 24h: {avg_response_time} sekunder")
else:
summary.append("🕒 Snittsvarstid senaste 24h: N/A")
summary.append(f"📊 Antal meddelanden (14 dagar): {len(df_14)}")
summary.append(f"📈 Unika användare (14 dagar): {df_14['user_id'].nunique()}")
# Likes och dislikes under senaste 24h
if "feedback" in df_day.columns:
df_day_feedback = df_day.dropna(subset=["feedback"])
likes = df_day_feedback[df_day_feedback["feedback"] == "up"].shape[0]
dislikes = df_day_feedback[df_day_feedback["feedback"] == "down"].shape[0]
else:
likes, dislikes = 0, 0
summary.append(f"👍 Likes senaste 24h: {likes}")
summary.append(f"👎 Dislikes senaste 24h: {dislikes}")
# Nyckeltal kring webbläsare: visa de tre mest använda
if "browser" in df_day.columns:
browser_counts = df_day["browser"].value_counts()
top_browsers = browser_counts.head(3)
browser_summary = "🌐 Browser-fördelning senaste 24h: " + ", ".join([f"{browser}: {count}" for browser, count in top_browsers.items()])
else:
browser_summary = "🌐 Browser-fördelning senaste 24h: Ingen data"
summary.append(browser_summary)
# Tre exempel på frågor och svar med tumme ner
if "feedback" in df_day.columns:
df_down = df_day[df_day["feedback"] == "down"].dropna(subset=["user_message", "bot_reply"])
else:
df_down = pd.DataFrame()
if not df_down.empty:
examples = df_down.head(3)
examples_text = "❌ Exempel på frågor och svar med tumme ner:\n"
for idx, row in examples.iterrows():
examples_text += f"• Fråga: {row['user_message']}\n Svar: {row['bot_reply']}\n"
else:
examples_text = "❌ Inga exempel med tumme ner hittades senaste 24h."
summary.append(examples_text)
return "\n".join(summary)
# --- Huvudfunktion ---
def run_report():
try:
logging.info("Startar rapportgenerering...")
log_path = hf_hub_download(
repo_id=REPO_ID,
filename=LOG_FILENAME,
repo_type="dataset",
token=HF_TOKEN
)
try:
df = pd.read_json(log_path, lines=True)
logging.info("Loggfil läst som JSONL.")
except Exception as e:
logging.error(f"Kunde inte läsa logg som JSONL: {e}", exc_info=True)
return "❌ Loggfilen kunde inte läsas som JSONL."
if df.empty:
logging.warning("Inga loggrader hittades – avbryter.")
return "⚠️ Inga loggar att rapportera."
summary = generate_summary(df)
send_summary_to_slack(summary)
return "✅ Slack-meddelande skickat."
except Exception as e:
logging.error(f"Fel vid körning: {e}", exc_info=True)
return f"❌ Fel vid körning: {e}"
# --- Schemaläggning ---
schedule.every().day.at("08:20").do(run_report)
def run_schedule():
while True:
schedule.run_pending()
time.sleep(60)
import threading
threading.Thread(target=run_schedule, daemon=True).start()
# --- Gradio-knapp ---
with gr.Blocks() as app:
gr.Markdown("# Slack Reporter – Nyckeltal")
btn = gr.Button("Skicka rapport nu")
output = gr.Textbox()
btn.click(fn=run_report, outputs=output)
if __name__ == "__main__":
app.launch()