# pages/log_viewer.py
import streamlit as st
import os
from utils.css_loader import load_css, apply_dark_theme
from datetime import datetime
# === CSS & Theme laden ===
load_css()
apply_dark_theme()
st.set_page_config(page_title="🧾 Log Viewer", layout="wide")
# Header
st.markdown("""
🧾 Log Viewer
Überwache Systemaktivitäten und Debug-Informationen
""", unsafe_allow_html=True)
LOG_FILE = "logs/rss_tool.log"
MAX_LINES = 500
# === Log-Datei Kontrollen ===
st.markdown('', unsafe_allow_html=True)
st.subheader("📁 Log-Datei Optionen")
col1, col2, col3, col4 = st.columns(4)
with col1:
lines_to_show = st.selectbox(
"Anzahl Zeilen",
[50, 100, 200, 500, 1000],
index=3, # Default: 500
key="lines_select"
)
with col2:
if st.button("🔄 Neu laden", use_container_width=True):
st.rerun()
with col3:
log_level_filter = st.selectbox(
"Log Level Filter",
["Alle", "INFO", "WARNING", "ERROR", "DEBUG"],
key="level_filter"
)
with col4:
search_term = st.text_input(
"Suche in Logs",
placeholder="Suchbegriff...",
key="log_search"
)
st.markdown('
', unsafe_allow_html=True)
# === Log-Datei Status ===
if not os.path.exists(LOG_FILE):
st.markdown("""
⚠️ Keine Log-Datei gefunden
Die Log-Datei wurde noch nicht erstellt oder befindet sich an einem anderen Ort.
Erwarteter Pfad: {}
""".format(LOG_FILE), unsafe_allow_html=True)
else:
# Datei-Informationen
file_size = os.path.getsize(LOG_FILE)
file_mtime = datetime.fromtimestamp(os.path.getmtime(LOG_FILE))
col1, col2, col3 = st.columns(3)
with col1:
st.markdown("""
""".format(file_size / 1024), unsafe_allow_html=True)
with col2:
st.markdown("""
""".format(file_mtime.strftime("%H:%M:%S")), unsafe_allow_html=True)
with col3:
# Zeilen zählen
try:
with open(LOG_FILE, "r", encoding="utf-8") as f:
total_lines = sum(1 for _ in f)
except:
total_lines = 0
st.markdown("""
""".format(total_lines), unsafe_allow_html=True)
# === Log-Inhalt anzeigen ===
try:
with open(LOG_FILE, "r", encoding="utf-8") as f:
lines = f.readlines()
# Filter anwenden
filtered_lines = []
for line in lines:
# Log Level Filter
if log_level_filter != "Alle":
if f" - {log_level_filter} - " not in line:
continue
# Suchfilter
if search_term and search_term.lower() not in line.lower():
continue
filtered_lines.append(line)
# Anzahl begrenzen
display_lines = filtered_lines[-lines_to_show:] if len(filtered_lines) > lines_to_show else filtered_lines
# Header für Log-Anzeige
st.subheader(f"📋 Log-Einträge ({len(display_lines)} von {len(filtered_lines)} gefilterten Zeilen)")
if display_lines:
# Log-Inhalt mit Syntax-Highlighting
log_content = "".join(display_lines)
# Farbkodierung für verschiedene Log-Level
colored_content = log_content
colored_content = colored_content.replace(" - ERROR - ", " - 🔴 ERROR - ")
colored_content = colored_content.replace(" - WARNING - ", " - 🟡 WARNING - ")
colored_content = colored_content.replace(" - INFO - ", " - 🔵 INFO - ")
colored_content = colored_content.replace(" - DEBUG - ", " - ⚪ DEBUG - ")
# Log in Card anzeigen
st.markdown("""
📄 Log-Ausgabe
Letzte {count} Einträge | Filter: {level} | Suche: "{search}"
""".format(
count=len(display_lines),
level=log_level_filter,
search=search_term or "Keine"
), unsafe_allow_html=True)
# Code-Block mit Logs
st.code(colored_content, language="text")
# Download-Button
st.download_button(
label="💾 Log-Datei herunterladen",
data=log_content,
file_name=f"rss_tool_log_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt",
mime="text/plain",
use_container_width=True
)
else:
st.markdown("""
🔍 Keine Log-Einträge gefunden
Mit den aktuellen Filtern wurden keine Log-Einträge gefunden.
Versuche andere Filter-Einstellungen.
""", unsafe_allow_html=True)
except Exception as e:
st.markdown(f"""
❌ Fehler beim Lesen der Log-Datei
{str(e)}
""", unsafe_allow_html=True)
# === Log-Level Erklärung ===
with st.expander("ℹ️ Log-Level Erklärung", expanded=False):
st.markdown("""
📖 Log-Level Bedeutung
🔵 INFO: Normale Programmaktivitäten (Feed-Updates, Artikel verarbeitet)
🟡 WARNING: Potentielle Probleme (Duplikate, fehlende Daten)
🔴 ERROR: Fehler die das Programm beeinträchtigen
⚪ DEBUG: Detaillierte Entwickler-Informationen
""", unsafe_allow_html=True)
# === Log-Datei verwalten ===
st.markdown("---")
st.subheader("🛠️ Log-Datei Verwaltung")
col1, col2, col3 = st.columns(3)
with col1:
if st.button("🗑️ Log-Datei leeren", use_container_width=True):
if st.button("⚠️ Wirklich leeren?", key="confirm_clear"):
try:
with open(LOG_FILE, "w", encoding="utf-8") as f:
f.write("")
st.success("Log-Datei wurde geleert!")
st.rerun()
except Exception as e:
st.error(f"Fehler beim Leeren der Log-Datei: {e}")
with col2:
if st.button("📦 Log archivieren", use_container_width=True):
try:
archive_name = f"rss_tool_log_archive_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
with open(LOG_FILE, "r", encoding="utf-8") as f:
log_data = f.read()
st.download_button(
label=f"💾 {archive_name}",
data=log_data,
file_name=archive_name,
mime="text/plain",
key="archive_download"
)
except Exception as e:
st.error(f"Fehler beim Archivieren: {e}")
with col3:
if st.button("📊 Log-Statistiken", use_container_width=True):
if os.path.exists(LOG_FILE):
try:
with open(LOG_FILE, "r", encoding="utf-8") as f:
all_lines = f.readlines()
# Statistiken berechnen
total_lines = len(all_lines)
info_count = sum(1 for line in all_lines if " - INFO - " in line)
warning_count = sum(1 for line in all_lines if " - WARNING - " in line)
error_count = sum(1 for line in all_lines if " - ERROR - " in line)
debug_count = sum(1 for line in all_lines if " - DEBUG - " in line)
st.subheader("📈 Log-Statistiken")
col1, col2, col3, col4 = st.columns(4)
with col1:
st.markdown("""
""".format(info_count), unsafe_allow_html=True)
with col2:
st.markdown("""
""".format(warning_count), unsafe_allow_html=True)
with col3:
st.markdown("""
""".format(error_count), unsafe_allow_html=True)
with col4:
st.markdown("""
""".format(debug_count), unsafe_allow_html=True)
except Exception as e:
st.error(f"Fehler beim Berechnen der Statistiken: {e}")
# === Auto-Refresh Option ===
if st.checkbox("🔄 Auto-Refresh (30s)", key="auto_refresh"):
import time
time.sleep(30)
st.rerun()