# 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()