Skip to content

Commit

Permalink
Merge pull request #35 from jackra1n/lavalink_stats
Browse files Browse the repository at this point in the history
Lavalink stats
  • Loading branch information
jackra1n authored Mar 22, 2024
2 parents ab72382 + b8d0ea0 commit 4f181f7
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 44 deletions.
36 changes: 35 additions & 1 deletion extensions/music.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from discord import ButtonStyle, Interaction, ui
from discord.ext import commands

import utils
from core import config
from core.bot import Substiify

Expand Down Expand Up @@ -72,7 +73,7 @@ async def ensure_voice(self, ctx: commands.Context):
if wavelink.Pool.nodes is None:
raise NoNodeAccessible()

if ctx.command.name in ["players", "cleanup"]:
if ctx.command.name in ["players", "cleanup", "lavalink"]:
return True

player: wavelink.Player = ctx.voice_client
Expand Down Expand Up @@ -222,6 +223,39 @@ async def players(self, ctx: commands.Context):
embed.description = players_string
await ctx.send(embed=embed, delete_after=60)

@commands.is_owner()
@commands.command(name="lavalink", aliases=["lv"], hidden=True)
async def lavalink_stats(self, ctx: commands.Context):
"""
Shows the Lavalink stats.
"""
stats: wavelink.StatsResponsePayload = await wavelink.Pool.get_node().fetch_stats()
info: wavelink.InfoResponsePayload = await wavelink.Pool.get_node().fetch_info()

players_str = f"[` {stats.players} | {stats.playing} `]"
version_str = f"[` {info.version.semver} `]"
uptime_str = f"[` {utils.seconds_to_human_readable(stats.uptime/1000)} `]"
memory_used = utils.bytes_to_human_readable(stats.memory.used)
memory_free = utils.bytes_to_human_readable(stats.memory.reservable)
memory_str = f"[` {memory_used} | {memory_free} `]"
system_load = round((stats.cpu.system_load * 100), 1)
cpu_str = f"[` {stats.cpu.cores} vCPU | {system_load} `]"
jvm_str = f"[` {info.jvm} `]"
sources_str = f"```ml\n{', '.join(info.source_managers).title()}\n```"
plugins_list_str = [f"({plugin.name} - {plugin.version})" for plugin in info.plugins]
plugins_str = f"```ml\n{', '.join(plugins_list_str).title()}\n```"

embed = discord.Embed(title="Lavalink Info", color=EMBED_COLOR)
embed.add_field(name="Players", value=players_str)
embed.add_field(name="Uptime", value=uptime_str)
embed.add_field(name="Version", value=version_str)
embed.add_field(name="Memory", value=memory_str)
embed.add_field(name="CPU Usage", value=cpu_str)
embed.add_field(name="JVM", value=jvm_str)
embed.add_field(name="Sources", value=sources_str, inline=False)
embed.add_field(name="Plugins", value=plugins_str, inline=False)
await ctx.send(embed=embed)

@commands.hybrid_command()
@commands.check_any(commands.has_permissions(manage_channels=True), commands.is_owner())
async def cleanup(self, ctx: commands.Context, enable: bool = None):
Expand Down
57 changes: 15 additions & 42 deletions extensions/util.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
import asyncio
import datetime
import logging
import math
import platform
from random import SystemRandom, shuffle

import discord
import psutil
from discord import MessageType, app_commands
from discord.ext import commands, tasks
from pytz import timezone

from core import constants
from core.bot import Substiify
from utils import ux
import core
import utils

logger = logging.getLogger(__name__)


class Util(commands.Cog):
COG_EMOJI = "📦"

def __init__(self, bot: Substiify):
def __init__(self, bot: core.Substiify):
self.bot = bot
self.giveaway_task.start()

Expand Down Expand Up @@ -300,11 +297,9 @@ async def ping(self, ctx: commands.Context):
"""
Shows the ping of the bot
"""
title = "Donk!" if "dink" in ctx.message.content.lower() else "Pong!"
embed = discord.Embed(
title=f"{title} 🏓", description=f"⏱️Ping: `{round(self.bot.latency*1000)}`ms", color=constants.PRIMARY_COLOR
)
await ctx.message.delete()
title = "Donk! 🏓" if "dink" in ctx.message.content.lower() else "Pong! 🏓"
desc = f"⏱️Ping: `{round(self.bot.latency*1000)}`ms"
embed = discord.Embed(title=title, description=desc, color=core.constants.PRIMARY_COLOR)
await ctx.send(embed=embed)

