diff --git a/metrics/redis_metrics.py b/metrics/redis_metrics.py index b35d96a..bcb61b2 100644 --- a/metrics/redis_metrics.py +++ b/metrics/redis_metrics.py @@ -110,14 +110,10 @@ async def get_redis_metrics() -> Dict[str, Any]: async def get_debrid_cache_metrics() -> Dict[str, Any]: """ - Get detailed metrics about debrid cache usage. + Get simplified metrics about debrid cache usage, focusing only on cached torrents per service. """ - metrics = { - "timestamp": datetime.now(tz=timezone.utc).isoformat(), - "total_memory_usage": 0, - "total_cached_torrents": 0, - "services": {}, - } + metrics = {"timestamp": datetime.now(tz=timezone.utc).isoformat(), "services": {}} + debrid_services = [ "alldebrid", "debridlink", @@ -132,37 +128,21 @@ async def get_debrid_cache_metrics() -> Dict[str, Any]: ] try: - for service in debrid_services: cache_key = f"debrid_cache:{service}" - - # Get various metrics for each service cache_size = await REDIS_ASYNC_CLIENT.hlen(cache_key) - memory_usage = await REDIS_ASYNC_CLIENT.memory_usage(cache_key) or 0 - metrics["services"][service] = { - "cached_torrents": cache_size, - "memory_usage": memory_usage, - } + if cache_size > 0: # Only include services with cached torrents + metrics["services"][service] = {"cached_torrents": cache_size} - # Update totals - metrics["total_cached_torrents"] += cache_size - metrics["total_memory_usage"] += memory_usage - - # Add human readable total memory - metrics["total_memory_usage_human"] = humanize.naturalsize( - metrics["total_memory_usage"] - ) - - # Calculate which service has most cached torrents - if metrics["services"]: - most_cached = max( - metrics["services"].items(), key=lambda x: x[1]["cached_torrents"] + # Sort services by cache size + metrics["services"] = dict( + sorted( + metrics["services"].items(), + key=lambda x: x[1]["cached_torrents"], + reverse=True, ) - metrics["most_used_service"] = { - "name": most_cached[0], - "cached_count": most_cached[1]["cached_torrents"], - } + ) return metrics except Exception as e: diff --git a/metrics/routes.py b/metrics/routes.py index c8f2ec0..3842778 100644 --- a/metrics/routes.py +++ b/metrics/routes.py @@ -1,4 +1,5 @@ import asyncio +from datetime import datetime, timezone, timedelta import humanize from fastapi import APIRouter, Request, Response @@ -65,6 +66,7 @@ async def get_torrents_by_sources(response: Response): [ {"$group": {"_id": "$source", "count": {"$sum": 1}}}, {"$sort": {"count": -1}}, + {"$limit": 20}, # Limit to top 20 sources ] ).to_list() torrent_sources = [ @@ -151,3 +153,65 @@ async def debrid_cache_metrics(): Returns statistics about cache size, memory usage, and usage patterns per service. """ return await get_debrid_cache_metrics() + + +@metrics_router.get("/torrents/uploaders", tags=["metrics"]) +async def get_torrents_by_uploaders(response: Response): + response.headers.update(const.NO_CACHE_HEADERS) + results = await TorrentStreams.aggregate( + [ + {"$match": {"uploader": {"$ne": None}}}, + {"$group": {"_id": "$uploader", "count": {"$sum": 1}}}, + {"$sort": {"count": -1}}, + {"$limit": 20}, # Limit to top 20 uploaders + ] + ).to_list() + + uploader_stats = [ + {"name": stat["_id"] if stat["_id"] else "Unknown", "count": stat["count"]} + for stat in results + ] + return uploader_stats + + +@metrics_router.get("/torrents/uploaders/weekly", tags=["metrics"]) +async def get_weekly_top_uploaders(response: Response): + response.headers.update(const.NO_CACHE_HEADERS) + + # Calculate the start of the current week (Monday) + today = datetime.now(tz=timezone.utc) + start_of_week = today - timedelta(days=today.weekday()) + start_of_week = start_of_week.replace(hour=0, minute=0, second=0, microsecond=0) + + results = await TorrentStreams.aggregate( + [ + { + "$match": { + "uploader": {"$ne": None}, + "created_at": {"$gte": start_of_week}, + } + }, + { + "$group": { + "_id": "$uploader", + "count": {"$sum": 1}, + "latest_upload": {"$max": "$created_at"}, + } + }, + {"$sort": {"count": -1}}, + {"$limit": 20}, + ] + ).to_list() + + uploaders_stats = [ + { + "name": stat["_id"], + "count": stat["count"], + "latest_upload": ( + stat["latest_upload"].isoformat() if stat["latest_upload"] else None + ), + } + for stat in results + ] + + return {"week_start": start_of_week.isoformat(), "uploaders": uploaders_stats} diff --git a/resources/css/metrics.css b/resources/css/metrics.css index 94d3150..39ba3c9 100644 --- a/resources/css/metrics.css +++ b/resources/css/metrics.css @@ -13,6 +13,14 @@ body, html { overflow-y: auto; } +h4 { + color: #ffffff; + font-weight: 600; + margin-bottom: 1.5rem; + border-bottom: 2px solid rgba(74, 71, 163, 0.5); + padding-bottom: 0.5rem; +} + .config-container { margin: 2% auto; padding: 2%; @@ -38,7 +46,37 @@ body, html { } .chart-section { - margin-bottom: 2rem; + background: rgba(0, 0, 0, 0.5); + border-radius: 10px; + padding: 20px; + margin-bottom: 30px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + transition: transform 0.3s ease; +} + +.chart-section:hover { + transform: translateY(-5px); +} + +.date-info { + background: rgba(129,87,208,0.6); + padding: 8px 16px; + border-radius: 4px; + text-align: center; + font-size: 0.9rem; +} + +.chart-wrapper { + position: relative; + width: 100%; + height: 400px; + margin: 20px 0; +} + +.chart-wrapper canvas { + position: absolute; + width: 100% !important; + height: 100% !important; } .chart-container { @@ -49,19 +87,6 @@ body, html { position: relative; } -.chart-wrapper { - position: relative; - width: 100%; - height: 0; - padding-bottom: 50%; -} - -.chart-wrapper canvas { - position: absolute; - width: 100%; - height: 100%; -} - .logo { max-width: 300px; display: block; @@ -69,9 +94,14 @@ body, html { } .card { - background: #4a47a3; - position: relative; - text-align: center; + background: linear-gradient(145deg, #4a47a3, #2d2a6a); + border: none; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + transition: transform 0.3s ease; +} + +.card:hover { + transform: translateY(-5px); } .card-text { @@ -178,6 +208,18 @@ body, html { @media (max-width: 768px) { + .chart-wrapper { + height: 300px; + } + + .chart-section { + padding: 15px; + margin-bottom: 20px; + } + + .card-text { + font-size: 1.2rem; + } .config-container { padding: 10px; } diff --git a/resources/html/metrics.html b/resources/html/metrics.html index d0e6795..8028dd3 100644 --- a/resources/html/metrics.html +++ b/resources/html/metrics.html @@ -48,7 +48,7 @@