mirror of
https://github.com/RPCS3/discord-bot.git
synced 2024-11-23 10:19:39 +00:00
add basic telemetry
This commit is contained in:
parent
cd6bec1cdb
commit
f9bd3111cc
@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using CompatBot.Commands.Attributes;
|
||||
using CompatBot.Database.Providers;
|
||||
@ -13,8 +15,11 @@ namespace CompatBot.Commands
|
||||
{
|
||||
internal class BaseCommandModuleCustom : BaseCommandModule
|
||||
{
|
||||
private DateTimeOffset executionStart;
|
||||
|
||||
public override async Task BeforeExecutionAsync(CommandContext ctx)
|
||||
{
|
||||
executionStart = DateTimeOffset.UtcNow;
|
||||
try
|
||||
{
|
||||
if (ctx.Prefix == Config.AutoRemoveCommandPrefix && ModProvider.IsMod(ctx.User.Id))
|
||||
@ -25,21 +30,23 @@ namespace CompatBot.Commands
|
||||
Config.Log.Warn(e, "Failed to delete command message with the autodelete command prefix");
|
||||
}
|
||||
|
||||
if (ctx.Channel.Name == "media" && ctx.Command.QualifiedName != "warn" && ctx.Command.QualifiedName != "report")
|
||||
{
|
||||
Config.Log.Info($"Ignoring command from {ctx.User.Username} (<@{ctx.User.Id}>) in #media: {ctx.Message.Content}");
|
||||
if (ctx.Member is DiscordMember member)
|
||||
{
|
||||
var dm = await member.CreateDmChannelAsync().ConfigureAwait(false);
|
||||
await dm.SendMessageAsync($"Only `{Config.CommandPrefix}warn` and `{Config.CommandPrefix}report` are allowed in {ctx.Channel.Mention}").ConfigureAwait(false);
|
||||
}
|
||||
throw new DSharpPlus.CommandsNext.Exceptions.ChecksFailedException(ctx.Command, ctx, new CheckBaseAttribute[] { new RequiresNotMedia() });
|
||||
}
|
||||
if (ctx.Channel.Name == "media" && ctx.Command.QualifiedName != "warn" && ctx.Command.QualifiedName != "report")
|
||||
{
|
||||
Config.Log.Info($"Ignoring command from {ctx.User.Username} (<@{ctx.User.Id}>) in #media: {ctx.Message.Content}");
|
||||
if (ctx.Member is DiscordMember member)
|
||||
{
|
||||
var dm = await member.CreateDmChannelAsync().ConfigureAwait(false);
|
||||
await dm.SendMessageAsync($"Only `{Config.CommandPrefix}warn` and `{Config.CommandPrefix}report` are allowed in {ctx.Channel.Mention}").ConfigureAwait(false);
|
||||
}
|
||||
Config.TelemetryClient?.TrackRequest(ctx.Command.QualifiedName, executionStart, DateTimeOffset.UtcNow-executionStart, HttpStatusCode.Forbidden.ToString(), true);
|
||||
throw new DSharpPlus.CommandsNext.Exceptions.ChecksFailedException(ctx.Command, ctx, new CheckBaseAttribute[] {new RequiresNotMedia()});
|
||||
}
|
||||
|
||||
var disabledCmds = DisabledCommandsProvider.Get();
|
||||
if (disabledCmds.Contains(ctx.Command.QualifiedName) && !disabledCmds.Contains("*"))
|
||||
{
|
||||
await ctx.RespondAsync(embed: new DiscordEmbedBuilder {Color = Config.Colors.Maintenance, Description = "Command is currently disabled"}).ConfigureAwait(false);
|
||||
Config.TelemetryClient?.TrackRequest(ctx.Command.QualifiedName, executionStart, DateTimeOffset.UtcNow - executionStart, HttpStatusCode.Locked.ToString(), true);
|
||||
throw new DSharpPlus.CommandsNext.Exceptions.ChecksFailedException(ctx.Command, ctx, new CheckBaseAttribute[] {new RequiresDm()});
|
||||
}
|
||||
|
||||
@ -52,8 +59,9 @@ namespace CompatBot.Commands
|
||||
public override async Task AfterExecutionAsync(CommandContext ctx)
|
||||
{
|
||||
var qualifiedName = ctx.Command.QualifiedName;
|
||||
StatsStorage. CmdStatCache.TryGetValue(qualifiedName, out int counter);
|
||||
StatsStorage.CmdStatCache.TryGetValue(qualifiedName, out int counter);
|
||||
StatsStorage.CmdStatCache.Set(qualifiedName, ++counter, StatsStorage.CacheTime);
|
||||
Config.TelemetryClient?.TrackRequest(qualifiedName, executionStart, DateTimeOffset.UtcNow - executionStart, HttpStatusCode.OK.ToString(), true);
|
||||
|
||||
if (TriggersTyping(ctx))
|
||||
await ctx.RemoveReactionAsync(Config.Reactions.PleaseWait).ConfigureAwait(false);
|
||||
@ -62,8 +70,6 @@ namespace CompatBot.Commands
|
||||
}
|
||||
|
||||
private static bool TriggersTyping(CommandContext ctx)
|
||||
{
|
||||
return ctx.Command.CustomAttributes.OfType<TriggersTyping>().FirstOrDefault() is TriggersTyping a && a.ExecuteCheck(ctx);
|
||||
}
|
||||
=> ctx.Command.CustomAttributes.OfType<TriggersTyping>().FirstOrDefault() is TriggersTyping a && a.ExecuteCheck(ctx);
|
||||
}
|
||||
}
|
@ -38,6 +38,9 @@
|
||||
<PackageReference Include="ksemenenko.ColorThief" Version="1.1.1.4" />
|
||||
<PackageReference Include="MathParser.org-mXparser" Version="4.4.2" />
|
||||
<PackageReference Include="MegaApiClient" Version="1.7.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.13.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.DependencyCollector" Version="2.13.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.PerfCounterCollector" Version="2.13.1" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
|
||||
<PackageReference Include="Microsoft.Azure.CognitiveServices.Vision.ComputerVision" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.3" />
|
||||
|
@ -7,6 +7,10 @@ using System.Reflection;
|
||||
using System.Threading;
|
||||
using CompatBot.Utils;
|
||||
using DSharpPlus.Entities;
|
||||
using Microsoft.ApplicationInsights;
|
||||
using Microsoft.ApplicationInsights.DependencyCollector;
|
||||
using Microsoft.ApplicationInsights.Extensibility;
|
||||
using Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Configuration.UserSecrets;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@ -27,6 +31,10 @@ namespace CompatBot
|
||||
internal static class Config
|
||||
{
|
||||
private static IConfigurationRoot config;
|
||||
private static TelemetryClient telemetryClient;
|
||||
private static readonly DependencyTrackingTelemetryModule dependencyTrackingTelemetryModule = new DependencyTrackingTelemetryModule();
|
||||
private static readonly PerformanceCollectorModule performanceCollectorModule = new PerformanceCollectorModule();
|
||||
|
||||
internal static readonly ILogger Log;
|
||||
internal static readonly ILoggerFactory LoggerFactory;
|
||||
internal static readonly ConcurrentDictionary<string, string> inMemorySettings = new ConcurrentDictionary<string, string>();
|
||||
@ -66,6 +74,7 @@ namespace CompatBot
|
||||
public static string AzureComputerVisionKey => config.GetValue(nameof(AzureComputerVisionKey), "");
|
||||
public static string AzureComputerVisionEndpoint => config.GetValue(nameof(AzureComputerVisionEndpoint), "https://westeurope.api.cognitive.microsoft.com/");
|
||||
public static Guid AzureDevOpsProjectId => config.GetValue(nameof(AzureDevOpsProjectId), new Guid("3598951b-4d39-4fad-ad3b-ff2386a649de"));
|
||||
public static string AzureAppInsightsKey => config.GetValue(nameof(AzureAppInsightsKey), "");
|
||||
public static string LogPath => config.GetValue(nameof(LogPath), "./logs/"); // paths are relative to the working directory
|
||||
public static string IrdCachePath => config.GetValue(nameof(IrdCachePath), "./ird/");
|
||||
public static double GameTitleMatchThreshold => config.GetValue(nameof(GameTitleMatchThreshold), 0.57);
|
||||
@ -254,5 +263,24 @@ namespace CompatBot
|
||||
var azureConnection = new VssConnection(new Uri("https://dev.azure.com/nekotekina"), azureCreds);
|
||||
return azureConnection.GetClient<BuildHttpClient>();
|
||||
}
|
||||
|
||||
public static TelemetryClient TelemetryClient
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrEmpty(AzureAppInsightsKey))
|
||||
return null;
|
||||
|
||||
if (telemetryClient != null && telemetryClient.InstrumentationKey == AzureAppInsightsKey)
|
||||
return telemetryClient;
|
||||
|
||||
var telemetryConfig = TelemetryConfiguration.CreateDefault();
|
||||
telemetryConfig.InstrumentationKey = AzureAppInsightsKey;
|
||||
telemetryConfig.TelemetryInitializers.Add(new HttpDependenciesParsingTelemetryInitializer());
|
||||
dependencyTrackingTelemetryModule.Initialize(telemetryConfig);
|
||||
performanceCollectorModule.Initialize(telemetryConfig);
|
||||
return telemetryClient = new TelemetryClient(telemetryConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Pipelines;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using CompatApiClient.Utils;
|
||||
@ -73,10 +74,12 @@ namespace CompatBot.EventHandlers
|
||||
|
||||
public static async void EnqueueLogProcessing(DiscordClient client, DiscordChannel channel, DiscordMessage message, DiscordMember requester = null, bool checkExternalLinks = false)
|
||||
{
|
||||
var start = DateTimeOffset.UtcNow;
|
||||
try
|
||||
{
|
||||
if (!QueueLimiter.Wait(0))
|
||||
{
|
||||
Config.TelemetryClient?.TrackRequest(nameof(LogParsingHandler), start, TimeSpan.Zero, HttpStatusCode.TooManyRequests.ToString(), false);
|
||||
await channel.SendMessageAsync("Log processing is rate limited, try again a bit later").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
@ -123,6 +126,7 @@ namespace CompatBot.EventHandlers
|
||||
.AddAuthor(client, message, source)
|
||||
.Build()
|
||||
).ConfigureAwait(false);
|
||||
Config.TelemetryClient?.TrackRequest(nameof(LogParsingHandler), start, DateTimeOffset.UtcNow - start, HttpStatusCode.InternalServerError.ToString(), false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -192,6 +196,7 @@ namespace CompatBot.EventHandlers
|
||||
embed: await result.AsEmbedAsync(client, message, source).ConfigureAwait(false)
|
||||
).ConfigureAwait(false);
|
||||
}
|
||||
Config.TelemetryClient?.TrackRequest(nameof(LogParsingHandler), start, DateTimeOffset.UtcNow - start, HttpStatusCode.OK.ToString(), true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -203,12 +208,16 @@ namespace CompatBot.EventHandlers
|
||||
else if (!string.IsNullOrEmpty(fail)
|
||||
&& ("help".Equals(channel.Name, StringComparison.InvariantCultureIgnoreCase) || LimitedToSpamChannel.IsSpamChannel(channel)))
|
||||
{
|
||||
Config.TelemetryClient?.TrackRequest(nameof(LogParsingHandler), start, DateTimeOffset.UtcNow - start, HttpStatusCode.InternalServerError.ToString(), false);
|
||||
await channel.SendMessageAsync($"{message.Author.Mention} {fail}").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!"help".Equals(channel.Name, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
Config.TelemetryClient?.TrackRequest(nameof(LogParsingHandler), start, DateTimeOffset.UtcNow - start, HttpStatusCode.NoContent.ToString(), true);
|
||||
return;
|
||||
}
|
||||
|
||||
var potentialLogExtension = message.Attachments.Select(a => Path.GetExtension(a.FileName).ToUpperInvariant().TrimStart('.')).FirstOrDefault();
|
||||
switch (potentialLogExtension)
|
||||
@ -216,19 +225,26 @@ namespace CompatBot.EventHandlers
|
||||
case "TXT":
|
||||
{
|
||||
await channel.SendMessageAsync($"{message.Author.Mention} Please upload the full RPCS3.log.gz (or RPCS3.log with a zip/rar icon) file after closing the emulator instead of copying the logs from RPCS3's interface, as it doesn't contain all the required information.").ConfigureAwait(false);
|
||||
Config.TelemetryClient?.TrackRequest(nameof(LogParsingHandler), start, DateTimeOffset.UtcNow - start, HttpStatusCode.BadRequest.ToString(), true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(message.Content))
|
||||
{
|
||||
Config.TelemetryClient?.TrackRequest(nameof(LogParsingHandler), start, DateTimeOffset.UtcNow - start, HttpStatusCode.NoContent.ToString(), true);
|
||||
return;
|
||||
}
|
||||
|
||||
var linkStart = message.Content.IndexOf("http");
|
||||
if (linkStart > -1)
|
||||
{
|
||||
var link = message.Content[linkStart..].Split(linkSeparator, 2)[0];
|
||||
if (link.Contains(".log", StringComparison.InvariantCultureIgnoreCase) || link.Contains("rpcs3.zip", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
await channel.SendMessageAsync("If you intended to upload a log file please re-upload it directly to discord").ConfigureAwait(false);
|
||||
Config.TelemetryClient?.TrackRequest(nameof(LogParsingHandler), start, DateTimeOffset.UtcNow - start, HttpStatusCode.BadRequest.ToString(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
@ -241,6 +257,8 @@ namespace CompatBot.EventHandlers
|
||||
catch (Exception e)
|
||||
{
|
||||
Config.Log.Error(e, "Error parsing log");
|
||||
Config.TelemetryClient?.TrackRequest(nameof(LogParsingHandler), start, DateTimeOffset.UtcNow - start, HttpStatusCode.InternalServerError.ToString(), false);
|
||||
Config.TelemetryClient?.TrackException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,8 @@ namespace CompatBot
|
||||
|
||||
internal static async Task Main(string[] args)
|
||||
{
|
||||
Config.TelemetryClient?.TrackEvent("startup");
|
||||
|
||||
Console.WriteLine("Confinement: " + SandboxDetector.Detect());
|
||||
if (args.Length > 0 && args[0] == "--dry-run")
|
||||
{
|
||||
@ -368,6 +370,7 @@ namespace CompatBot
|
||||
}
|
||||
finally
|
||||
{
|
||||
Config.TelemetryClient?.Flush();
|
||||
ShutdownCheck.Release();
|
||||
if (singleInstanceCheckThread.IsAlive)
|
||||
singleInstanceCheckThread.Join(100);
|
||||
|
Loading…
Reference in New Issue
Block a user