PluralKit/PluralKit.Bot/Commands/Misc.cs

140 lines
5.5 KiB
C#
Raw Normal View History

2019-12-22 12:50:47 +01:00
using System.Diagnostics;
2019-07-16 21:59:06 +02:00
using App.Metrics;
2019-12-22 12:50:47 +01:00
2020-12-24 14:52:44 +01:00
using Myriad.Builders;
using Myriad.Rest.Types.Requests;
using Myriad.Types;
2025-01-05 00:52:45 +00:00
using Newtonsoft.Json;
using NodaTime;
using PluralKit.Core;
namespace PluralKit.Bot;
public class Misc
2021-08-27 11:03:47 -04:00
{
private readonly BotConfig _botConfig;
private readonly CpuStatService _cpu;
private readonly IMetrics _metrics;
private readonly ShardInfoService _shards;
2022-01-22 03:52:52 -05:00
private readonly ModelRepository _repo;
public Misc(BotConfig botConfig, IMetrics metrics, CpuStatService cpu, ModelRepository repo, ShardInfoService shards)
2019-10-05 07:41:00 +02:00
{
_botConfig = botConfig;
_metrics = metrics;
_cpu = cpu;
_repo = repo;
2022-01-22 03:52:52 -05:00
_shards = shards;
}
2020-04-24 15:50:28 -04:00
public async Task Invite(Context ctx)
{
var permissions =
PermissionSet.AddReactions |
PermissionSet.AttachFiles |
PermissionSet.EmbedLinks |
PermissionSet.ManageMessages |
PermissionSet.ManageWebhooks |
PermissionSet.ReadMessageHistory |
PermissionSet.SendMessages;
var invite =
$"https://discord.com/oauth2/authorize?client_id={_botConfig.ClientId}&scope=bot%20applications.commands&permissions={(ulong)permissions}";
2021-11-27 11:09:08 -05:00
var botName = _botConfig.IsBetaBot ? "PluralKit Beta" : "PluralKit";
await ctx.Reply($"{Emojis.Success} Use this link to add {botName} to your server:\n<{invite}>");
}
public async Task Stats(Context ctx)
{
var timeBefore = SystemClock.Instance.GetCurrentInstant();
var msg = await ctx.Reply("...");
var timeAfter = SystemClock.Instance.GetCurrentInstant();
var apiLatency = timeAfter - timeBefore;
2025-01-05 00:52:45 +00:00
var process = Process.GetCurrentProcess();
var stats = await GetStats(ctx);
2022-01-22 03:52:52 -05:00
var shards = await _shards.GetShards();
2022-02-04 14:53:56 -05:00
var shardInfo = shards.Where(s => s.ShardId == ctx.ShardId).FirstOrDefault();
2025-01-05 00:52:45 +00:00
var embed = new EmbedBuilder();
2022-01-22 03:52:52 -05:00
embed
2025-01-05 00:52:45 +00:00
.Field(new("Connection status", $"**{shards.Count()}** shards across **{shards.Select(s => s.ClusterId).Distinct().Count()}** clusters\n"
+ $"Current server is on **shard {ctx.ShardId} (cluster {shardInfo.ClusterId ?? 0})**\n"
+ $"Latency: API **{apiLatency.TotalMilliseconds:F0}ms** (p90: {stats.prom.nirn_proxy_latency_p90 * 1000:F0}ms, p99: {stats.prom.nirn_proxy_latency_p99 * 1000:F0}ms), "
+ $"shard **{shardInfo.Latency}ms** (avg: {stats.prom.shard_latency_average}ms)", true))
.Field(new("Resource usage", $"**CPU:** {stats.prom.cpu_used}% used / {stats.prom.cpu_total_cores} total cores ({stats.prom.cpu_total_threads} threads)\n"
+ $"**Memory:** {(stats.prom.memory_used / 1_000_000_000):N1}GB used / {(stats.prom.memory_total / 1_000_000_000):N1}GB total", true))
.Field(new("Usage metrics", $"Messages received: **{stats.prom.messages_1m}/s** ({stats.prom.messages_15m}/s over 15m)\n" +
$"Messages proxied: **{stats.prom.proxy_1m}/s** ({stats.prom.proxy_15m}/s over 15m, {stats.db.messages_24h} total in last 24h)\n" +
$"Commands executed: **{stats.prom.commands_1m}/m** ({stats.prom.commands_15m}/m over 15m)"));
embed.Field(new("Total numbers", $"**{stats.db.systems:N0}** systems, **{stats.db.members:N0}** members, **{stats.db.groups:N0}** groups, "
+ $"**${stats.db.switches:N0}** switches, **{stats.db.messages:N0}** messages\n" +
$"**{stats.db.guilds:N0}** servers with **{stats.db.channels:N0}** channels"));
embed.Footer(Help.helpEmbed.Footer);
var uptime = ((DateTimeOffset)process.StartTime).ToUnixTimeSeconds();
embed.Description($"### PluralKit [{BuildInfoService.Version}](https://github.com/pluralkit/pluralkit/commit/{BuildInfoService.FullVersion})\n" +
$"Built on <t:{BuildInfoService.Timestamp}> (<t:{BuildInfoService.Timestamp}:R>)"
+ (BuildInfoService.IsDev ? ", **development build**" : "")
+ $"\nLast restart: <t:{uptime}:R>");
2022-01-22 03:52:52 -05:00
await ctx.Rest.EditMessage(msg.ChannelId, msg.Id,
2022-02-26 16:28:20 -05:00
new MessageEditRequest { Content = "", Embeds = new[] { embed.Build() } });
2019-04-29 20:21:16 +02:00
}
2025-01-05 00:52:45 +00:00
private async Task<Stats> GetStats(Context ctx)
{
var db = ctx.Redis.Connection.GetDatabase();
var data = await db.StringGetAsync("statsapi");
return JsonConvert.DeserializeObject<Stats>(data);
}
}
// none of these fields are "assigned to" for some reason
#pragma warning disable CS0649
class Stats
{
public DbStats db;
public PrometheusStats prom;
};
class DbStats
{
public double systems;
public double members;
public double groups;
public double switches;
public double messages;
public double messages_24h;
public double guilds;
public double channels;
};
class PrometheusStats
{
public double messages_1m;
public double messages_15m;
public double proxy_1m;
public double proxy_15m;
public double commands_1m;
public double commands_15m;
public double cpu_total_cores;
public double cpu_total_threads;
public double cpu_used;
public double memory_total;
public double memory_used;
public double nirn_proxy_rps;
public double nirn_proxy_latency_p90;
public double nirn_proxy_latency_p99;
public double shard_latency_average;
};