@commands.command(name="specialThanks", hidden=True)
Expand All @@ -320,23 +315,25 @@ async def special_thanks(self, ctx: commands.Context):
embed = discord.Embed(
title="Special thanks for any help to those people",
description=" ".join(peeople_who_helped),
color=constants.PRIMARY_COLOR,
color=core.constants.PRIMARY_COLOR,
)

await ctx.send(embed=embed)
await ctx.message.delete()

@commands.command()
@commands.cooldown(3, 30)
async def info(self, ctx: commands.Context):
"""
Shows different technical information about the bot
"""
content = ""
bot_uptime = time_up((discord.utils.utcnow() - self.bot.start_time).total_seconds())
last_commit_hash = ux.get_last_commit_hash()
uptime_in_seconds = (discord.utils.utcnow() - self.bot.start_time).total_seconds()
bot_uptime = utils.seconds_to_human_readable(uptime_in_seconds)
last_commit_hash = utils.ux.get_last_commit_hash()
cpu_percent = psutil.cpu_percent()
ram = psutil.virtual_memory()
ram_used = format_bytes((ram.total - ram.available))
ram_used = utils.bytes_to_human_readable((ram.total - ram.available))
ram_percent = psutil.virtual_memory().percent
proc = psutil.Process()

Expand All @@ -348,42 +345,18 @@ async def info(self, ctx: commands.Context):
f"**Python:** `{platform.python_version()}`\n"
f"**discord.py:** `{discord.__version__}`\n\n"
f"**CPU:** `{cpu_percent}%`\n"
f"**Process RAM:** `{format_bytes(memory.uss)}`\n"
f"**Process RAM:** `{utils.bytes_to_human_readable(memory.uss)}`\n"
f"**Total RAM:** `{ram_used} ({ram_percent}%)`\n\n"
f"**Made by:** <@{self.bot.owner_id}>"
)

embed = discord.Embed(
title=f"Info about {self.bot.user.display_name}",
description=content,
color=constants.PRIMARY_COLOR,
timestamp=datetime.datetime.now(timezone("Europe/Zurich")),
title=f"Info about {self.bot.user.display_name}", description=content, color=core.constants.PRIMARY_COLOR
)
embed.set_thumbnail(url=self.bot.user.display_avatar.url)
embed.set_footer(text=f"Requested by {ctx.author}", icon_url=ctx.author.avatar)
await ctx.send(embed=embed)


def time_up(seconds: int) -> str:
if seconds <= 60:
return "<1 minute"
elif 3600 > seconds > 60:
minutes = seconds // 60
return f"{int(minutes)} minutes"
hours = seconds // 3600 # Seconds divided by 3600 gives amount of hours
minutes = (seconds % 3600) // 60 # The remaining seconds are looked at to see how many minutes they make up
if hours >= 24:
days = hours // 24
hours = hours % 24
return f"{int(days)} days, {int(hours)} hours, {int(minutes)} minutes"
return f"{int(hours)} hours, {int(minutes)} minutes"


def format_bytes(size_in_bytes: int) -> str:
units = ("B", "KiB", "MiB", "GiB", "TiB")
power = int(math.log(max(abs(size_in_bytes), 1), 1024))
return f"{size_in_bytes / (1024 ** power):.2f} {units[power]}"


async def setup(bot: Substiify):
async def setup(bot: core.Substiify):
await bot.add_cog(Util(bot))
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ target-version = "py312"
[tool.ruff.lint]
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
select = ["E4", "E7", "E9", "F"]
ignore = []
ignore = ["F403"]

# Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"]
Expand Down
1 change: 1 addition & 0 deletions utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from . import ux as ux
from .general import *
25 changes: 25 additions & 0 deletions utils/general.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import math

__all__ = ("seconds_to_human_readable", "bytes_to_human_readable")


def seconds_to_human_readable(seconds: int) -> str:
if seconds <= 60:
return "<1 minute"
elif 3600 > seconds > 60:
minutes = seconds // 60
seconds = seconds % 60
return f"{int(minutes)}m {int(seconds)}s"
hours = seconds // 3600 # Seconds divided by 3600 gives amount of hours
minutes = (seconds % 3600) // 60 # The remaining seconds are looked at to see how many minutes they make up
if hours >= 24:
days = hours // 24
hours = hours % 24
return f"{int(days)}d {int(hours)}h {int(minutes)}m"
return f"{int(hours)}h {int(minutes)}m"


def bytes_to_human_readable(size_in_bytes: int) -> str:
units = ("B", "KB", "MB", "GB", "TB")
power = int(math.log(size_in_bytes, 1024))
return f"{size_in_bytes / (1024 ** power):.1f} {units[power]}"

0 comments on commit 4f181f7

Please sign in to comment.