add basic telemetry

This commit is contained in:
13xforever 2020-04-13 16:50:50 +05:00
parent cd6bec1cdb
commit f9bd3111cc
5 changed files with 72 additions and 14 deletions

View File

@ -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);
}
}

View File

@ -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" />

View File

@ -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);
}
}
}
}

View File

@ -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);
}
}

View File

@ -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);