diff --git a/Chaos.Messaging/ChannelService.cs b/Chaos.Messaging/ChannelService.cs
index 38b73b2b86..b4313ee545 100644
--- a/Chaos.Messaging/ChannelService.cs
+++ b/Chaos.Messaging/ChannelService.cs
@@ -4,6 +4,8 @@
using Chaos.Extensions.Common;
using Chaos.IO.Memory;
using Chaos.Messaging.Abstractions;
+using Chaos.NLog.Logging.Definitions;
+using Chaos.NLog.Logging.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@@ -62,7 +64,9 @@ public void JoinChannel(IChannelSubscriber subscriber, string channelName, bool
if (channelDetails.AddSubscriber(subscriber))
{
- Logger.LogDebug("{@SubscriberName} has joined channel {@ChannelName}", subscriber.Name, channelName);
+ Logger.WithTopics(Topics.Entities.Channel, Topics.Actions.Join)
+ .WithProperty(subscriber)
+ .LogDebug("{@SubscriberName} has joined channel {@ChannelName}", subscriber.Name, channelName);
subscriber.SendMessage($"You have joined channel {channelDetails.ChannelNameOverride ?? channelName}");
} else
@@ -81,7 +85,9 @@ public void LeaveChannel(IChannelSubscriber subscriber, string channelName)
if (channelDetails.RemoveSubscriber(subscriber))
{
- Logger.LogDebug("{@SubscriberName} has left channel {@ChannelName}", subscriber.Name, channelName);
+ Logger.WithTopics(Topics.Entities.Channel, Topics.Actions.Leave)
+ .WithProperty(subscriber)
+ .LogDebug("{@SubscriberName} has left channel {@ChannelName}", subscriber.Name, channelName);
subscriber.SendMessage($"You have left channel {channelDetails.ChannelNameOverride ?? channelName}");
} else
@@ -140,7 +146,9 @@ public void RegisterChannel(
}
Channels.TryAdd(channelName, new ChannelDetails(defaultMessageColor, sendMessageAction, channelNameOverride));
- Logger.LogInformation("Channel {@ChannelName} has been registered", channelName);
+
+ Logger.WithTopics(Topics.Entities.Channel, Topics.Actions.Create)
+ .LogInformation("Channel {@ChannelName} has been registered", channelName);
if (subscriber is not null)
JoinChannel(subscriber, channelName, bypassValidation);
@@ -190,11 +198,13 @@ public void SendMessage(IChannelSubscriber subscriber, string channelName, strin
var defaultMessage = Encoding.Default.GetString(buffer);
- Logger.LogInformation(
- "Subscriber {@SubscriberName} sent message {@Message} to channel {@ChannelName}",
- subscriber.Name,
- message,
- channelName);
+ Logger.WithTopics(Topics.Entities.Channel, Topics.Entities.Message, Topics.Actions.Send)
+ .WithProperty(subscriber)
+ .LogInformation(
+ "Subscriber {@SubscriberName} sent message {@Message} to channel {@ChannelName}",
+ subscriber.Name,
+ message,
+ channelName);
foreach (var subDetails in channelDetails.Subscribers.Values)
{
@@ -239,7 +249,8 @@ public bool UnregisterChannel(string channelName)
foreach (var subDetails in channel.Subscribers.Values)
LeaveChannel(subDetails.Subscriber, channelName);
- Logger.LogInformation("Channel {@ChannelName} has been unregistered", channelName);
+ Logger.WithTopics(Topics.Entities.Channel, Topics.Actions.Delete)
+ .LogInformation("Channel {@ChannelName} has been unregistered", channelName);
return Channels.TryRemove(channelName, out _);
}
diff --git a/Chaos.Messaging/Chaos.Messaging.csproj b/Chaos.Messaging/Chaos.Messaging.csproj
index a84d8d8469..9d9938d442 100644
--- a/Chaos.Messaging/Chaos.Messaging.csproj
+++ b/Chaos.Messaging/Chaos.Messaging.csproj
@@ -6,6 +6,7 @@
+
diff --git a/Chaos.Messaging/CommandInterceptor.cs b/Chaos.Messaging/CommandInterceptor.cs
index ebd7b1afe2..85d30750dd 100644
--- a/Chaos.Messaging/CommandInterceptor.cs
+++ b/Chaos.Messaging/CommandInterceptor.cs
@@ -4,6 +4,8 @@
using Chaos.Common.Definitions;
using Chaos.Extensions.Common;
using Chaos.Messaging.Abstractions;
+using Chaos.NLog.Logging.Definitions;
+using Chaos.NLog.Logging.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@@ -72,15 +74,19 @@ public async ValueTask HandleCommandAsync(T source, string commandStr)
if (!Commands.TryGetValue(commandName, out var descriptor))
return;
- Logger.LogDebug("Handling command {@CommandStr}", commandStr);
+ Logger.WithTopics(Topics.Entities.Command, Topics.Actions.Execute)
+ .WithProperty(source)
+ .LogDebug("Handling command {@CommandStr}", commandStr);
if (descriptor.Details.RequiresAdmin && !source.IsAdmin)
{
- Logger.LogWarning(
- "Non-Admin {@SourceType} {@SourceName} tried to execute admin command {@CommandStr}",
- source.GetType().Name,
- source.Name,
- commandStr);
+ Logger.WithTopics(Topics.Entities.Command, Topics.Actions.Execute)
+ .WithProperty(source)
+ .LogWarning(
+ "Non-Admin {@SourceType} {@SourceName} tried to execute admin command {@CommandStr}",
+ source.GetType().Name,
+ source.Name,
+ commandStr);
return;
}
@@ -89,7 +95,8 @@ public async ValueTask HandleCommandAsync(T source, string commandStr)
{
var commandInstance = (ICommand)ActivatorUtilities.CreateInstance(ServiceProvider, descriptor.Type);
- Logger.LogTrace("Successfully created command {@CommandName}", commandName);
+ Logger.WithTopics(Topics.Entities.Command, Topics.Actions.Create)
+ .LogTrace("Successfully created command {@CommandName}", commandName);
if (commandName.EqualsI("help") || commandName.EqualsI("commands"))
{
@@ -103,22 +110,26 @@ async ValueTask InnerExecute()
{
await commandInstance.ExecuteAsync(source, new ArgumentCollection(commandArgs));
- Logger.LogInformation(
- "{@SourceType} {@SourceName} executed {@CommandStr}",
- source.GetType().Name,
- source.Name,
- commandStr);
+ Logger.WithTopics(Topics.Entities.Command, Topics.Actions.Execute)
+ .WithProperty(source)
+ .LogInformation(
+ "{@SourceType} {@SourceName} executed {@CommandStr}",
+ source.GetType().Name,
+ source.Name,
+ commandStr);
}
await InnerExecute();
} catch (Exception e)
{
- Logger.LogError(
- e,
- "{@SourceType} {@SourceName} failed to execute {@Command}",
- source.GetType().Name,
- source.Name,
- commandStr);
+ Logger.WithTopics(Topics.Entities.Command, Topics.Actions.Execute)
+ .WithProperty(source)
+ .LogError(
+ e,
+ "{@SourceType} {@SourceName} failed to execute {@Command}",
+ source.GetType().Name,
+ source.Name,
+ commandStr);
}
}
diff --git a/Chaos.NLog.Logging/Chaos.NLog.Logging.csproj b/Chaos.NLog.Logging/Chaos.NLog.Logging.csproj
index eb70ae6cc2..c2196952d9 100644
--- a/Chaos.NLog.Logging/Chaos.NLog.Logging.csproj
+++ b/Chaos.NLog.Logging/Chaos.NLog.Logging.csproj
@@ -1,6 +1,6 @@
-
+
diff --git a/Chaos.NLog.Logging/Definitions/Topics.cs b/Chaos.NLog.Logging/Definitions/Topics.cs
index 6e6ada52fa..a7ef466aef 100644
--- a/Chaos.NLog.Logging/Definitions/Topics.cs
+++ b/Chaos.NLog.Logging/Definitions/Topics.cs
@@ -5,76 +5,62 @@ public static class Topics
{
public static class Actions
{
- #region Bank Actions
- public static string Deposit => nameof(Deposit);
- public static string Withdraw => nameof(Withdraw);
- #endregion
-
- #region Shop Actions
+ public static string Accepted => nameof(Accepted);
+ public static string Add => nameof(Add);
+ public static string Admit => nameof(Admit);
public static string Buy => nameof(Buy);
- public static string Sell => nameof(Sell);
- #endregion
-
- #region Exchange Actions
public static string Canceled => nameof(Canceled);
- public static string Accepted => nameof(Accepted);
- #endregion
-
- #region Guild / Group Actions
- public static string Promote => nameof(Promote);
+ public static string Connect => nameof(Connect);
+ public static string Create => nameof(Create);
+ public static string Death => nameof(Death);
+ public static string Delete => nameof(Delete);
public static string Demote => nameof(Demote);
- public static string Kick => nameof(Kick);
- public static string Admit => nameof(Admit);
- public static string Invite => nameof(Invite);
- public static string Leave => nameof(Leave);
+ public static string Deposit => nameof(Deposit);
public static string Disband => nameof(Disband);
- #endregion
-
- #region Creature Actions
- public static string Walk => nameof(Walk);
- public static string Traverse => nameof(Traverse);
- public static string Death => nameof(Death);
+ public static string Disconnect => nameof(Disconnect);
public static string Drop => nameof(Drop);
+ public static string Execute => nameof(Execute);
+ public static string Forget => nameof(Forget);
+ public static string Highlight => nameof(Highlight);
+ public static string Invite => nameof(Invite);
+ public static string Join => nameof(Join);
+ public static string Kick => nameof(Kick);
+ public static string Learn => nameof(Learn);
+ public static string Leave => nameof(Leave);
+ public static string Listening => nameof(Listening);
+ public static string Load => nameof(Load);
public static string Login => nameof(Login);
public static string Logout => nameof(Logout);
+ public static string Penalty => nameof(Penalty);
public static string Pickup => nameof(Pickup);
- public static string Reward => nameof(Reward);
- public static string Message => nameof(Message);
- public static string Command => nameof(Command);
- public static string Learn => nameof(Learn);
- public static string Forget => nameof(Forget);
- #endregion
-
- #region Storage Actions
- public static string Load => nameof(Load);
- public static string Reload => nameof(Reload);
- public static string Save => nameof(Save);
- public static string Add => nameof(Add);
- public static string Remove => nameof(Remove);
- public static string Create => nameof(Create);
- public static string Read => nameof(Read);
- public static string Update => nameof(Update);
- public static string Delete => nameof(Delete);
- public static string Highlight => nameof(Highlight);
- #endregion
-
- #region Server Actions
public static string Processing => nameof(Processing);
+ public static string Promote => nameof(Promote);
+ public static string Read => nameof(Read);
public static string Receive => nameof(Receive);
- public static string Send => nameof(Send);
public static string Redirect => nameof(Redirect);
- public static string Connect => nameof(Connect);
- public static string Disconnect => nameof(Disconnect);
+ public static string Reload => nameof(Reload);
+ public static string Remove => nameof(Remove);
+ public static string Reward => nameof(Reward);
+ public static string Save => nameof(Save);
+ public static string Sell => nameof(Sell);
+ public static string Send => nameof(Send);
+ public static string Traverse => nameof(Traverse);
+ public static string Update => nameof(Update);
public static string Validation => nameof(Validation);
- #endregion
+ public static string Walk => nameof(Walk);
+ public static string Withdraw => nameof(Withdraw);
}
public static class Entities
{
public static string Aisling => nameof(Aisling);
+ public static string Backup => nameof(Backup);
public static string BulletinBoard => nameof(BulletinBoard);
+ public static string Channel => nameof(Channel);
public static string Client => nameof(Client);
+ public static string Command => nameof(Command);
public static string Creature => nameof(Creature);
+ public static string DeltaMonitor => nameof(DeltaMonitor);
public static string Dialog => nameof(Dialog);
public static string Effect => nameof(Effect);
public static string Exchange => nameof(Exchange);
@@ -89,11 +75,14 @@ public static class Entities
public static string MapInstance => nameof(MapInstance);
public static string MapTemplate => nameof(MapTemplate);
public static string Merchant => nameof(Merchant);
+ public static string Message => nameof(Message);
public static string MetaData => nameof(MetaData);
public static string Monster => nameof(Monster);
public static string Options => nameof(Options);
public static string Packet => nameof(Packet);
public static string Post => nameof(Post);
+ public static string Quest => nameof(Quest);
+ public static string Script => nameof(Script);
public static string Skill => nameof(Skill);
public static string Spell => nameof(Spell);
public static string WorldMap => nameof(WorldMap);
diff --git a/Chaos.Networking/Abstractions/ServerBase.cs b/Chaos.Networking/Abstractions/ServerBase.cs
index 43c82223bf..da758f559e 100644
--- a/Chaos.Networking/Abstractions/ServerBase.cs
+++ b/Chaos.Networking/Abstractions/ServerBase.cs
@@ -4,6 +4,8 @@
using Chaos.Extensions.Common;
using Chaos.Networking.Entities.Client;
using Chaos.Networking.Options;
+using Chaos.NLog.Logging.Definitions;
+using Chaos.NLog.Logging.Extensions;
using Chaos.Packets;
using Chaos.Packets.Abstractions;
using Chaos.Packets.Abstractions.Definitions;
@@ -97,7 +99,9 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
Socket.Bind(endPoint);
Socket.Listen(20);
Socket.BeginAccept(OnConnection, Socket);
- Logger.LogInformation("Listening on {@EndPoint}", endPoint.ToString());
+
+ Logger.WithTopics(Topics.Actions.Listening)
+ .LogInformation("Listening on {@EndPoint}", endPoint.ToString());
await stoppingToken.WaitTillCanceled();
@@ -165,12 +169,13 @@ public virtual async ValueTask ExecuteHandler(T client, TArgs args, Func<
await action(client, args);
} catch (Exception e)
{
- Logger.LogError(
- e,
- "{@ClientType} failed to execute inner handler with args type {@ArgsType} ({@Args})",
- client.GetType().Name,
- args!.GetType().Name,
- args);
+ Logger.WithTopics(Topics.Entities.Packet, Topics.Actions.Processing)
+ .LogError(
+ e,
+ "{@ClientType} failed to execute inner handler with args type {@ArgsType} ({@Args})",
+ client.GetType().Name,
+ args!.GetType().Name,
+ args);
}
}
@@ -188,7 +193,8 @@ public virtual async ValueTask ExecuteHandler(T client, Func actio
await action(client);
} catch (Exception e)
{
- Logger.LogError(e, "{@ClientType} failed to execute inner handler", client.GetType().Name);
+ Logger.WithTopics(Topics.Entities.Packet, Topics.Actions.Processing)
+ .LogError(e, "{@ClientType} failed to execute inner handler", client.GetType().Name);
}
}
diff --git a/Chaos.Networking/Abstractions/SocketClientBase.cs b/Chaos.Networking/Abstractions/SocketClientBase.cs
index 90c7b96df9..e19786787d 100644
--- a/Chaos.Networking/Abstractions/SocketClientBase.cs
+++ b/Chaos.Networking/Abstractions/SocketClientBase.cs
@@ -7,6 +7,8 @@
using Chaos.Extensions.Networking;
using Chaos.IO.Memory;
using Chaos.Networking.Entities.Server;
+using Chaos.NLog.Logging.Definitions;
+using Chaos.NLog.Logging.Extensions;
using Chaos.Packets;
using Chaos.Packets.Abstractions;
using Chaos.Packets.Abstractions.Definitions;
@@ -199,14 +201,16 @@ void InnerCatch()
var hex = BitConverter.ToString(buffer.ToArray()).Replace("-", " ");
var ascii = Encoding.ASCII.GetString(buffer);
- Logger.LogCritical(
- ex,
- "Exception while handling a packet for {@ClientType}. (Count: {Count}, Offset: {Offset}, BufferHex: {BufferHex}, BufferAscii: {BufferAscii})",
- GetType().Name,
- Count,
- offset,
- hex,
- ascii);
+ Logger.WithTopics(Topics.Entities.Client, Topics.Entities.Packet, Topics.Actions.Processing)
+ .WithProperty(this)
+ .LogError(
+ ex,
+ "Exception while handling a packet for {@ClientType}. (Count: {Count}, Offset: {Offset}, BufferHex: {BufferHex}, BufferAscii: {BufferAscii})",
+ GetType().Name,
+ Count,
+ offset,
+ hex,
+ ascii);
}
InnerCatch();
@@ -256,7 +260,13 @@ public virtual void Send(ref ServerPacket packet)
//no way to pass the packet in because its a ref struct
//but we still want to avoid serializing the packet to a string if we aren't actually going to log it
if (LogRawPackets)
- Logger.LogTrace("[Snd] {Packet}", packet.ToString());
+ Logger.WithTopics(
+ Topics.Qualifiers.Raw,
+ Topics.Entities.Client,
+ Topics.Entities.Packet,
+ Topics.Actions.Send)
+ .WithProperty(this)
+ .LogTrace("[Snd] {Packet}", packet.ToString());
packet.ShouldEncrypt = Crypto.ShouldEncrypt((byte)packet.OpCode);
diff --git a/Chaos.Networking/Chaos.Networking.csproj b/Chaos.Networking/Chaos.Networking.csproj
index 72970fd863..f029a8898e 100644
--- a/Chaos.Networking/Chaos.Networking.csproj
+++ b/Chaos.Networking/Chaos.Networking.csproj
@@ -4,6 +4,7 @@
+
diff --git a/Chaos.Networking/Entities/RedirectManager.cs b/Chaos.Networking/Entities/RedirectManager.cs
index d95eb482f0..a72ebfdab4 100644
--- a/Chaos.Networking/Entities/RedirectManager.cs
+++ b/Chaos.Networking/Entities/RedirectManager.cs
@@ -1,4 +1,6 @@
using Chaos.Networking.Abstractions;
+using Chaos.NLog.Logging.Definitions;
+using Chaos.NLog.Logging.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
@@ -21,7 +23,8 @@ public sealed class RedirectManager : BackgroundService, IRedirectManager
///
public void Add(IRedirect redirect)
{
- Logger.LogTrace("Now tracking redirect {@RedirectId}", redirect.Id);
+ Logger.WithTopics(Topics.Actions.Redirect)
+ .LogTrace("Now tracking redirect {@RedirectId}", redirect.Id);
Redirects.TryAdd(redirect.Id, redirect);
}
@@ -31,7 +34,8 @@ public bool TryGetRemove(uint id, [MaybeNullWhen(false)] out IRedirect redirect)
{
if (Redirects.TryRemove(id, out redirect))
{
- Logger.LogTrace("Redirect {@RedirectId} has been consumed", redirect.Id);
+ Logger.WithTopics(Topics.Actions.Redirect)
+ .LogTrace("Redirect {@RedirectId} has been consumed", redirect.Id);
return true;
}
@@ -53,7 +57,8 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
foreach (var redirect in Redirects.Values)
if (now.Subtract(redirect.Created) > Timeout)
{
- Logger.LogTrace("Redirect {@RedirectId} has timed out", redirect.Id);
+ Logger.WithTopics(Topics.Actions.Redirect)
+ .LogTrace("Redirect {@RedirectId} has timed out", redirect.Id);
Redirects.TryRemove(redirect.Id, out _);
}
diff --git a/Chaos.Packets/Chaos.Packets.csproj b/Chaos.Packets/Chaos.Packets.csproj
index 4a9d8b94aa..a26d53a1a6 100644
--- a/Chaos.Packets/Chaos.Packets.csproj
+++ b/Chaos.Packets/Chaos.Packets.csproj
@@ -2,4 +2,7 @@
+
+
+
\ No newline at end of file
diff --git a/Chaos.Packets/ClientPacket.cs b/Chaos.Packets/ClientPacket.cs
index 5a30bdb082..bf2d29a541 100644
--- a/Chaos.Packets/ClientPacket.cs
+++ b/Chaos.Packets/ClientPacket.cs
@@ -1,6 +1,5 @@
using System.Text;
using Chaos.Packets.Abstractions.Definitions;
-using Chaos.Packets.Definitions;
namespace Chaos.Packets;
@@ -67,7 +66,7 @@ public readonly string GetAsciiString(bool replaceNewline = true)
/// Returns the packet data as a hexadecimal string.
///
/// The packet data as a hexadecimal string.
- public string GetHexString() => $"{OpCode}: {RegexCache.DOUBLE_BYTE_REGEX.Replace(Convert.ToHexString(Buffer), "$1 ")}";
+ public string GetHexString() => $"{OpCode}: {BitConverter.ToString(Buffer.ToArray()).Replace("-", " ")}";
///
/// Converts the packet data to a byte array.
diff --git a/Chaos.Packets/Definitions/RegexCache.cs b/Chaos.Packets/Definitions/RegexCache.cs
deleted file mode 100644
index 8e718fa6e9..0000000000
--- a/Chaos.Packets/Definitions/RegexCache.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System.Text.RegularExpressions;
-
-namespace Chaos.Packets.Definitions;
-
-internal static partial class RegexCache
-{
- internal static readonly Regex DOUBLE_BYTE_REGEX = GenerateDoubleByteRegex();
-
- [GeneratedRegex("(.{2})", RegexOptions.Compiled)]
- private static partial Regex GenerateDoubleByteRegex();
-}
\ No newline at end of file
diff --git a/Chaos.Packets/ServerPacket.cs b/Chaos.Packets/ServerPacket.cs
index b1fa0a6a84..37d6c5fd0e 100644
--- a/Chaos.Packets/ServerPacket.cs
+++ b/Chaos.Packets/ServerPacket.cs
@@ -1,6 +1,5 @@
using System.Text;
using Chaos.Packets.Abstractions.Definitions;
-using Chaos.Packets.Definitions;
namespace Chaos.Packets;
@@ -75,7 +74,7 @@ public readonly string GetAsciiString(bool replaceNewline = true)
/// Gets the hexadecimal string representation of the packet buffer.
///
/// The hexadecimal string representation of the packet buffer.
- public string GetHexString() => $"{OpCode}: {RegexCache.DOUBLE_BYTE_REGEX.Replace(Convert.ToHexString(Buffer), "$1 ")}";
+ public string GetHexString() => $"{OpCode}: {BitConverter.ToString(Buffer.ToArray()).Replace("-", " ")}";
///
/// Converts the packet data to an array of bytes.
diff --git a/Chaos.Schemas/Aisling/AislingSchema.cs b/Chaos.Schemas/Aisling/AislingSchema.cs
index 80ca5fc723..17eeaed214 100644
--- a/Chaos.Schemas/Aisling/AislingSchema.cs
+++ b/Chaos.Schemas/Aisling/AislingSchema.cs
@@ -30,10 +30,6 @@ public sealed record AislingSchema
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public Direction Direction { get; set; }
///
- /// A collection of effects that are currently active on the aisling
- ///
- public ICollection Effects { get; set; } = Array.Empty();
- ///
/// The sprite id of the aisling's face
///
public int FaceSprite { get; set; }
diff --git a/Chaos.Scripting/Chaos.Scripting.csproj b/Chaos.Scripting/Chaos.Scripting.csproj
index 4c145cfb8f..8609c68355 100644
--- a/Chaos.Scripting/Chaos.Scripting.csproj
+++ b/Chaos.Scripting/Chaos.Scripting.csproj
@@ -5,6 +5,7 @@
+
\ No newline at end of file
diff --git a/Chaos.Scripting/ScriptFactory.cs b/Chaos.Scripting/ScriptFactory.cs
index d1f4839751..eb1faf7eab 100644
--- a/Chaos.Scripting/ScriptFactory.cs
+++ b/Chaos.Scripting/ScriptFactory.cs
@@ -1,5 +1,7 @@
using System.Collections.Concurrent;
using Chaos.Extensions.Common;
+using Chaos.NLog.Logging.Definitions;
+using Chaos.NLog.Logging.Extensions;
using Chaos.Scripting.Abstractions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@@ -73,7 +75,9 @@ public TScript CreateScript(ICollection scriptKeys, TScripted subject)
if (instance is not TScript tScript)
{
- Logger.LogError("Script obtained from key {@ScriptKey} is not of type {@TypeName}", scriptKey, TypeName);
+ Logger.WithTopics(Topics.Entities.Script, Topics.Actions.Create)
+ .WithProperty(subject)
+ .LogError("Script obtained from key {@ScriptKey} is not of type {@TypeName}", scriptKey, TypeName);
continue;
}
@@ -97,13 +101,15 @@ private void LoadScriptTypes()
var scriptKey = ScriptBase.GetScriptKey(type);
ScriptTypeCache[scriptKey] = type;
- Logger.LogTrace(
- "Cached {@TypeName} of type {@Type} with key {@ScriptKey}",
- TypeName,
- type.Name,
- scriptKey);
+ Logger.WithTopics(Topics.Entities.Script, Topics.Actions.Load)
+ .LogTrace(
+ "Cached {@TypeName} of type {@Type} with key {@ScriptKey}",
+ TypeName,
+ type.Name,
+ scriptKey);
}
- Logger.LogInformation("{Count} {@TScriptName}s loaded", ScriptTypeCache.Count, TypeName);
+ Logger.WithTopics(Topics.Entities.Script, Topics.Actions.Load)
+ .LogInformation("{Count} {@TScriptName}s loaded", ScriptTypeCache.Count, TypeName);
}
}
\ No newline at end of file
diff --git a/Chaos.Security/AccessManager.cs b/Chaos.Security/AccessManager.cs
index b673913f56..b690a2847f 100644
--- a/Chaos.Security/AccessManager.cs
+++ b/Chaos.Security/AccessManager.cs
@@ -4,6 +4,8 @@
using System.Text;
using Chaos.Common.Synchronization;
using Chaos.Extensions.Common;
+using Chaos.NLog.Logging.Definitions;
+using Chaos.NLog.Logging.Extensions;
using Chaos.Security.Abstractions;
using Chaos.Security.Definitions;
using Chaos.Security.Options;
@@ -91,9 +93,10 @@ string newPassword
if (!result.Success)
{
if (result.Code == CredentialValidationResult.FailureCode.TooManyAttempts)
- Logger.LogWarning(
- "{@ClientIp} has exceeded the maximum number of credential attempts while attempting to change password",
- ipAddress.ToString());
+ Logger.WithTopics(Topics.Entities.Client, Topics.Actions.Validation)
+ .LogWarning(
+ "{@ClientIp} has exceeded the maximum number of credential attempts while attempting to change password",
+ ipAddress.ToString());
return result;
}
@@ -165,9 +168,10 @@ public async Task ValidateCredentialsAsync(IPAddress
var result = await InnerValidateCredentialsAsync(ipAddress, name, password);
if (result is { Success: false, Code: CredentialValidationResult.FailureCode.TooManyAttempts })
- Logger.LogWarning(
- "{@ClientIp} has exceeded the maximum number of credential attempts while attempting to log in",
- ipAddress.ToString());
+ Logger.WithTopics(Topics.Entities.Client, Topics.Actions.Validation)
+ .LogWarning(
+ "{@ClientIp} has exceeded the maximum number of credential attempts while attempting to log in",
+ ipAddress.ToString());
return result;
}
diff --git a/Chaos.Security/Chaos.Security.csproj b/Chaos.Security/Chaos.Security.csproj
index fbf13dc7bd..ec6cc922da 100644
--- a/Chaos.Security/Chaos.Security.csproj
+++ b/Chaos.Security/Chaos.Security.csproj
@@ -3,6 +3,7 @@
+
diff --git a/Chaos.Storage.Abstractions/Chaos.Storage.Abstractions.csproj b/Chaos.Storage.Abstractions/Chaos.Storage.Abstractions.csproj
index 02926c3c1a..ed73b0d95a 100644
--- a/Chaos.Storage.Abstractions/Chaos.Storage.Abstractions.csproj
+++ b/Chaos.Storage.Abstractions/Chaos.Storage.Abstractions.csproj
@@ -10,6 +10,8 @@
+
+
\ No newline at end of file
diff --git a/Chaos.Storage.Abstractions/DirectoryBackupService.cs b/Chaos.Storage.Abstractions/DirectoryBackupService.cs
index 8b3cd8e1d1..7a02c9342b 100644
--- a/Chaos.Storage.Abstractions/DirectoryBackupService.cs
+++ b/Chaos.Storage.Abstractions/DirectoryBackupService.cs
@@ -1,6 +1,7 @@
-using System.Diagnostics;
using System.IO.Compression;
using Chaos.IO.FileSystem;
+using Chaos.NLog.Logging.Definitions;
+using Chaos.NLog.Logging.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@@ -36,7 +37,8 @@ public virtual ValueTask HandleBackupRetentionAsync(string directory, Cancellati
if (!directoryInfo.Exists)
{
- Logger.LogError("Failed to handle backup retention for path {@Directory} because it doesn't exist", directory);
+ Logger.WithTopics(Topics.Entities.Backup, Topics.Actions.Save)
+ .LogError("Failed to handle backup retention for path {@Directory} because it doesn't exist", directory);
return default;
}
@@ -47,7 +49,9 @@ public virtual ValueTask HandleBackupRetentionAsync(string directory, Cancellati
if (fileInfo.CreationTimeUtc < deleteTime)
try
{
- Logger.LogTrace("Deleting backup {@Backup}", fileInfo.FullName);
+ Logger.WithTopics(Topics.Entities.Backup, Topics.Actions.Delete)
+ .LogTrace("Deleting backup {@Backup}", fileInfo.FullName);
+
fileInfo.Delete();
} catch
{
@@ -66,7 +70,8 @@ public virtual ValueTask TakeBackupAsync(string saveDirectory, CancellationToken
if (!directoryInfo.Exists)
{
- Logger.LogError("Failed to take backup for path {@SaveDir} because it doesn't exist", saveDirectory);
+ Logger.WithTopics(Topics.Entities.Backup, Topics.Actions.Save)
+ .LogError("Failed to take backup for path {@SaveDir} because it doesn't exist", saveDirectory);
return default;
}
@@ -89,12 +94,15 @@ public virtual ValueTask TakeBackupAsync(string saveDirectory, CancellationToken
saveDirectory.SafeExecute(
saveDir =>
{
- Logger.LogTrace("Backing up directory {@SaveDir}", saveDirectory);
+ Logger.WithTopics(Topics.Entities.Backup, Topics.Actions.Save)
+ .LogTrace("Backing up directory {@SaveDir}", saveDirectory);
+
ZipFile.CreateFromDirectory(saveDir, backupPath);
});
} catch (Exception e)
{
- Logger.LogError(e, "Failed to take backup for path {@SaveDir}", saveDirectory);
+ Logger.WithTopics(Topics.Entities.Backup, Topics.Actions.Save)
+ .LogError(e, "Failed to take backup for path {@SaveDir}", saveDirectory);
}
return default;
@@ -114,9 +122,12 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
try
{
await backupTimer.WaitForNextTickAsync(stoppingToken);
- var start = Stopwatch.GetTimestamp();
- Logger.LogDebug("Performing backup");
+ Logger.WithTopics(Topics.Entities.Backup, Topics.Actions.Save)
+ .LogDebug("Performing backup");
+
+ var metricsLogger = Logger.WithTopics(Topics.Entities.Backup, Topics.Actions.Save)
+ .WithMetrics();
await Parallel.ForEachAsync(
Directory.EnumerateDirectories(Options.Directory),
@@ -125,14 +136,16 @@ await Parallel.ForEachAsync(
await Parallel.ForEachAsync(Directory.EnumerateDirectories(Options.BackupDirectory), pOptions, HandleBackupRetentionAsync);
- Logger.LogDebug("Backup completed, took {@Elapsed}", Stopwatch.GetElapsedTime(start));
+ metricsLogger.WithTopics(Topics.Entities.Backup, Topics.Actions.Save)
+ .LogDebug("Backup completed");
} catch (OperationCanceledException)
{
//ignore
return;
} catch (Exception e)
{
- Logger.LogCritical(e, "Exception occurred while performing backup");
+ Logger.WithTopics(Topics.Entities.Backup, Topics.Actions.Save)
+ .LogError(e, "Exception occurred while performing backup");
}
}
}
\ No newline at end of file
diff --git a/Chaos.Storage/EntityRepository.cs b/Chaos.Storage/EntityRepository.cs
index a7b0685fdc..05e2061ee0 100644
--- a/Chaos.Storage/EntityRepository.cs
+++ b/Chaos.Storage/EntityRepository.cs
@@ -1,6 +1,8 @@
using System.Runtime.Serialization;
using System.Text.Json;
using Chaos.Common.Utilities;
+using Chaos.NLog.Logging.Definitions;
+using Chaos.NLog.Logging.Extensions;
using Chaos.Storage.Abstractions;
using Chaos.TypeMapper.Abstractions;
using Microsoft.Extensions.Logging;
@@ -32,7 +34,8 @@ public TSchema Load(string path)
{
ArgumentException.ThrowIfNullOrEmpty(path);
- Logger.LogTrace("Loading new unmapped {@TypeName} object from path {@Path}", typeof(TSchema).Name, path);
+ Logger.WithTopics(Topics.Actions.Load)
+ .LogTrace("Loading new unmapped {@TypeName} object from path {@Path}", typeof(TSchema).Name, path);
var schema = JsonSerializerEx.Deserialize(path, JsonSerializerOptions);
@@ -47,7 +50,8 @@ public T LoadAndMap(string path, Action? preMapAction = nul
{
ArgumentException.ThrowIfNullOrEmpty(path);
- Logger.LogTrace("Loading new {@TypeName} object from path {@Path}", typeof(T).Name, path);
+ Logger.WithTopics(Topics.Actions.Load)
+ .LogTrace("Loading new {@TypeName} object from path {@Path}", typeof(T).Name, path);
var schema = JsonSerializerEx.Deserialize(path, JsonSerializerOptions);
@@ -64,7 +68,8 @@ public async Task LoadAndMapAsync(string path, Func(path, JsonSerializerOptions);
@@ -82,7 +87,8 @@ public IEnumerable LoadAndMapMany(string path, Action? p
{
ArgumentException.ThrowIfNullOrEmpty(path);
- Logger.LogTrace("Loading collection of {@TypeName} objects from path {@Path}", typeof(T).Name, path);
+ Logger.WithTopics(Topics.Actions.Load)
+ .LogTrace("Loading collection of {@TypeName} objects from path {@Path}", typeof(T).Name, path);
var schemas = JsonSerializerEx.Deserialize>(path, JsonSerializerOptions)!;
@@ -100,7 +106,8 @@ public async IAsyncEnumerable LoadAndMapManyAsync(string path, Fu
{
ArgumentException.ThrowIfNullOrEmpty(path);
- Logger.LogTrace("Loading collection of {@TypeName} objects from path {@Path}", typeof(T).Name, path);
+ Logger.WithTopics(Topics.Actions.Load)
+ .LogTrace("Loading collection of {@TypeName} objects from path {@Path}", typeof(T).Name, path);
var schemas = await JsonSerializerEx.DeserializeAsync>(path, JsonSerializerOptions);
@@ -124,7 +131,8 @@ public async Task LoadAsync(string path)
{
ArgumentException.ThrowIfNullOrEmpty(path);
- Logger.LogTrace("Loading new unmapped {@TypeName} object from path {@Path}", typeof(TSchema).Name, path);
+ Logger.WithTopics(Topics.Actions.Load)
+ .LogTrace("Loading new unmapped {@TypeName} object from path {@Path}", typeof(TSchema).Name, path);
var schema = await JsonSerializerEx.DeserializeAsync(path, JsonSerializerOptions);
@@ -139,7 +147,8 @@ public IEnumerable LoadMany(string path)
{
ArgumentException.ThrowIfNullOrEmpty(path);
- Logger.LogTrace("Loading collection of unmapped {@TypeName} objects from path {@Path}", typeof(TSchema).Name, path);
+ Logger.WithTopics(Topics.Actions.Load)
+ .LogTrace("Loading collection of unmapped {@TypeName} objects from path {@Path}", typeof(TSchema).Name, path);
var schemas = JsonSerializerEx.Deserialize>(path, JsonSerializerOptions);
@@ -154,7 +163,8 @@ public async IAsyncEnumerable LoadManyAsync(string path)
{
ArgumentException.ThrowIfNullOrEmpty(path);
- Logger.LogTrace("Loading collection of unmapped {@TypeName} objects from path {@Path}", typeof(TSchema).Name, path);
+ Logger.WithTopics(Topics.Actions.Load)
+ .LogTrace("Loading collection of unmapped {@TypeName} objects from path {@Path}", typeof(TSchema).Name, path);
var schemas = await JsonSerializerEx.DeserializeAsync>(path, JsonSerializerOptions);
@@ -171,7 +181,8 @@ public void Save(TSchema obj, string path)
ArgumentNullException.ThrowIfNull(obj);
ArgumentException.ThrowIfNullOrEmpty(path);
- Logger.LogTrace("Saving {@TypeName} to path {@Path}", typeof(TSchema).Name, path);
+ Logger.WithTopics(Topics.Actions.Save)
+ .LogTrace("Saving {@TypeName} to path {@Path}", typeof(TSchema).Name, path);
JsonSerializerEx.Serialize(path, obj, JsonSerializerOptions);
}
@@ -182,7 +193,8 @@ public void SaveAndMap(T obj, string path)
ArgumentNullException.ThrowIfNull(obj);
ArgumentException.ThrowIfNullOrEmpty(path);
- Logger.LogTrace("Saving {@TypeName} to path {@Path}", typeof(T).Name, path);
+ Logger.WithTopics(Topics.Actions.Save)
+ .LogTrace("Saving {@TypeName} to path {@Path}", typeof(T).Name, path);
var schema = Mapper.Map(obj)!;
@@ -195,7 +207,8 @@ public Task SaveAndMapAsync(T obj, string path)
ArgumentNullException.ThrowIfNull(obj);
ArgumentException.ThrowIfNullOrEmpty(path);
- Logger.LogTrace("Saving {@TypeName} to path {@Path}", typeof(T).Name, path);
+ Logger.WithTopics(Topics.Actions.Save)
+ .LogTrace("Saving {@TypeName} to path {@Path}", typeof(T).Name, path);
var schema = Mapper.Map(obj)!;
@@ -208,7 +221,8 @@ public void SaveAndMapMany(IEnumerable obj, string path)
ArgumentNullException.ThrowIfNull(obj);
ArgumentException.ThrowIfNullOrEmpty(path);
- Logger.LogTrace("Saving many {@TypeName} to path {@Path}", typeof(T).Name, path);
+ Logger.WithTopics(Topics.Actions.Save)
+ .LogTrace("Saving many {@TypeName} to path {@Path}", typeof(T).Name, path);
var schema = Mapper.MapMany(obj);
@@ -221,7 +235,8 @@ public Task SaveAndMapManyAsync(IEnumerable obj, string path)
ArgumentNullException.ThrowIfNull(obj);
ArgumentException.ThrowIfNullOrEmpty(path);
- Logger.LogTrace("Saving many {@TypeName} to path {@Path}", typeof(T).Name, path);
+ Logger.WithTopics(Topics.Actions.Save)
+ .LogTrace("Saving many {@TypeName} to path {@Path}", typeof(T).Name, path);
var schema = Mapper.MapMany(obj);
@@ -234,7 +249,8 @@ public Task SaveAsync(TSchema obj, string path)
ArgumentNullException.ThrowIfNull(obj);
ArgumentException.ThrowIfNullOrEmpty(path);
- Logger.LogTrace("Saving {@TypeName} to path {@Path}", typeof(TSchema).Name, path);
+ Logger.WithTopics(Topics.Actions.Save)
+ .LogTrace("Saving {@TypeName} to path {@Path}", typeof(TSchema).Name, path);
return JsonSerializerEx.SerializeAsync(path, obj, JsonSerializerOptions);
}
@@ -245,7 +261,8 @@ public void SaveMany(IEnumerable obj, string path)
ArgumentNullException.ThrowIfNull(obj);
ArgumentException.ThrowIfNullOrEmpty(path);
- Logger.LogTrace("Saving many {@TypeName} to path {@Path}", typeof(TSchema).Name, path);
+ Logger.WithTopics(Topics.Actions.Save)
+ .LogTrace("Saving many {@TypeName} to path {@Path}", typeof(TSchema).Name, path);
JsonSerializerEx.Serialize(path, obj, JsonSerializerOptions);
}
@@ -256,7 +273,8 @@ public Task SaveManyAsync(IEnumerable obj, string path)
ArgumentNullException.ThrowIfNull(obj);
ArgumentException.ThrowIfNullOrEmpty(path);
- Logger.LogTrace("Saving many {@TypeName} to path {@Path}", typeof(TSchema).Name, path);
+ Logger.WithTopics(Topics.Actions.Save)
+ .LogTrace("Saving many {@TypeName} to path {@Path}", typeof(TSchema).Name, path);
return JsonSerializerEx.SerializeAsync(path, obj, JsonSerializerOptions);
}
diff --git a/Chaos.Storage/ExpiringFileCache.cs b/Chaos.Storage/ExpiringFileCache.cs
index c8120f0add..b7e69ef937 100644
--- a/Chaos.Storage/ExpiringFileCache.cs
+++ b/Chaos.Storage/ExpiringFileCache.cs
@@ -1,9 +1,10 @@
using System.Collections;
using System.Collections.Concurrent;
-using System.Diagnostics;
using Chaos.Common.Collections.Synchronized;
using Chaos.Common.Synchronization;
using Chaos.Extensions.Common;
+using Chaos.NLog.Logging.Definitions;
+using Chaos.NLog.Logging.Extensions;
using Chaos.Storage.Abstractions;
using Chaos.Storage.Abstractions.Definitions;
using Microsoft.Extensions.Caching.Memory;
@@ -86,7 +87,8 @@ ILogger> logger
///
public void ForceLoad()
{
- Logger.LogInformation("Force loading {@TypeName} cache", typeof(T).Name);
+ Logger.WithTopics(Topics.Qualifiers.Forced, Topics.Actions.Load)
+ .LogInformation("Force loading {@TypeName} cache", typeof(T).Name);
using var @lock = Sync.Enter();
@@ -143,11 +145,12 @@ public virtual Task ReloadAsync()
entry.Value = CreateFromEntry(entry);
} catch (Exception e)
{
- Logger.LogError(
- e,
- "Failed to reload {@TypeName} with key {@Key}",
- typeof(T).Name,
- key);
+ Logger.WithTopics(Topics.Qualifiers.Forced, Topics.Actions.Load)
+ .LogError(
+ e,
+ "Failed to reload {@TypeName} with key {@Key}",
+ typeof(T).Name,
+ key);
//otherwise ignored
}
@@ -175,8 +178,11 @@ protected virtual T CreateFromEntry(ICacheEntry entry)
var key = entry.Key.ToString();
var keyActual = DeconstructKeyForType(key!);
- Logger.LogDebug("Creating new {@TypeName} entry with key {@Key}", typeof(T).Name, key);
- var start = Stopwatch.GetTimestamp();
+ Logger.WithTopics(Topics.Actions.Create)
+ .LogDebug("Creating new {@TypeName} entry with key {@Key}", typeof(T).Name, key);
+
+ var metricsLogger = Logger.WithTopics(Topics.Actions.Load)
+ .WithMetrics();
entry.SetSlidingExpiration(TimeSpan.FromMinutes(Options.ExpirationMins));
entry.RegisterPostEvictionCallback(RemoveValueCallback);
@@ -187,11 +193,10 @@ protected virtual T CreateFromEntry(ICacheEntry entry)
LocalLookup[key!] = entity;
- Logger.LogDebug(
- "Created new {@TypeName} entry with key {@Key}, took {@Elapsed}",
+ metricsLogger.LogDebug(
+ "Created new {@TypeName} entry with key {@Key}",
typeof(T).Name,
- key,
- Stopwatch.GetElapsedTime(start));
+ key);
return entity;
}
diff --git a/Chaos.Time/Chaos.Time.csproj b/Chaos.Time/Chaos.Time.csproj
index 909fc1e7fd..4b708db147 100644
--- a/Chaos.Time/Chaos.Time.csproj
+++ b/Chaos.Time/Chaos.Time.csproj
@@ -1,6 +1,7 @@
+
diff --git a/Chaos.Time/DeltaMonitor.cs b/Chaos.Time/DeltaMonitor.cs
index 0ff00cd857..3a0a4f40b3 100644
--- a/Chaos.Time/DeltaMonitor.cs
+++ b/Chaos.Time/DeltaMonitor.cs
@@ -1,3 +1,5 @@
+using Chaos.NLog.Logging.Definitions;
+using Chaos.NLog.Logging.Extensions;
using Chaos.Time.Abstractions;
using Microsoft.Extensions.Logging;
@@ -96,32 +98,35 @@ private void CheckStatistics(List deltas) => _ = Task.Run(
//depending on how the loop is performing, log the output at different levels
if ((average > MaxDelta) || (max > 250))
- Logger.LogError(
- FORMAT,
- Name,
- average,
- median,
- upperPct,
- max,
- deltas.Count);
+ Logger.WithTopics(Topics.Entities.DeltaMonitor, Topics.Actions.Update)
+ .LogError(
+ FORMAT,
+ Name,
+ average,
+ median,
+ upperPct,
+ max,
+ deltas.Count);
else if ((upperPct > MaxDelta / 2) || (max > 100))
- Logger.LogWarning(
- FORMAT,
- Name,
- average,
- median,
- upperPct,
- max,
- deltas.Count);
+ Logger.WithTopics(Topics.Entities.DeltaMonitor, Topics.Actions.Update)
+ .LogWarning(
+ FORMAT,
+ Name,
+ average,
+ median,
+ upperPct,
+ max,
+ deltas.Count);
else
- Logger.LogTrace(
- FORMAT,
- Name,
- average,
- median,
- upperPct,
- max,
- deltas.Count);
+ Logger.WithTopics(Topics.Entities.DeltaMonitor, Topics.Actions.Update)
+ .LogTrace(
+ FORMAT,
+ Name,
+ average,
+ median,
+ upperPct,
+ max,
+ deltas.Count);
return Task.CompletedTask;
});
diff --git a/Chaos/Collections/TitleList.cs b/Chaos/Collections/TitleList.cs
index e85666a6df..8b1ecb8664 100644
--- a/Chaos/Collections/TitleList.cs
+++ b/Chaos/Collections/TitleList.cs
@@ -6,7 +6,7 @@ namespace Chaos.Collections;
public sealed class TitleList : SynchronizedList
{
public TitleList(IEnumerable? items = null)
- : base(items?.Distinct(StringComparer.OrdinalIgnoreCase) ?? Array.Empty()) { }
+ : base(items?.Distinct(StringComparer.OrdinalIgnoreCase) ?? Enumerable.Empty()) { }
///
public override void Add(string item)
diff --git a/Chaos/Models/World/Abstractions/Creature.cs b/Chaos/Models/World/Abstractions/Creature.cs
index 1c929e0ea0..07bb86cd02 100644
--- a/Chaos/Models/World/Abstractions/Creature.cs
+++ b/Chaos/Models/World/Abstractions/Creature.cs
@@ -406,7 +406,7 @@ public void TraverseMap(
.WithProperty(this)
.WithProperty(currentMap)
.WithProperty(destinationMap)
- .LogCritical(
+ .LogError(
e,
"Exception thrown while creature {@CreatureName} attempted to traverse from map {@FromMapInstanceId} to map {@ToMapInstanceId}",
Name,
diff --git a/Chaos/Models/World/Aisling.cs b/Chaos/Models/World/Aisling.cs
index d1a79421c0..2cc228438d 100644
--- a/Chaos/Models/World/Aisling.cs
+++ b/Chaos/Models/World/Aisling.cs
@@ -550,7 +550,7 @@ public override void ShowPublicMessage(PublicMessageType publicMessageType, stri
if (!Script.CanTalk())
return;
- Logger.WithTopics(Topics.Entities.Aisling, Topics.Actions.Message)
+ Logger.WithTopics(Topics.Entities.Aisling, Topics.Entities.Message, Topics.Actions.Send)
.WithProperty(this)
.LogInformation(
"Aisling {@AislingName} sent {@Type} message {@Message}",
diff --git a/Chaos/Scripting/DialogScripts/GuildScripts/GuildMemberAdmitScript.cs b/Chaos/Scripting/DialogScripts/GuildScripts/GuildMemberAdmitScript.cs
index b9730b7e50..4d5cd84858 100644
--- a/Chaos/Scripting/DialogScripts/GuildScripts/GuildMemberAdmitScript.cs
+++ b/Chaos/Scripting/DialogScripts/GuildScripts/GuildMemberAdmitScript.cs
@@ -95,7 +95,7 @@ private void OnDisplayingAccepted(Aisling source)
guild.AddMember(aislingToAdmit, source);
- Logger.WithTopics(Topics.Entities.Guild, Topics.Actions.Admit)
+ Logger.WithTopics(Topics.Entities.Guild, Topics.Actions.Join)
.WithProperty(Subject)
.WithProperty(Subject.DialogSource)
.WithProperty(source)
diff --git a/Chaos/Services/MapperProfiles/AislingMapperProfile.cs b/Chaos/Services/MapperProfiles/AislingMapperProfile.cs
index 2dc80b18a4..d10168b929 100644
--- a/Chaos/Services/MapperProfiles/AislingMapperProfile.cs
+++ b/Chaos/Services/MapperProfiles/AislingMapperProfile.cs
@@ -145,7 +145,6 @@ AislingSchema IMapperProfile.Map(Aisling obj)
Titles = obj.Titles.ToList(),
UserOptions = Mapper.Map(obj.Options),
IgnoreList = obj.IgnoreList.ToList(),
- Effects = Array.Empty(),
ChannelSettings = Mapper.MapMany(obj.ChannelSettings).ToList()
};
diff --git a/Chaos/Services/Servers/WorldServer.cs b/Chaos/Services/Servers/WorldServer.cs
index 2a0fe52c8b..c1eaec52cb 100644
--- a/Chaos/Services/Servers/WorldServer.cs
+++ b/Chaos/Services/Servers/WorldServer.cs
@@ -990,8 +990,10 @@ async ValueTask InnerOnPublicMessage(IWorldClient localClient, PublicMessageArgs
{
Logger.WithTopics(
Topics.Entities.Aisling,
- Topics.Actions.Message,
- Topics.Actions.Command)
+ Topics.Entities.Message,
+ Topics.Actions.Send,
+ Topics.Entities.Command,
+ Topics.Actions.Execute)
.WithProperty(localClient)
.LogDebug("Aisling {@AislingName} sent command {@Command}", localClient.Aisling, message);
@@ -1398,7 +1400,11 @@ ValueTask InnerOnWhisper(IWorldClient localClient, WhisperArgs localArgs)
//let them waste their time typing for no reason
if (targetAisling.IgnoreList.ContainsI(fromAisling.Name))
{
- Logger.WithTopics(Topics.Entities.Aisling, Topics.Actions.Message, Topics.Qualifiers.Harassment)
+ Logger.WithTopics(
+ Topics.Entities.Aisling,
+ Topics.Entities.Message,
+ Topics.Actions.Send,
+ Topics.Qualifiers.Harassment)
.WithProperty(fromAisling)
.WithProperty(targetAisling)
.LogWarning(
@@ -1410,7 +1416,7 @@ ValueTask InnerOnWhisper(IWorldClient localClient, WhisperArgs localArgs)
return default;
}
- Logger.WithTopics(Topics.Entities.Aisling, Topics.Actions.Message)
+ Logger.WithTopics(Topics.Entities.Aisling, Topics.Entities.Message, Topics.Actions.Send)
.WithProperty(fromAisling)
.WithProperty(targetAisling)
.LogInformation(
diff --git a/Chaos/Services/Storage/Abstractions/PeriodicSaveStoreBase.cs b/Chaos/Services/Storage/Abstractions/PeriodicSaveStoreBase.cs
index 6ddb099147..4eb601fb6e 100644
--- a/Chaos/Services/Storage/Abstractions/PeriodicSaveStoreBase.cs
+++ b/Chaos/Services/Storage/Abstractions/PeriodicSaveStoreBase.cs
@@ -110,7 +110,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
} catch (Exception e)
{
Logger.WithTopics(Topics.Actions.Save)
- .LogCritical(e, "Exception while performing save");
+ .LogError(e, "Exception while performing save");
}
Logger.WithTopics(Topics.Actions.Save)
diff --git a/Directory.Build.props b/Directory.Build.props
index 6c5d4070bc..a8be0a3d7c 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,6 +1,6 @@
- 11
+ latest
net7.0
true
true
diff --git a/Tools/SeqConfigurator/Builders/ChartBuilder.cs b/Tools/SeqConfigurator/Builders/ChartBuilder.cs
new file mode 100644
index 0000000000..cf0275e75f
--- /dev/null
+++ b/Tools/SeqConfigurator/Builders/ChartBuilder.cs
@@ -0,0 +1,81 @@
+using Seq.Api;
+using Seq.Api.Model.Dashboarding;
+using Seq.Api.Model.Signals;
+
+namespace SeqConfigurator.Builders;
+
+public class ChartBuilder
+{
+ private readonly TaskCompletionSource Promise;
+ private readonly SeqConnection SeqConnection;
+
+ private ChartBuilder(SeqConnection seqConnection)
+ {
+ SeqConnection = seqConnection;
+ Promise = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
+
+ Promise.SetResult(new ChartPart());
+ }
+
+ public Task BuildAsync() => Promise.Task;
+
+ public static ChartBuilder Create(SeqConnection seqConnection) => new(seqConnection);
+
+ public ChartBuilder WithDimensions(int columnCount = 6, int rowCount = 1)
+ {
+ Promise.Task.ContinueWith(
+ async creation => (await creation).DisplayStyle = new ChartDisplayStylePart
+ {
+ HeightRows = rowCount,
+ WidthColumns = columnCount
+ });
+
+ return this;
+ }
+
+ public ChartBuilder WithQuery(params Action[] builderActions)
+ {
+ var buildTasks = builderActions.Select(
+ action =>
+ {
+ var builder = ChartQueryBuilder.Create(SeqConnection);
+ action(builder);
+
+ return builder.BuildAsync();
+ });
+
+ var chartQueriesTask = Task.WhenAll(buildTasks);
+
+ Promise.Task.ContinueWith(
+ async creation =>
+ {
+ var chartPart = await creation;
+ var chartQueries = await chartQueriesTask;
+ chartPart.Queries.AddRange(chartQueries);
+ });
+
+ return this;
+ }
+
+ public ChartBuilder WithSignalExpression(string signalId) => WithSignalExpression(
+ builder =>
+ builder.WithKind(SignalExpressionKind.Signal)
+ .WithSignal(signalId));
+
+ public ChartBuilder WithSignalExpression(Action builderAction)
+ {
+ var signalExpressionBuilder = SignalExpressionBuilder.Create(SeqConnection);
+ builderAction(signalExpressionBuilder);
+
+ Promise.Task.ContinueWith(async creation => (await creation).SignalExpression = await signalExpressionBuilder.BuildAsync());
+
+ return this;
+ }
+
+ public ChartBuilder WithTitle(string title)
+ {
+ Promise.Task.ContinueWith(async creation => (await creation).Title = title);
+
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/Tools/SeqConfigurator/Builders/ChartQueryBuilder.cs b/Tools/SeqConfigurator/Builders/ChartQueryBuilder.cs
new file mode 100644
index 0000000000..9525e714c9
--- /dev/null
+++ b/Tools/SeqConfigurator/Builders/ChartQueryBuilder.cs
@@ -0,0 +1,107 @@
+using Seq.Api;
+using Seq.Api.Model.Dashboarding;
+using Seq.Api.Model.Shared;
+
+namespace SeqConfigurator.Builders;
+
+public class ChartQueryBuilder
+{
+ private readonly TaskCompletionSource Promise;
+ private readonly SeqConnection SeqConnection;
+
+ private ChartQueryBuilder(SeqConnection seqConnection)
+ {
+ SeqConnection = seqConnection;
+ Promise = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
+
+ Promise.SetResult(new ChartQueryPart());
+ }
+
+ public Task BuildAsync() => Promise.Task;
+
+ public static ChartQueryBuilder Create(SeqConnection seqConnection) => new(seqConnection);
+
+ public ChartQueryBuilder WithDisplayStyle(
+ MeasurementDisplayType type,
+ bool lineShowMarkers = true,
+ bool lineFillToZeroY = false,
+ bool barOverlaySum = false,
+ bool suppressLegend = false,
+ MeasurementDisplayPalette palette = MeasurementDisplayPalette.Default
+ )
+ {
+ Promise.Task.ContinueWith(
+ async creation =>
+ {
+ var chartQuery = await creation;
+
+ chartQuery.DisplayStyle = new MeasurementDisplayStylePart
+ {
+ Type = type,
+ LineShowMarkers = lineShowMarkers,
+ LineFillToZeroY = lineFillToZeroY,
+ BarOverlaySum = barOverlaySum,
+ SuppressLegend = suppressLegend,
+ Palette = palette
+ };
+ });
+
+ return this;
+ }
+
+ public ChartQueryBuilder WithGroupBy(params string[] groupByClauses)
+ {
+ Promise.Task.ContinueWith(async creation => (await creation).GroupBy.AddRange(groupByClauses));
+
+ return this;
+ }
+
+ public ChartQueryBuilder WithLimit(int limit)
+ {
+ Promise.Task.ContinueWith(async creation => (await creation).Limit = limit);
+
+ return this;
+ }
+
+ public ChartQueryBuilder WithOrderBy(params string[] orderByClauses)
+ {
+ Promise.Task.ContinueWith(async creation => (await creation).OrderBy.AddRange(orderByClauses));
+
+ return this;
+ }
+
+ public ChartQueryBuilder WithSelect(params (string Label, string SelectClause)[] columns)
+ {
+ Promise.Task.ContinueWith(
+ async creation =>
+ {
+ var measurements = columns.Select(
+ col => new ColumnPart
+ {
+ Label = col.Label,
+ Value = col.SelectClause
+ });
+
+ (await creation).Measurements.AddRange(measurements);
+ });
+
+ return this;
+ }
+
+ public ChartQueryBuilder WithSignalExpression(Action builder)
+ {
+ var signalExpressionBuilder = SignalExpressionBuilder.Create(SeqConnection);
+ builder(signalExpressionBuilder);
+
+ Promise.Task.ContinueWith(async creation => (await creation).SignalExpression = await signalExpressionBuilder.BuildAsync());
+
+ return this;
+ }
+
+ public ChartQueryBuilder WithWhere(string whereClause)
+ {
+ Promise.Task.ContinueWith(async creation => (await creation).Where = whereClause);
+
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/Tools/SeqConfigurator/Builders/DashboardBuilder.cs b/Tools/SeqConfigurator/Builders/DashboardBuilder.cs
new file mode 100644
index 0000000000..45a49384dd
--- /dev/null
+++ b/Tools/SeqConfigurator/Builders/DashboardBuilder.cs
@@ -0,0 +1,84 @@
+using Seq.Api;
+using Seq.Api.Model.Dashboarding;
+using Seq.Api.Model.Signals;
+
+namespace SeqConfigurator.Builders;
+
+public class DashboardBuilder
+{
+ private readonly TaskCompletionSource Promise;
+ private readonly SeqConnection SeqConnection;
+
+ private DashboardBuilder(SeqConnection seqConnection)
+ {
+ SeqConnection = seqConnection;
+ Promise = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
+
+ SeqConnection.Dashboards.TemplateAsync()
+ .ContinueWith(async task => Promise.SetResult(await task));
+ }
+
+ public static DashboardBuilder Create(SeqConnection seqConnection) => new(seqConnection);
+
+ public DashboardBuilder IsProtected()
+ {
+ Promise.Task.ContinueWith(async creation => (await creation).IsProtected = true);
+
+ return this;
+ }
+
+ public DashboardBuilder IsShared()
+ {
+ Promise.Task.ContinueWith(async creation => (await creation).OwnerId = null);
+
+ return this;
+ }
+
+ public async Task SaveAsync() => await SeqConnection.Dashboards.AddAsync(await Promise.Task);
+
+ public DashboardBuilder WithCharts(params Action[] builderActions)
+ {
+ var buildTasks = builderActions.Select(
+ builderAction =>
+ {
+ var chartBuilder = ChartBuilder.Create(SeqConnection);
+ builderAction(chartBuilder);
+
+ return chartBuilder.BuildAsync();
+ });
+
+ var chartTasks = Task.WhenAll(buildTasks);
+
+ Promise.Task.ContinueWith(
+ async creation =>
+ {
+ var dashboard = await creation;
+ var charts = await chartTasks;
+ dashboard.Charts.AddRange(charts);
+ });
+
+ return this;
+ }
+
+ public DashboardBuilder WithSignalExpression(string signalTitle) => WithSignalExpression(
+ builder => builder.WithKind(SignalExpressionKind.Signal)
+ .WithSignal(signalTitle));
+
+ public DashboardBuilder WithSignalExpression(Action builderAction)
+ {
+ var signalBuilder = SignalExpressionBuilder.Create(SeqConnection);
+ builderAction(signalBuilder);
+ var signalTask = signalBuilder.BuildAsync();
+
+ Promise.Task.ContinueWith(async creation => (await creation).SignalExpression = await signalTask);
+
+ return this;
+ }
+
+ public DashboardBuilder WithTitle(string title)
+ {
+ Promise.Task.ContinueWith(async creation => (await creation).Title = title);
+
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/Tools/SeqConfigurator/Builders/SignalBuilder.cs b/Tools/SeqConfigurator/Builders/SignalBuilder.cs
new file mode 100644
index 0000000000..00307608f5
--- /dev/null
+++ b/Tools/SeqConfigurator/Builders/SignalBuilder.cs
@@ -0,0 +1,72 @@
+using Seq.Api;
+using Seq.Api.Model.Shared;
+using Seq.Api.Model.Signals;
+
+namespace SeqConfigurator.Builders;
+
+public sealed class SignalBuilder
+{
+ private readonly TaskCompletionSource Promise;
+ private readonly SeqConnection SeqConnection;
+
+ private SignalBuilder(SeqConnection seqConnection)
+ {
+ SeqConnection = seqConnection;
+ Promise = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
+
+ SeqConnection.Signals.TemplateAsync()
+ .ContinueWith(async task => Promise.SetResult(await task));
+ }
+
+ public static SignalBuilder Create(SeqConnection seqConnection) => new(seqConnection);
+
+ public SignalBuilder IsShared()
+ {
+ Promise.Task.ContinueWith(async creation => (await creation).OwnerId = null);
+
+ return this;
+ }
+
+ public async Task SaveAsync() => await SeqConnection.Signals.AddAsync(await Promise.Task);
+
+ public SignalBuilder WithDescription(string description)
+ {
+ Promise.Task.ContinueWith(async creation => (await creation).Description = description);
+
+ return this;
+ }
+
+ public SignalBuilder WithFilter(string filter, string? filterNonStrict = null, string? filterDescription = null)
+ {
+ var filterDescriptor = new DescriptiveFilterPart
+ {
+ Filter = filter,
+ FilterNonStrict = filterNonStrict,
+ Description = filterDescription
+ };
+
+ Promise.Task.ContinueWith(async creation => (await creation).Filters.Add(filterDescriptor));
+
+ return this;
+ }
+
+ public SignalBuilder WithGrouping(SignalGrouping grouping, string? groupName = null)
+ {
+ Promise.Task.ContinueWith(
+ async creation =>
+ {
+ var signal = await creation;
+ signal.Grouping = grouping;
+ signal.ExplicitGroupName = groupName;
+ });
+
+ return this;
+ }
+
+ public SignalBuilder WithTitle(string title)
+ {
+ Promise.Task.ContinueWith(async creation => (await creation).Title = title);
+
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/Tools/SeqConfigurator/Builders/SignalExpressionBuilder.cs b/Tools/SeqConfigurator/Builders/SignalExpressionBuilder.cs
new file mode 100644
index 0000000000..924a98e4c9
--- /dev/null
+++ b/Tools/SeqConfigurator/Builders/SignalExpressionBuilder.cs
@@ -0,0 +1,102 @@
+using Chaos.Extensions.Common;
+using Seq.Api;
+using Seq.Api.Model.Signals;
+
+namespace SeqConfigurator.Builders;
+
+public class SignalExpressionBuilder
+{
+ private readonly TaskCompletionSource> AllSignals;
+ private readonly TaskCompletionSource Promise;
+ private readonly SeqConnection SeqConnection;
+
+ private SignalExpressionBuilder(SeqConnection seqConnection)
+ {
+ SeqConnection = seqConnection;
+ Promise = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
+ AllSignals = new TaskCompletionSource>();
+
+ Promise.TrySetResult(new SignalExpressionPart());
+
+ SeqConnection.Signals.ListAsync(shared: true)
+ .ContinueWith(async task => AllSignals.SetResult(await task));
+ }
+
+ public Task BuildAsync() => Promise.Task;
+
+ public static SignalExpressionBuilder Create(SeqConnection seqConnection) => new(seqConnection);
+
+ public SignalExpressionBuilder WithKind(SignalExpressionKind kind)
+ {
+ Promise.Task.ContinueWith(async creation => (await creation).Kind = kind);
+
+ return this;
+ }
+
+ public SignalExpressionBuilder WithLeft(SignalExpressionPart left)
+ {
+ Promise.Task.ContinueWith(async creation => (await creation).Left = left);
+
+ return this;
+ }
+
+ public SignalExpressionBuilder WithLeftSignal(string signalTitle)
+ {
+ Promise.Task.ContinueWith(
+ async creation =>
+ {
+ var allSignals = await AllSignals.Task;
+ var leftSignal = allSignals.First(s => s.Title.EqualsI(signalTitle));
+ var expression = await creation;
+
+ expression.Left = new SignalExpressionPart
+ {
+ Kind = SignalExpressionKind.Signal,
+ SignalId = leftSignal.Id
+ };
+ });
+
+ return this;
+ }
+
+ public SignalExpressionBuilder WithRight(SignalExpressionPart right)
+ {
+ Promise.Task.ContinueWith(async creation => (await creation).Right = right);
+
+ return this;
+ }
+
+ public SignalExpressionBuilder WithRightSignal(string signalTitle)
+ {
+ Promise.Task.ContinueWith(
+ async creation =>
+ {
+ var allSignals = await AllSignals.Task;
+ var rightSignal = allSignals.First(s => s.Title.EqualsI(signalTitle));
+ var expression = await creation;
+
+ expression.Right = new SignalExpressionPart
+ {
+ Kind = SignalExpressionKind.Signal,
+ SignalId = rightSignal.Id
+ };
+ });
+
+ return this;
+ }
+
+ public SignalExpressionBuilder WithSignal(string signalTitle)
+ {
+ Promise.Task.ContinueWith(
+ async creation =>
+ {
+ var allSignals = await AllSignals.Task;
+ var signal = allSignals.First(s => s.Title.EqualsI(signalTitle));
+ var expression = await creation;
+
+ expression.SignalId = signal.Id;
+ });
+
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/Tools/SeqConfigurator/Program.cs b/Tools/SeqConfigurator/Program.cs
index a8ed2d102a..2a89ca3f90 100644
--- a/Tools/SeqConfigurator/Program.cs
+++ b/Tools/SeqConfigurator/Program.cs
@@ -4,8 +4,8 @@
using NLog;
using Seq.Api;
using Seq.Api.Model.Dashboarding;
-using Seq.Api.Model.Shared;
using Seq.Api.Model.Signals;
+using SeqConfigurator.Builders;
using var seq = new SeqConnection("http://localhost:5341", "AdminGuestSeqToken");
await seq.EnsureConnectedAsync(TimeSpan.FromSeconds(30));
@@ -44,144 +44,59 @@
foreach (var logLevel in logLevels)
{
var level = logLevel.ToString()!.ToUpper();
- var template = await seq.Signals.TemplateAsync();
- template.Title = level;
- template.Description = level;
-
- template.Filters = new List
- {
- new()
- {
- Description = $"Filter by LogLevel = {level}",
- Filter = $"@Level = '{level}'",
- FilterNonStrict = $@"@Level = ""{level}"""
- }
- };
-
- template.Grouping = SignalGrouping.Explicit;
- template.ExplicitGroupName = "LogLevels";
-
- await seq.Signals.AddAsync(template);
+
+ await SignalBuilder.Create(seq)
+ .IsShared()
+ .WithTitle(level)
+ .WithDescription(level)
+ .WithFilter($"@Level = '{level}'", filterDescription: $"Filter by LogLevel = {level}")
+ .WithGrouping(SignalGrouping.Explicit, "LogLevels")
+ .SaveAsync();
}
Console.WriteLine("Creating Topics.Servers signals");
foreach (var topic in serverTopics)
-{
- var template = await seq.Signals.TemplateAsync();
- template.Title = topic.Name;
- template.Description = topic.Name;
-
- template.Filters = new List
- {
- new()
- {
- Description = $"Filter by Topics.Servers.{topic.Name}",
- Filter = $"'{topic.Name}' in Topics",
- FilterNonStrict = $@"""{topic.Name}"" in Topics"
- }
- };
-
- template.Grouping = SignalGrouping.Explicit;
- template.ExplicitGroupName = "Servers";
-
- await seq.Signals.AddAsync(template);
-}
+ await SignalBuilder.Create(seq)
+ .IsShared()
+ .WithTitle(topic.Name)
+ .WithDescription(topic.Name)
+ .WithFilter($"'{topic.Name}' in Topics", filterDescription: $"Filter by Topics.Servers.{topic.Name}")
+ .WithGrouping(SignalGrouping.Explicit, "Servers")
+ .SaveAsync();
Console.WriteLine("Creating Topics.Entities signals");
foreach (var topic in entityTopics)
-{
- var template = await seq.Signals.TemplateAsync();
- template.Title = topic.Name;
- template.Description = topic.Name;
-
- template.Filters = new List
- {
- new()
- {
- Description = $"Filter by Topics.Entities.{topic.Name}",
- Filter = $"'{topic.Name}' in Topics",
- FilterNonStrict = $@"""{topic.Name}"" in Topics"
- }
- };
-
- template.Grouping = SignalGrouping.Explicit;
- template.ExplicitGroupName = "Entities";
-
- await seq.Signals.AddAsync(template);
-}
+ await SignalBuilder.Create(seq)
+ .IsShared()
+ .WithTitle(topic.Name)
+ .WithDescription(topic.Name)
+ .WithFilter($"'{topic.Name}' in Topics", filterDescription: $"Filter by Topics.Entities.{topic.Name}")
+ .WithGrouping(SignalGrouping.Explicit, "Entities")
+ .SaveAsync();
Console.WriteLine("Creating Topics.Actions signals");
foreach (var topic in actionTopics)
-{
- var template = await seq.Signals.TemplateAsync();
- template.Title = topic.Name;
- template.Description = topic.Name;
-
- template.Filters = new List
- {
- new()
- {
- Description = $"Filter by Topics.Actions.{topic.Name}",
- Filter = $"'{topic.Name}' in Topics",
- FilterNonStrict = $@"""{topic.Name}"" in Topics"
- }
- };
-
- template.Grouping = SignalGrouping.Explicit;
- template.ExplicitGroupName = "Actions";
-
- await seq.Signals.AddAsync(template);
-}
+ await SignalBuilder.Create(seq)
+ .IsShared()
+ .WithTitle(topic.Name)
+ .WithDescription(topic.Name)
+ .WithFilter($"'{topic.Name}' in Topics", filterDescription: $"Filter by Topics.Actions.{topic.Name}")
+ .WithGrouping(SignalGrouping.Explicit, "Actions")
+ .SaveAsync();
Console.WriteLine("Creating Topics.Qualifiers signals");
foreach (var topic in qualifierTopics)
-{
- var template = await seq.Signals.TemplateAsync();
- template.Title = topic.Name;
- template.Description = topic.Name;
-
- template.Filters = new List
- {
- new()
- {
- Description = $"Filter by Topics.Qualifiers.{topic.Name}",
- Filter = $"'{topic.Name}' in Topics",
- FilterNonStrict = $@"""{topic.Name}"" in Topics"
- }
- };
-
- template.Grouping = SignalGrouping.Explicit;
- template.ExplicitGroupName = "Qualifiers";
-
- await seq.Signals.AddAsync(template);
-}
-
-Console.WriteLine("Creating Delta Monitor signal");
-
-{
- var template = await seq.Signals.TemplateAsync();
- template.Title = "Delta Monitor";
- template.Description = "Delta Monitor";
-
- template.Filters = new List
- {
- new()
- {
- Description = "Filter by Delta Monitor",
- Filter = "@MessageTemplate like 'Delta Monitor%'",
- FilterNonStrict = @"@MessageTemplate like ""Delta Monitor%"""
- }
- };
-
- template.Grouping = SignalGrouping.Explicit;
- template.ExplicitGroupName = "Delta Monitor";
-
- await seq.Signals.AddAsync(template);
-}
+ await SignalBuilder.Create(seq)
+ .IsShared()
+ .WithTitle(topic.Name)
+ .WithDescription(topic.Name)
+ .WithFilter($"'{topic.Name}' in Topics", filterDescription: $"Filter by Topics.Qualifiers.{topic.Name}")
+ .WithGrouping(SignalGrouping.Explicit, "Qualifiers")
+ .SaveAsync();
Console.WriteLine("Clearing existing dashboards");
@@ -193,219 +108,77 @@
Console.WriteLine("Creating Dashboard");
-var signals = await seq.Signals.ListAsync(shared: true);
-
-{
- var dashboard = await seq.Dashboards.TemplateAsync();
- dashboard.OwnerId = null;
- dashboard.Title = "Monitor";
- dashboard.IsProtected = false;
- dashboard.SignalExpression = null;
-
- dashboard.Charts = new List
- {
- new()
- {
- Title = "Map Count",
- SignalExpression = new SignalExpressionPart
- {
- Kind = SignalExpressionKind.Signal,
- SignalId = signals.First(signal => signal.Title == "Delta Monitor").Id
- },
- Queries = new List
- {
- new()
- {
- Measurements = new List
- {
- new()
- {
- Value = "count(distinct(Name))",
- Label = "MapCount"
- }
- },
- Where = null,
- SignalExpression = null,
- GroupBy = new List(),
- DisplayStyle = new MeasurementDisplayStylePart
- {
- Type = MeasurementDisplayType.Line,
- LineFillToZeroY = false,
- LineShowMarkers = true,
- BarOverlaySum = false,
- SuppressLegend = false,
- Palette = MeasurementDisplayPalette.Default
- }
- }
- }
- },
- new()
- {
- Title = "Aisling Count",
- SignalExpression = new SignalExpressionPart
- {
- Kind = SignalExpressionKind.Signal,
- SignalId = signals.First(signal => signal.Title == "Aisling").Id
- },
- Queries = new List
- {
- new()
- {
- Measurements = new List
- {
- new()
- {
- Value = "count(distinct(AislingName))",
- Label = "AislingCount"
- }
- },
- Where = "Has(AislingName)",
- GroupBy = new List(),
- DisplayStyle = new MeasurementDisplayStylePart
- {
- Type = MeasurementDisplayType.Line,
- LineFillToZeroY = false,
- LineShowMarkers = true,
- BarOverlaySum = false,
- SuppressLegend = false,
- Palette = MeasurementDisplayPalette.Default
- }
- }
- }
- },
- new()
- {
- Title = "Average Deltas",
- SignalExpression = new SignalExpressionPart
- {
- Kind = SignalExpressionKind.Signal,
- SignalId = signals.First(signal => signal.Title == "Delta Monitor").Id
- },
- Queries = new List
- {
- new()
- {
- Measurements = new List
- {
- new()
- {
- Value = "mean(Average)",
- Label = "Delta"
- }
- },
- GroupBy = new List { "Name" },
- DisplayStyle = new MeasurementDisplayStylePart
- {
- Type = MeasurementDisplayType.Line,
- LineFillToZeroY = false,
- LineShowMarkers = true,
- BarOverlaySum = false,
- SuppressLegend = false,
- Palette = MeasurementDisplayPalette.Default
- }
- }
- }
- },
- new()
- {
- Title = "Mean Deltas",
- SignalExpression = new SignalExpressionPart
- {
- Kind = SignalExpressionKind.Signal,
- SignalId = signals.First(signal => signal.Title == "Delta Monitor").Id
- },
- Queries = new List
- {
- new()
- {
- Measurements = new List
- {
- new()
- {
- Value = "mean(Median)",
- Label = "Delta"
- }
- },
- GroupBy = new List { "Name" },
- DisplayStyle = new MeasurementDisplayStylePart
- {
- Type = MeasurementDisplayType.Line,
- LineFillToZeroY = false,
- LineShowMarkers = true,
- BarOverlaySum = false,
- SuppressLegend = false,
- Palette = MeasurementDisplayPalette.Default
- }
- }
- }
- },
- new()
- {
- Title = "95th% Deltas",
- SignalExpression = new SignalExpressionPart
- {
- Kind = SignalExpressionKind.Signal,
- SignalId = signals.First(signal => signal.Title == "Delta Monitor").Id
- },
- Queries = new List
- {
- new()
- {
- Measurements = new List
- {
- new()
- {
- Value = "mean(UpperPercentile)",
- Label = "Delta"
- }
- },
- GroupBy = new List { "Name" },
- DisplayStyle = new MeasurementDisplayStylePart
- {
- Type = MeasurementDisplayType.Line,
- LineFillToZeroY = false,
- LineShowMarkers = true,
- BarOverlaySum = false,
- SuppressLegend = false,
- Palette = MeasurementDisplayPalette.Default
- }
- }
- }
- },
- new()
- {
- Title = "Max Deltas",
- SignalExpression = new SignalExpressionPart
- {
- Kind = SignalExpressionKind.Signal,
- SignalId = signals.First(signal => signal.Title == "Delta Monitor").Id
- },
- Queries = new List
- {
- new()
- {
- Measurements = new List
- {
- new()
- {
- Value = "mean(Max)",
- Label = "Delta"
- }
- },
- GroupBy = new List { "Name" },
- DisplayStyle = new MeasurementDisplayStylePart
- {
- Type = MeasurementDisplayType.Line,
- LineFillToZeroY = false,
- LineShowMarkers = true,
- BarOverlaySum = false,
- SuppressLegend = false,
- Palette = MeasurementDisplayPalette.Default
- }
- }
- }
- }
- };
-
- await seq.Dashboards.AddAsync(dashboard);
-}
\ No newline at end of file
+await DashboardBuilder.Create(seq)
+ .IsShared()
+ .WithTitle("Monitor")
+ .WithCharts(
+ BuildMapCountChart,
+ BuildAislingCountChart,
+ BuildAverageDeltasChart,
+ BuildMedianDeltasChart,
+ Build95ThPctDeltasChart,
+ BuildMaxDeltasChart)
+ .SaveAsync();
+
+Console.WriteLine("Done");
+
+return;
+
+static void BuildAverageDeltasChart(ChartBuilder chartBuilder) =>
+ chartBuilder.WithTitle("Average Deltas")
+ .WithSignalExpression("DeltaMonitor")
+ .WithDimensions(12, 2)
+ .WithQuery(
+ queryBuilder =>
+ queryBuilder.WithSelect(("Delta", "mean(Average)"))
+ .WithGroupBy("Name")
+ .WithDisplayStyle(MeasurementDisplayType.Line));
+
+static void BuildMedianDeltasChart(ChartBuilder chartBuilder) =>
+ chartBuilder.WithTitle("Median Deltas")
+ .WithSignalExpression("DeltaMonitor")
+ .WithDimensions(12, 2)
+ .WithQuery(
+ queryBuilder =>
+ queryBuilder.WithSelect(("Delta", "mean(Median)"))
+ .WithGroupBy("Name")
+ .WithDisplayStyle(MeasurementDisplayType.Line));
+
+static void Build95ThPctDeltasChart(ChartBuilder chartBuilder) =>
+ chartBuilder.WithTitle("95th% Deltas")
+ .WithSignalExpression("DeltaMonitor")
+ .WithDimensions(12, 2)
+ .WithQuery(
+ queryBuilder =>
+ queryBuilder.WithSelect(("Delta", "mean(UpperPercentile)"))
+ .WithGroupBy("Name")
+ .WithDisplayStyle(MeasurementDisplayType.Line));
+
+static void BuildMaxDeltasChart(ChartBuilder chartBuilder) =>
+ chartBuilder.WithTitle("Max Deltas")
+ .WithSignalExpression("DeltaMonitor")
+ .WithDimensions(12, 2)
+ .WithQuery(
+ queryBuilder =>
+ queryBuilder.WithSelect(("Delta", "mean(Max)"))
+ .WithGroupBy("Name")
+ .WithDisplayStyle(MeasurementDisplayType.Line));
+
+static void BuildAislingCountChart(ChartBuilder chartBuilder) =>
+ chartBuilder.WithTitle("AislingCount")
+ .WithSignalExpression("Aisling")
+ .WithDimensions(12, 2)
+ .WithQuery(
+ queryBuilder =>
+ queryBuilder.WithSelect(("MapCount", "count(distinct(Name))"))
+ .WithWhere("Has(AislingName)")
+ .WithDisplayStyle(MeasurementDisplayType.Line));
+
+static void BuildMapCountChart(ChartBuilder chartBuilder) =>
+ chartBuilder.WithTitle("MapCount")
+ .WithSignalExpression("DeltaMonitor")
+ .WithDimensions(12, 2)
+ .WithQuery(
+ queryBuilder =>
+ queryBuilder.WithSelect(("MapName", "count(distinct(Name))"))
+ .WithDisplayStyle(MeasurementDisplayType.Line));
\ No newline at end of file
diff --git a/Tools/SeqConfigurator/SeqConfigurator.csproj b/Tools/SeqConfigurator/SeqConfigurator.csproj
index ed10eb40ec..51508c4007 100644
--- a/Tools/SeqConfigurator/SeqConfigurator.csproj
+++ b/Tools/SeqConfigurator/SeqConfigurator.csproj
@@ -16,4 +16,5 @@
+