Skip to content

Commit

Permalink
Add charts for top torrent uploaders and weekly top uploader data & i…
Browse files Browse the repository at this point in the history
…mprove debrid cache & torrent source charts

Introduced new visualizations to display the top 20 torrent uploaders and their weekly activity. Enhanced the styling for metrics sections and updated backend logic to support these additions, ensuring cleaner and more focused data retrieval.
  • Loading branch information
mhdzumair committed Jan 9, 2025
1 parent 458fc0d commit 361b6ba
Show file tree
Hide file tree
Showing 5 changed files with 341 additions and 138 deletions.
44 changes: 12 additions & 32 deletions metrics/redis_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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:
Expand Down
64 changes: 64 additions & 0 deletions metrics/routes.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
from datetime import datetime, timezone, timedelta

import humanize
from fastapi import APIRouter, Request, Response
Expand Down Expand Up @@ -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 = [
Expand Down Expand Up @@ -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}
70 changes: 56 additions & 14 deletions resources/css/metrics.css
Original file line number Diff line number Diff line change
Expand Up @@ -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%;
Expand All @@ -38,28 +46,45 @@ 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-container {
padding: 1rem;
background: rgba(0, 0, 0, 0.37);
border-radius: 8px;
transition: margin-bottom 0.3s ease, padding 0.3s ease;
position: relative;
.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: 0;
padding-bottom: 50%;
height: 400px;
margin: 20px 0;
}

.chart-wrapper canvas {
position: absolute;
width: 100%;
height: 100%;
width: 100% !important;
height: 100% !important;
}

.chart-container {
padding: 1rem;
background: rgba(0, 0, 0, 0.37);
border-radius: 8px;
transition: margin-bottom 0.3s ease, padding 0.3s ease;
position: relative;
}

.logo {
Expand All @@ -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 {
Expand Down Expand Up @@ -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;
}
Expand Down
41 changes: 19 additions & 22 deletions resources/html/metrics.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,38 +48,35 @@ <h5 class="card-title">Total Torrents</h5>
</div>

<div class="chart-section">
<h4 class="text-left">Torrent Count By Sources</h4>
<h4 class="text-left">Top 20 Torrents Sources</h4>
<div class="chart-wrapper">
<canvas id="torrentSourcesChart"></canvas>
<div class="skeleton-loader" id="torrentSourcesSkeleton"></div>
</div>
</div>

<div class="chart-section">
<h4 class="text-left">Debrid Cache Statistics</h4>
<div class="row">
<div class="col-md-6 mb-3">
<div class="card text-white">
<div class="card-body">
<h5 class="card-title">Total Cached Torrents Count (Not Unique)</h5>
<p id="totalCachedTorrentsValue" class="card-text large-number"></p>
<div class="skeleton-loader" id="debridTotalsSkeleton"></div>
</div>
</div>
</div>
<div class="col-md-6 mb-3">
<div class="card text-white">
<div class="card-body">
<h5 class="card-title">Total Cache Memory Usage</h5>
<p id="totalCacheMemoryValue" class="card-text large-number"></p>
<div class="skeleton-loader" id="debridMemorySkeleton"></div>
</div>
</div>
</div>
<h4 class="text-left">Top 20 Torrents Uploaders</h4>
<div class="chart-wrapper">
<canvas id="torrentUploadersChart"></canvas>
<div class="skeleton-loader" id="torrentUploadersSkeleton"></div>
</div>
</div>

<div class="chart-section">
<h4 class="text-left">Top 20 Uploaders This Week</h4>
<div class="date-info mb-3" id="weekDateRange"></div>
<div class="chart-wrapper">
<canvas id="weeklyUploadersChart"></canvas>
<div class="skeleton-loader" id="weeklyUploadersSkeleton"></div>
</div>
</div>

<div class="chart-section">
<h4 class="text-left">Debrid Cache Statistics</h4>
<div class="card text-white">
<div class="card-body">
<h5 class="card-title">Cache Distribution</h5>
<h5 class="card-title">Cached Torrents by Service</h5>
<div class="chart-wrapper">
<canvas id="debridCacheChart"></canvas>
<div class="skeleton-loader" id="debridChartSkeleton"></div>
Expand Down
Loading

0 comments on commit 361b6ba

Please sign in to comment.