Repository: Cog-Creators/Red-DiscordBot

Issue:
Add more information to `[p]debuginfo`
### What component of Red (cog, command, API) would you like to see improvements on?

Core

### Describe the enhancement you're suggesting.

Add information about things like:
- instance name
- more system information, i.e. RAM
- ??? (@Kowlin seems to have more ideas than me so he can add them here)


### Anything else?

I would highly suggest dropping the embed version entirely while doing these changes - the embed is getting big and it's not that easy to read already and it will only get worse. Also, we might eventually run out of fields as you can only put 20...


Discussion:

Resolving patch:
diff --git a/redbot/core/core_commands.py b/redbot/core/core_commands.py
--- a/redbot/core/core_commands.py
+++ b/redbot/core/core_commands.py
@@ -12,10 +12,12 @@
 import re
 import sys
 import platform
+import psutil
 import getpass
 import pip
 import traceback
 from pathlib import Path
+from redbot.core import data_manager
 from redbot.core.utils.menus import menu, DEFAULT_CONTROLS
 from redbot.core.commands import GuildConverter
 from string import ascii_letters, digits
@@ -25,7 +27,6 @@
 import discord
 from babel import Locale as BabelLocale, UnknownLocaleError
 from redbot.core.data_manager import storage_type
-from redbot.core.utils.chat_formatting import box, pagify
 
 from . import (
     __version__,
@@ -3558,19 +3559,20 @@ async def debuginfo(self, ctx: commands.Context):
         IS_MAC = sys.platform == "darwin"
         IS_LINUX = sys.platform == "linux"
 
-        pyver = "{}.{}.{} ({})".format(*sys.version_info[:3], platform.architecture()[0])
+        python_version = ".".join(map(str, sys.version_info[:3]))
+        pyver = f"{python_version} ({platform.architecture()[0]})"
         pipver = pip.__version__
         redver = red_version_info
         dpy_version = discord.__version__
         if IS_WINDOWS:
             os_info = platform.uname()
-            osver = "{} {} (version {})".format(os_info.system, os_info.release, os_info.version)
+            osver = f"{os_info.system} {os_info.release} (version {os_info.version})"
         elif IS_MAC:
             os_info = platform.mac_ver()
-            osver = "Mac OSX {} {}".format(os_info[0], os_info[2])
+            osver = f"Mac OSX {os_info[0]} {os_info[2]}"
         elif IS_LINUX:
             os_info = distro.linux_distribution()
-            osver = "{} {}".format(os_info[0], os_info[1]).strip()
+            osver = f"{os_info[0]} {os_info[1]}".strip()
         else:
             osver = "Could not parse OS, report this on Github."
         user_who_ran = getpass.getuser()
@@ -3587,51 +3589,69 @@ async def debuginfo(self, ctx: commands.Context):
             )
             or "None"
         )
-        if await ctx.embed_requested():
-            e = discord.Embed(color=await ctx.embed_colour())
-            e.title = "Debug Info for Red"
-            e.add_field(name="Red version", value=redver, inline=True)
-            e.add_field(name="Python version", value=pyver, inline=True)
-            e.add_field(name="Discord.py version", value=dpy_version, inline=True)
-            e.add_field(name="Pip version", value=pipver, inline=True)
-            e.add_field(name="System arch", value=platform.machine(), inline=True)
-            e.add_field(name="User", value=user_who_ran, inline=True)
-            e.add_field(name="Storage type", value=driver, inline=True)
-            e.add_field(name="Disabled intents", value=disabled_intents, inline=True)
-            e.add_field(name="OS version", value=osver, inline=False)
-            e.add_field(
-                name="Python executable",
-                value=escape(sys.executable, formatting=True),
-                inline=False,
-            )
-            e.add_field(
-                name="Data path",
-                value=escape(str(data_path), formatting=True),
-                inline=False,
-            )
-            e.add_field(
-                name="Metadata file",
-                value=escape(str(config_file), formatting=True),
-                inline=False,
-            )
-            await ctx.send(embed=e)
-        else:
-            info = (
-                "Debug Info for Red\n\n"
-                + "Red version: {}\n".format(redver)
-                + "Python version: {}\n".format(pyver)
-                + "Discord.py version: {}\n".format(dpy_version)
-                + "Pip version: {}\n".format(pipver)
-                + "System arch: {}\n".format(platform.machine())
-                + "User: {}\n".format(user_who_ran)
-                + "OS version: {}\n".format(osver)
-                + "Storage type: {}\n".format(driver)
-                + "Disabled intents: {}\n".format(disabled_intents)
-                + "Python executable: {}\n".format(sys.executable)
-                + "Data path: {}\n".format(data_path)
-                + "Metadata file: {}\n".format(config_file)
-            )
-            await ctx.send(box(info))
+
+        def _datasize(num: int):
+            for unit in ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB"]:
+                if abs(num) < 1024.0:
+                    return "{0:.1f}{1}".format(num, unit)
+                num /= 1024.0
+            return "{0:.1f}{1}".format(num, "YB")
+
+        memory_ram = psutil.virtual_memory()
+        ram_string = "{used}/{total} ({percent}%)".format(
+            used=_datasize(memory_ram.used),
+            total=_datasize(memory_ram.total),
+            percent=memory_ram.percent,
+        )
+
+        owners = []
+        for uid in self.bot.owner_ids:
+            try:
+                u = await self.bot.get_or_fetch_user(uid)
+                owners.append(f"{u.id} ({u})")
+            except discord.HTTPException:
+                owners.append(f"{uid} (Unresolvable)")
+        owners_string = ", ".join(owners) or "None"
+
+        resp_intro = "# Debug Info for Red:"
+        resp_system_intro = "## System Metadata:"
+        resp_system = (
+            f"CPU Cores: {psutil.cpu_count()} ({platform.machine()})\nRAM: {ram_string}\n"
+        )
+        resp_os_intro = "## OS Variables:"
+        resp_os = f"OS version: {osver}\nUser: {user_who_ran}\n"  # Ran where off to?!
+        resp_py_metadata = (
+            f"Python executable: {sys.executable}\n"
+            f"Python version: {pyver}\n"
+            f"Pip version: {pipver}\n"
+        )
+        resp_red_metadata = f"Red version: {redver}\nDiscord.py version: {dpy_version}\n"
+        resp_red_vars_intro = "## Red variables:"
+        resp_red_vars = (
+            f"Instance name: {data_manager.instance_name}\n"
+            f"Owner(s): {owners_string}\n"
+            f"Storage type: {driver}\n"
+            f"Disabled intents: {disabled_intents}\n"
+            f"Data path: {data_path}\n"
+            f"Metadata file: {config_file}"
+        )
+
+        response = (
+            box(resp_intro, lang="md"),
+            "\n",
+            box(resp_system_intro, lang="md"),
+            box(resp_system),
+            "\n",
+            box(resp_os_intro, lang="md"),
+            box(resp_os),
+            box(resp_py_metadata),
+            box(resp_red_metadata),
+            "\n",
+            box(resp_red_vars_intro, lang="md"),
+            box(resp_red_vars),
+        )
+
+        await ctx.send("".join(response))
 
     @commands.group(aliases=["whitelist"])
     @checks.is_owner()


Test patch: