From 7b27574f7303451d6afa2c31af21af712d945bdb Mon Sep 17 00:00:00 2001 From: queil Date: Tue, 16 Jan 2024 13:03:32 +0000 Subject: [PATCH 1/2] add: basic logging types chore: rename Runnable to App --- .../packages.lock.json | 26 +++++++++++++++++++ .../Abstractions/Runnable.cs | 12 ++++++--- src/Queil.Ring.DotNet.Cli/Program.cs | 2 +- .../Runnables/CsProjRunnable.cs | 6 ++--- .../DockerCompose/DockerComposeRunnable.cs | 6 ++--- .../Runnables/Dotnet/AspNetCoreRunnable.cs | 6 ++--- .../Runnables/Dotnet/DotnetRunnable.cs | 6 ++--- .../Runnables/Kustomize/KustomizeRunnable.cs | 8 +++--- .../Runnables/Proc/ProcRunnable.cs | 6 ++--- .../Runnables/ProcessRunnable.cs | 6 ++--- .../Windows/IISExpress/IISExpressRunnable.cs | 6 ++--- .../Windows/IISExpress/IISXCoreRunnable.cs | 6 ++--- .../Windows/NetExe/NetExeRunnable.cs | 6 ++--- .../Tools/DockerCompose.cs | 3 +-- .../Tools/DotnetCliBundle.cs | 2 +- src/Queil.Ring.DotNet.Cli/Tools/GitClone.cs | 2 +- src/Queil.Ring.DotNet.Cli/Tools/Kubectl.cs | 2 +- .../Tools/KustomizeTool.cs | 3 +-- .../Tools/ProcessRunner.cs | 3 +-- src/Queil.Ring.DotNet.Cli/packages.lock.json | 25 ++++++++++++++++-- .../Events/RunnableLogLine.cs | 15 +++++++++++ src/Queil.Ring.Protocol/Message.cs | 2 ++ .../Queil.Ring.Protocol.csproj | 1 + src/Queil.Ring.Protocol/packages.lock.json | 26 +++++++++++++++++++ .../Ring.Tests.Integration/packages.lock.json | 21 +++++++++++++++ 25 files changed, 161 insertions(+), 46 deletions(-) create mode 100644 src/Queil.Ring.Protocol/Events/RunnableLogLine.cs diff --git a/src/Queil.Ring.Client.FSharp/packages.lock.json b/src/Queil.Ring.Client.FSharp/packages.lock.json index 32c4a49..ce81bf6 100644 --- a/src/Queil.Ring.Client.FSharp/packages.lock.json +++ b/src/Queil.Ring.Client.FSharp/packages.lock.json @@ -18,11 +18,36 @@ "resolved": "8.0.101", "contentHash": "sOLz3O4BOxnTKfd5OChdRmDUy4Id0GfoEClRG4nzIod8LY1LJZcNyygKAV0A78XOLh8yvhA5hsDYKZXGCR9blw==" }, + "MessagePack": { + "type": "Transitive", + "resolved": "2.5.140", + "contentHash": "nkIsgy8BkIfv40bSz9XZb4q//scI1PF3AYeB5X66nSlIhBIqbdpLz8Qk3gHvnjV3RZglQLO/ityK3eNfLii2NA==", + "dependencies": { + "MessagePack.Annotations": "2.5.140", + "Microsoft.NET.StringTools": "17.6.3", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "MessagePack.Annotations": { + "type": "Transitive", + "resolved": "2.5.140", + "contentHash": "JE3vwluOrsJ4t3hnfXzIxJUh6lhx6M/KR8Sark/HOUw1DJ5UKu5JsAnnuaQngg6poFkRx1lzHSLTkxHNJO7+uQ==" + }, "Microsoft.Bcl.AsyncInterfaces": { "type": "Transitive", "resolved": "5.0.0", "contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==" }, + "Microsoft.NET.StringTools": { + "type": "Transitive", + "resolved": "17.6.3", + "contentHash": "N0ZIanl1QCgvUumEL1laasU0a7sOE5ZwLZVTn0pAePnfhq8P7SvTjF8Axq+CnavuQkmdQpGNXQ1efZtu5kDFbA==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, "System.Text.Encodings.Web": { "type": "Transitive", "resolved": "8.0.0", @@ -44,6 +69,7 @@ "queil.ring.protocol": { "type": "Project", "dependencies": { + "MessagePack": "[2.*, )", "System.Text.Json": "[8.*, )", "System.Threading.Channels": "[8.*, )" } diff --git a/src/Queil.Ring.DotNet.Cli/Abstractions/Runnable.cs b/src/Queil.Ring.DotNet.Cli/Abstractions/Runnable.cs index 2430af8..42fd647 100644 --- a/src/Queil.Ring.DotNet.Cli/Abstractions/Runnable.cs +++ b/src/Queil.Ring.DotNet.Cli/Abstractions/Runnable.cs @@ -13,21 +13,22 @@ namespace Queil.Ring.DotNet.Cli.Abstractions; using Logging; using Microsoft.Extensions.Logging; using Protocol; +using Protocol.Events; using Stateless; [DebuggerDisplay("{UniqueId}")] -public abstract class Runnable : IRunnable +public abstract class App : IRunnable where TConfig : IRunnableConfig { private readonly Dictionary _details = new(); private readonly Fsm _fsm = new(); - private readonly ILogger> _logger; + private readonly ILogger> _logger; protected readonly ISender Sender; private TContext? _context; private Task _destroyTask = Task.CompletedTask; private Task _stopTask = Task.CompletedTask; - protected Runnable(TConfig config, ILogger> logger, ISender sender) + protected App(TConfig config, ILogger> logger, ISender sender) { Config = config; if (Config.FriendlyName != null) _details.Add(DetailsKeys.FriendlyName, Config.FriendlyName); @@ -343,6 +344,11 @@ private async Task DestroyCoreAsync(TContext ctx, CancellationToken token) } } + protected virtual void PublishLogs(string line) + { + Sender.Enqueue(Message.RunnableLogs(new RunnableLogLine { RunnableId = UniqueId, Line = line })); + } + private class Fsm() : StateMachine(State.Zero); } diff --git a/src/Queil.Ring.DotNet.Cli/Program.cs b/src/Queil.Ring.DotNet.Cli/Program.cs index 0b8f1e3..e25e9f0 100644 --- a/src/Queil.Ring.DotNet.Cli/Program.cs +++ b/src/Queil.Ring.DotNet.Cli/Program.cs @@ -112,7 +112,7 @@ static string Ring(string ver) => .Where(t => typeof(IRunnable).IsAssignableFrom(t)).ToList(); var configMap = (from r in runnableTypes - let cfg = r.GetProperty(nameof(Runnable.Config)) + let cfg = r.GetProperty(nameof(App.Config)) where cfg != null select (RunnableType: r, ConfigType: cfg.PropertyType)) .ToDictionary(x => x.ConfigType, x => x.RunnableType); diff --git a/src/Queil.Ring.DotNet.Cli/Runnables/CsProjRunnable.cs b/src/Queil.Ring.DotNet.Cli/Runnables/CsProjRunnable.cs index 2af9620..673505d 100644 --- a/src/Queil.Ring.DotNet.Cli/Runnables/CsProjRunnable.cs +++ b/src/Queil.Ring.DotNet.Cli/Runnables/CsProjRunnable.cs @@ -8,11 +8,11 @@ namespace Queil.Ring.DotNet.Cli.Runnables; using Infrastructure; using Microsoft.Extensions.Logging; -public abstract class CsProjRunnable( +public abstract class CsProjApp( TConfig config, - ILogger> logger, + ILogger> logger, ISender sender) - : ProcessRunnable(config, logger, sender) + : ProcessApp(config, logger, sender) where TContext : ITrackProcessId, ICsProjContext, ITrackRetries where TConfig : IRunnableConfig, IUseCsProjFile { diff --git a/src/Queil.Ring.DotNet.Cli/Runnables/DockerCompose/DockerComposeRunnable.cs b/src/Queil.Ring.DotNet.Cli/Runnables/DockerCompose/DockerComposeRunnable.cs index 22e1a13..e220a8f 100644 --- a/src/Queil.Ring.DotNet.Cli/Runnables/DockerCompose/DockerComposeRunnable.cs +++ b/src/Queil.Ring.DotNet.Cli/Runnables/DockerCompose/DockerComposeRunnable.cs @@ -9,12 +9,12 @@ namespace Queil.Ring.DotNet.Cli.Runnables.DockerCompose; using Tools; using DockerComposeConfig = Configuration.Runnables.DockerCompose; -public class DockerComposeRunnable( +public class DockerComposeApp( DockerComposeConfig config, - ILogger> logger, + ILogger> logger, ISender sender, DockerCompose dockerCompose) - : Runnable(config, logger, sender) + : App(config, logger, sender) { public override string UniqueId => Config.Path; diff --git a/src/Queil.Ring.DotNet.Cli/Runnables/Dotnet/AspNetCoreRunnable.cs b/src/Queil.Ring.DotNet.Cli/Runnables/Dotnet/AspNetCoreRunnable.cs index 9b6b840..8038062 100644 --- a/src/Queil.Ring.DotNet.Cli/Runnables/Dotnet/AspNetCoreRunnable.cs +++ b/src/Queil.Ring.DotNet.Cli/Runnables/Dotnet/AspNetCoreRunnable.cs @@ -9,13 +9,13 @@ namespace Queil.Ring.DotNet.Cli.Runnables.Dotnet; using Tools; using static Dtos.DetailsKeys; -public class AspNetCoreRunnable( +public class AspNetCoreApp( AspNetCore config, DotnetCliBundle dotnet, - ILogger logger, + ILogger logger, ISender sender, GitClone gitClone) - : DotnetRunnableBase(config, dotnet, logger, sender, gitClone) + : DotnetAppBase(config, dotnet, logger, sender, gitClone) { protected override async Task InitAsync(CancellationToken token) { diff --git a/src/Queil.Ring.DotNet.Cli/Runnables/Dotnet/DotnetRunnable.cs b/src/Queil.Ring.DotNet.Cli/Runnables/Dotnet/DotnetRunnable.cs index c84e99c..d751f33 100644 --- a/src/Queil.Ring.DotNet.Cli/Runnables/Dotnet/DotnetRunnable.cs +++ b/src/Queil.Ring.DotNet.Cli/Runnables/Dotnet/DotnetRunnable.cs @@ -10,13 +10,13 @@ namespace Queil.Ring.DotNet.Cli.Runnables.Dotnet; using Microsoft.Extensions.Logging; using Tools; -public abstract class DotnetRunnableBase( +public abstract class DotnetAppBase( TConfig config, DotnetCliBundle dotnet, - ILogger> logger, + ILogger> logger, ISender sender, GitClone gitClone) - : ProcessRunnable(config, logger, sender) + : ProcessApp(config, logger, sender) where TContext : DotnetContext where TConfig : IUseCsProjFile, IRunnableConfig { diff --git a/src/Queil.Ring.DotNet.Cli/Runnables/Kustomize/KustomizeRunnable.cs b/src/Queil.Ring.DotNet.Cli/Runnables/Kustomize/KustomizeRunnable.cs index 9958826..761a776 100644 --- a/src/Queil.Ring.DotNet.Cli/Runnables/Kustomize/KustomizeRunnable.cs +++ b/src/Queil.Ring.DotNet.Cli/Runnables/Kustomize/KustomizeRunnable.cs @@ -16,20 +16,20 @@ namespace Queil.Ring.DotNet.Cli.Runnables.Kustomize; using Microsoft.Extensions.Options; using Tools; -public class KustomizeRunnable( +public class KustomizeApp( KustomizeConfig config, IOptions ringCfg, - ILogger> logger, + ILogger> logger, ISender sender, KubectlBundle bundle) - : Runnable(config, logger, sender) + : App(config, logger, sender) { private const string NamespacesPath = "{range .items[?(@.kind=='Namespace')]}{.metadata.name}{'\\n'}{end}"; private readonly string _cacheDir = ringCfg?.Value?.Kustomize.CachePath ?? throw new ArgumentNullException(nameof(RingConfiguration.Kustomize.CachePath)); - private readonly ILogger> _logger = logger; + private readonly ILogger> _logger = logger; public override string UniqueId => Config.Path; protected override TimeSpan HealthCheckPeriod => TimeSpan.FromSeconds(10); diff --git a/src/Queil.Ring.DotNet.Cli/Runnables/Proc/ProcRunnable.cs b/src/Queil.Ring.DotNet.Cli/Runnables/Proc/ProcRunnable.cs index 633e274..ce9470d 100644 --- a/src/Queil.Ring.DotNet.Cli/Runnables/Proc/ProcRunnable.cs +++ b/src/Queil.Ring.DotNet.Cli/Runnables/Proc/ProcRunnable.cs @@ -13,12 +13,12 @@ public class ProcContext : ITrackProcessId public int ProcessId { get; set; } } -public class ProcRunnable : ProcessRunnable +public class ProcApp : ProcessApp { private readonly ProcessRunner _runner; - public ProcRunnable(Proc config, - ILogger> logger, + public ProcApp(Proc config, + ILogger> logger, ISender sender, ProcessRunner runner) : base(config, logger, sender) { diff --git a/src/Queil.Ring.DotNet.Cli/Runnables/ProcessRunnable.cs b/src/Queil.Ring.DotNet.Cli/Runnables/ProcessRunnable.cs index b8a4510..80fbfc0 100644 --- a/src/Queil.Ring.DotNet.Cli/Runnables/ProcessRunnable.cs +++ b/src/Queil.Ring.DotNet.Cli/Runnables/ProcessRunnable.cs @@ -9,11 +9,11 @@ using Microsoft.Extensions.Logging; using Tools; -public abstract class ProcessRunnable( +public abstract class ProcessApp( TConfig config, - ILogger> logger, + ILogger> logger, ISender sender) - : Runnable(config, logger, sender) + : App(config, logger, sender) where TContext : ITrackProcessId where TConfig : IRunnableConfig { diff --git a/src/Queil.Ring.DotNet.Cli/Runnables/Windows/IISExpress/IISExpressRunnable.cs b/src/Queil.Ring.DotNet.Cli/Runnables/Windows/IISExpress/IISExpressRunnable.cs index 893b479..2951383 100644 --- a/src/Queil.Ring.DotNet.Cli/Runnables/Windows/IISExpress/IISExpressRunnable.cs +++ b/src/Queil.Ring.DotNet.Cli/Runnables/Windows/IISExpress/IISExpressRunnable.cs @@ -16,13 +16,13 @@ using Tools.Windows; using IISExpressConfig = Configuration.Runnables.IISExpress; -public class IISExpressRunnable( +public class IisExpressApp( IISExpressConfig config, IISExpressExe iisExpress, - ILogger logger, + ILogger logger, ISender sender, Func clientFactory) - : CsProjRunnable(config, logger, sender) + : CsProjApp(config, logger, sender) { private readonly List _wcfServices = []; diff --git a/src/Queil.Ring.DotNet.Cli/Runnables/Windows/IISExpress/IISXCoreRunnable.cs b/src/Queil.Ring.DotNet.Cli/Runnables/Windows/IISExpress/IISXCoreRunnable.cs index 82dd2ee..df79eac 100644 --- a/src/Queil.Ring.DotNet.Cli/Runnables/Windows/IISExpress/IISXCoreRunnable.cs +++ b/src/Queil.Ring.DotNet.Cli/Runnables/Windows/IISExpress/IISXCoreRunnable.cs @@ -10,13 +10,13 @@ using Tools.Windows; using IISXCoreConfig = Configuration.Runnables.IISXCore; -public class IISXCoreRunnable( +public class IisxCoreApp( IISXCoreConfig config, IISExpressExe iisExpress, - ILogger logger, + ILogger logger, ISender sender, GitClone gitClone) - : CsProjRunnable(config, logger, sender) + : CsProjApp(config, logger, sender) { protected override IISXCoreContext CreateContext() { diff --git a/src/Queil.Ring.DotNet.Cli/Runnables/Windows/NetExe/NetExeRunnable.cs b/src/Queil.Ring.DotNet.Cli/Runnables/Windows/NetExe/NetExeRunnable.cs index 85d8056..0f03dbe 100644 --- a/src/Queil.Ring.DotNet.Cli/Runnables/Windows/NetExe/NetExeRunnable.cs +++ b/src/Queil.Ring.DotNet.Cli/Runnables/Windows/NetExe/NetExeRunnable.cs @@ -10,12 +10,12 @@ namespace Queil.Ring.DotNet.Cli.Runnables.Windows.NetExe; using Microsoft.Extensions.Logging; using Tools; -public class NetExeRunnable( +public class NetExeApp( NetExeConfig config, ProcessRunner processRunner, - ILogger logger, + ILogger logger, ISender sender) - : CsProjRunnable(config, logger, sender) + : CsProjApp(config, logger, sender) { protected override NetExeContext CreateContext() { diff --git a/src/Queil.Ring.DotNet.Cli/Tools/DockerCompose.cs b/src/Queil.Ring.DotNet.Cli/Tools/DockerCompose.cs index 8863bb3..c1b6fb2 100644 --- a/src/Queil.Ring.DotNet.Cli/Tools/DockerCompose.cs +++ b/src/Queil.Ring.DotNet.Cli/Tools/DockerCompose.cs @@ -1,6 +1,5 @@ namespace Queil.Ring.DotNet.Cli.Tools; -using System; using System.Threading; using System.Threading.Tasks; using Abstractions.Tools; @@ -9,7 +8,7 @@ namespace Queil.Ring.DotNet.Cli.Tools; public class DockerCompose(ILogger logger) : ITool { public string Command { get; set; } = "docker-compose"; - public string[] DefaultArgs { get; set; } = Array.Empty(); + public string[] DefaultArgs { get; set; } = []; public ILogger Logger { get; } = logger; public async Task RmAsync(string composeFilePath, CancellationToken token) => diff --git a/src/Queil.Ring.DotNet.Cli/Tools/DotnetCliBundle.cs b/src/Queil.Ring.DotNet.Cli/Tools/DotnetCliBundle.cs index 0db86e7..39112fc 100644 --- a/src/Queil.Ring.DotNet.Cli/Tools/DotnetCliBundle.cs +++ b/src/Queil.Ring.DotNet.Cli/Tools/DotnetCliBundle.cs @@ -16,7 +16,7 @@ public class DotnetCliBundle(ProcessRunner processRunner, ILogger DefaultEnvVars = new() { ["ASPNETCORE_ENVIRONMENT"] = "Development" }; public ILogger Logger { get; } = logger; public string Command { get; set; } = "dotnet"; - public string[] DefaultArgs { get; set; } = Array.Empty(); + public string[] DefaultArgs { get; set; } = []; public async Task RunAsync(DotnetContext ctx, CancellationToken token, string[]? urls = null) { diff --git a/src/Queil.Ring.DotNet.Cli/Tools/GitClone.cs b/src/Queil.Ring.DotNet.Cli/Tools/GitClone.cs index c8b8b70..778234a 100644 --- a/src/Queil.Ring.DotNet.Cli/Tools/GitClone.cs +++ b/src/Queil.Ring.DotNet.Cli/Tools/GitClone.cs @@ -20,7 +20,7 @@ public partial class GitClone(ILogger logger, IOptions(); + public string[] DefaultArgs { get; set; } = []; public ILogger Logger { get; } = logger; public string ResolveFullClonePath(IFromGit gitCfg, string? rootPathOverride = null) diff --git a/src/Queil.Ring.DotNet.Cli/Tools/Kubectl.cs b/src/Queil.Ring.DotNet.Cli/Tools/Kubectl.cs index e886784..18cace5 100644 --- a/src/Queil.Ring.DotNet.Cli/Tools/Kubectl.cs +++ b/src/Queil.Ring.DotNet.Cli/Tools/Kubectl.cs @@ -20,7 +20,7 @@ public class KubectlBundle( private readonly string[] _allowedContexts = config.Value.Kubernetes.AllowedContexts ?? Array.Empty(); public string Command { get; set; } = "kubectl"; - public string[] DefaultArgs { get; set; } = Array.Empty(); + public string[] DefaultArgs { get; set; } = []; public ILogger Logger { get; } = logger; public async Task EnsureContextIsAllowed(CancellationToken token) diff --git a/src/Queil.Ring.DotNet.Cli/Tools/KustomizeTool.cs b/src/Queil.Ring.DotNet.Cli/Tools/KustomizeTool.cs index fa2add1..a7d108d 100644 --- a/src/Queil.Ring.DotNet.Cli/Tools/KustomizeTool.cs +++ b/src/Queil.Ring.DotNet.Cli/Tools/KustomizeTool.cs @@ -1,6 +1,5 @@ namespace Queil.Ring.DotNet.Cli.Tools; -using System; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -10,7 +9,7 @@ namespace Queil.Ring.DotNet.Cli.Tools; public class KustomizeTool(ILogger logger) : ITool { public string Command { get; set; } = "kustomize"; - public string[] DefaultArgs { get; set; } = Array.Empty(); + public string[] DefaultArgs { get; set; } = []; public ILogger Logger { get; } = logger; public async Task BuildAsync(string kustomizeDir, string outputFilePath, CancellationToken token) diff --git a/src/Queil.Ring.DotNet.Cli/Tools/ProcessRunner.cs b/src/Queil.Ring.DotNet.Cli/Tools/ProcessRunner.cs index 3111d2b..102d4e2 100644 --- a/src/Queil.Ring.DotNet.Cli/Tools/ProcessRunner.cs +++ b/src/Queil.Ring.DotNet.Cli/Tools/ProcessRunner.cs @@ -1,12 +1,11 @@ namespace Queil.Ring.DotNet.Cli.Tools; -using System; using Abstractions.Tools; using Microsoft.Extensions.Logging; public class ProcessRunner(ILogger logger) : ITool { public string Command { get; set; } - public string[] DefaultArgs { get; set; } = Array.Empty(); + public string[] DefaultArgs { get; set; } = []; public ILogger Logger { get; } = logger; } diff --git a/src/Queil.Ring.DotNet.Cli/packages.lock.json b/src/Queil.Ring.DotNet.Cli/packages.lock.json index a4a6177..1f86d21 100644 --- a/src/Queil.Ring.DotNet.Cli/packages.lock.json +++ b/src/Queil.Ring.DotNet.Cli/packages.lock.json @@ -143,6 +143,21 @@ "Microsoft.Extensions.DependencyInjection.Abstractions": "3.1.9" } }, + "MessagePack": { + "type": "Transitive", + "resolved": "2.5.140", + "contentHash": "nkIsgy8BkIfv40bSz9XZb4q//scI1PF3AYeB5X66nSlIhBIqbdpLz8Qk3gHvnjV3RZglQLO/ityK3eNfLii2NA==", + "dependencies": { + "MessagePack.Annotations": "2.5.140", + "Microsoft.NET.StringTools": "17.6.3", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "MessagePack.Annotations": { + "type": "Transitive", + "resolved": "2.5.140", + "contentHash": "JE3vwluOrsJ4t3hnfXzIxJUh6lhx6M/KR8Sark/HOUw1DJ5UKu5JsAnnuaQngg6poFkRx1lzHSLTkxHNJO7+uQ==" + }, "Microsoft.AspNetCore.Connections.Abstractions": { "type": "Transitive", "resolved": "2.2.0", @@ -464,6 +479,11 @@ "System.Buffers": "4.5.0" } }, + "Microsoft.NET.StringTools": { + "type": "Transitive", + "resolved": "17.6.3", + "contentHash": "N0ZIanl1QCgvUumEL1laasU0a7sOE5ZwLZVTn0pAePnfhq8P7SvTjF8Axq+CnavuQkmdQpGNXQ1efZtu5kDFbA==" + }, "prometheus-net": { "type": "Transitive", "resolved": "8.2.1", @@ -587,8 +607,8 @@ }, "System.Runtime.CompilerServices.Unsafe": { "type": "Transitive", - "resolved": "4.5.1", - "contentHash": "Zh8t8oqolRaFa9vmOZfdQm/qKejdqz0J9kr7o2Fu0vPeoH3BL1EOXipKWwkWtLT1JPzjByrF19fGuFlNbmPpiw==" + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" }, "System.Security.Cryptography.Cng": { "type": "Transitive", @@ -637,6 +657,7 @@ "queil.ring.protocol": { "type": "Project", "dependencies": { + "MessagePack": "[2.*, )", "System.Text.Json": "[8.*, )", "System.Threading.Channels": "[8.*, )" } diff --git a/src/Queil.Ring.Protocol/Events/RunnableLogLine.cs b/src/Queil.Ring.Protocol/Events/RunnableLogLine.cs new file mode 100644 index 0000000..15a0ab6 --- /dev/null +++ b/src/Queil.Ring.Protocol/Events/RunnableLogLine.cs @@ -0,0 +1,15 @@ +namespace Queil.Ring.Protocol.Events; + +using System; +using MessagePack; + +[MessagePackObject] +public class RunnableLogLine +{ + [property: Key(0)]public string RunnableId { get; set; } = null!; + [property: Key(1)]public string Line { get; set; } = null!; + + public ReadOnlySpan Serialize() => MessagePackSerializer.Serialize(this); + public static RunnableLogLine Deserialize(ReadOnlySpan bytes) => + MessagePackSerializer.Deserialize(bytes.ToArray().AsMemory()); +} diff --git a/src/Queil.Ring.Protocol/Message.cs b/src/Queil.Ring.Protocol/Message.cs index 649eeae..764e296 100644 --- a/src/Queil.Ring.Protocol/Message.cs +++ b/src/Queil.Ring.Protocol/Message.cs @@ -35,6 +35,7 @@ public enum M : byte WORKSPACE_STOPPED = 21, WORKSPACE_INFO_PUBLISH = 26, WORKSPACE_APPLY_FLAVOUR = 27, + RUNNABLE_LOGS = 28, SERVER_IDLE = 22, SERVER_LOADED = 23, SERVER_RUNNING = 24, @@ -112,6 +113,7 @@ public override string ToString() public static Message RunnableRecovering(ReadOnlySpan id) => new(M.RUNNABLE_RECOVERING, id); public static Message RunnableStopped(ReadOnlySpan id) => new(M.RUNNABLE_STOPPED, id); public static Message RunnableDestroyed(ReadOnlySpan id) => new(M.RUNNABLE_DESTROYED, id); + public static Message RunnableLogs(RunnableLogLine line) => new(M.RUNNABLE_LOGS, line.Serialize()); public static Message ServerIdle() => new(M.SERVER_IDLE); public static Message ServerLoaded(ReadOnlySpan workspacePath) => new(M.SERVER_LOADED, workspacePath); public static Message ServerRunning(ReadOnlySpan workspacePath) => new(M.SERVER_RUNNING, workspacePath); diff --git a/src/Queil.Ring.Protocol/Queil.Ring.Protocol.csproj b/src/Queil.Ring.Protocol/Queil.Ring.Protocol.csproj index a91c73b..29880da 100644 --- a/src/Queil.Ring.Protocol/Queil.Ring.Protocol.csproj +++ b/src/Queil.Ring.Protocol/Queil.Ring.Protocol.csproj @@ -14,6 +14,7 @@ + diff --git a/src/Queil.Ring.Protocol/packages.lock.json b/src/Queil.Ring.Protocol/packages.lock.json index 062b77a..11bd4ef 100644 --- a/src/Queil.Ring.Protocol/packages.lock.json +++ b/src/Queil.Ring.Protocol/packages.lock.json @@ -8,6 +8,17 @@ "resolved": "0.4.0-beta.1", "contentHash": "3cTaYc/hcDJumpCTjYNu+X0IEyTFRKHsIlsHwDjju1rGpH7/9dcostXJlRtmIIno6PgRWIh5ZalHDq76QYUA2w==" }, + "MessagePack": { + "type": "Direct", + "requested": "[2.*, )", + "resolved": "2.5.140", + "contentHash": "nkIsgy8BkIfv40bSz9XZb4q//scI1PF3AYeB5X66nSlIhBIqbdpLz8Qk3gHvnjV3RZglQLO/ityK3eNfLii2NA==", + "dependencies": { + "MessagePack.Annotations": "2.5.140", + "Microsoft.NET.StringTools": "17.6.3", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, "System.Text.Json": { "type": "Direct", "requested": "[8.*, )", @@ -23,6 +34,21 @@ "resolved": "8.0.0", "contentHash": "CMaFr7v+57RW7uZfZkPExsPB6ljwzhjACWW1gfU35Y56rk72B/Wu+sTqxVmGSk4SFUlPc3cjeKND0zktziyjBA==" }, + "MessagePack.Annotations": { + "type": "Transitive", + "resolved": "2.5.140", + "contentHash": "JE3vwluOrsJ4t3hnfXzIxJUh6lhx6M/KR8Sark/HOUw1DJ5UKu5JsAnnuaQngg6poFkRx1lzHSLTkxHNJO7+uQ==" + }, + "Microsoft.NET.StringTools": { + "type": "Transitive", + "resolved": "17.6.3", + "contentHash": "N0ZIanl1QCgvUumEL1laasU0a7sOE5ZwLZVTn0pAePnfhq8P7SvTjF8Axq+CnavuQkmdQpGNXQ1efZtu5kDFbA==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, "System.Text.Encodings.Web": { "type": "Transitive", "resolved": "8.0.0", diff --git a/tests/Ring.Tests.Integration/packages.lock.json b/tests/Ring.Tests.Integration/packages.lock.json index 70c5e00..69ce61c 100644 --- a/tests/Ring.Tests.Integration/packages.lock.json +++ b/tests/Ring.Tests.Integration/packages.lock.json @@ -123,6 +123,21 @@ "Microsoft.Bcl.AsyncInterfaces": "5.0.0" } }, + "MessagePack": { + "type": "Transitive", + "resolved": "2.5.140", + "contentHash": "nkIsgy8BkIfv40bSz9XZb4q//scI1PF3AYeB5X66nSlIhBIqbdpLz8Qk3gHvnjV3RZglQLO/ityK3eNfLii2NA==", + "dependencies": { + "MessagePack.Annotations": "2.5.140", + "Microsoft.NET.StringTools": "17.6.3", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "MessagePack.Annotations": { + "type": "Transitive", + "resolved": "2.5.140", + "contentHash": "JE3vwluOrsJ4t3hnfXzIxJUh6lhx6M/KR8Sark/HOUw1DJ5UKu5JsAnnuaQngg6poFkRx1lzHSLTkxHNJO7+uQ==" + }, "Microsoft.Bcl.AsyncInterfaces": { "type": "Transitive", "resolved": "5.0.0", @@ -133,6 +148,11 @@ "resolved": "17.8.0", "contentHash": "KC8SXWbGIdoFVdlxKk9WHccm0llm9HypcHMLUUFabRiTS3SO2fQXNZfdiF3qkEdTJhbRrxhdRxjL4jbtwPq4Ew==" }, + "Microsoft.NET.StringTools": { + "type": "Transitive", + "resolved": "17.6.3", + "contentHash": "N0ZIanl1QCgvUumEL1laasU0a7sOE5ZwLZVTn0pAePnfhq8P7SvTjF8Axq+CnavuQkmdQpGNXQ1efZtu5kDFbA==" + }, "Microsoft.TestPlatform.ObjectModel": { "type": "Transitive", "resolved": "17.8.0", @@ -224,6 +244,7 @@ "queil.ring.protocol": { "type": "Project", "dependencies": { + "MessagePack": "[2.*, )", "System.Text.Json": "[8.*, )", "System.Threading.Channels": "[8.*, )" } From 8924b6f345428e2f260bb79fdc38837752422795 Mon Sep 17 00:00:00 2001 From: queil Date: Tue, 16 Jan 2024 13:37:13 +0000 Subject: [PATCH 2/2] add: broadcast logs --- .../Logging/BroadcastSink.cs | 24 +++++++++++++++++++ src/Queil.Ring.DotNet.Cli/Logging/Scope.cs | 2 +- .../Logging/ScopeLoggingExtensions.cs | 10 ++++++-- src/Queil.Ring.DotNet.Cli/Program.cs | 15 ++++++------ .../Events/RunnableLogLine.cs | 4 ++-- 5 files changed, 43 insertions(+), 12 deletions(-) create mode 100644 src/Queil.Ring.DotNet.Cli/Logging/BroadcastSink.cs diff --git a/src/Queil.Ring.DotNet.Cli/Logging/BroadcastSink.cs b/src/Queil.Ring.DotNet.Cli/Logging/BroadcastSink.cs new file mode 100644 index 0000000..625e372 --- /dev/null +++ b/src/Queil.Ring.DotNet.Cli/Logging/BroadcastSink.cs @@ -0,0 +1,24 @@ +namespace Queil.Ring.DotNet.Cli.Logging; + +using Infrastructure; +using Protocol; +using Protocol.Events; +using Serilog.Core; +using Serilog.Events; + +public class BroadcastSink(ISender sender) : ILogEventSink +{ + public void Emit(Serilog.Events.LogEvent logEvent) + { + if (logEvent.Level < LogEventLevel.Information || !logEvent.Properties.TryGetValue(Scope.Broadcast, out _)) return; + var message = logEvent.RenderMessage(); + sender.Enqueue( + Message.RunnableLogs(new RunnableLogLine + { + Line = message, + RunnableId = logEvent.Properties.TryGetValue(Scope.UniqueIdKey, out var uniqueId) + ? uniqueId.ToString() + : null + })); + } +} diff --git a/src/Queil.Ring.DotNet.Cli/Logging/Scope.cs b/src/Queil.Ring.DotNet.Cli/Logging/Scope.cs index abb4362..083d6c5 100644 --- a/src/Queil.Ring.DotNet.Cli/Logging/Scope.cs +++ b/src/Queil.Ring.DotNet.Cli/Logging/Scope.cs @@ -6,6 +6,6 @@ public class Scope : Dictionary { public const string LogEventKey = "LogEvent"; public const string UniqueIdKey = "UniqueId"; - + public const string Broadcast = "Broadcast"; public static Scope Event(LogEvent logEvent) => new() { { LogEventKey, logEvent } }; } diff --git a/src/Queil.Ring.DotNet.Cli/Logging/ScopeLoggingExtensions.cs b/src/Queil.Ring.DotNet.Cli/Logging/ScopeLoggingExtensions.cs index d814599..9dd6607 100644 --- a/src/Queil.Ring.DotNet.Cli/Logging/ScopeLoggingExtensions.cs +++ b/src/Queil.Ring.DotNet.Cli/Logging/ScopeLoggingExtensions.cs @@ -49,9 +49,15 @@ public static void LogContextDebug(this ILogger logger, object context) public static IDisposable? WithLogErrorScope(this ILogger logger) => logger.BeginScope(new Scope - { [Scope.LogEventKey] = $"{Red}ERROR" }); + { + [Scope.LogEventKey] = $"{Red}ERROR", + [Scope.Broadcast] = true + }); public static IDisposable? WithLogInfoScope(this ILogger logger) => logger.BeginScope(new Scope - { [Scope.LogEventKey] = $"{Gray}LOG" }); + { + [Scope.LogEventKey] = $"{Gray}LOG", + [Scope.Broadcast] = true + }); } diff --git a/src/Queil.Ring.DotNet.Cli/Program.cs b/src/Queil.Ring.DotNet.Cli/Program.cs index e25e9f0..e79e834 100644 --- a/src/Queil.Ring.DotNet.Cli/Program.cs +++ b/src/Queil.Ring.DotNet.Cli/Program.cs @@ -73,6 +73,7 @@ static string Ring(string ver) => services.AddOptions(); services.Configure(builder.Configuration); services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true)); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); @@ -104,7 +105,12 @@ static string Ring(string ver) => services.AddTransient(); services.AddTransient(); - builder.Host.UseSerilog(); + builder.Host.UseSerilog((c, f, l) => + { + l.ReadFrom.Configuration(c.Configuration) + .WriteTo.Sink(f.GetRequiredService()); + if (options.IsDebug) l.MinimumLevel.Debug(); + }); builder.Host.ConfigureContainer((ctx, container) => { @@ -150,12 +156,7 @@ static string Ring(string ver) => var app = builder.Build(); app.Urls.Add($"http://0.0.0.0:{app.Configuration.GetValue("ring:port")}"); - - var loggingConfig = new LoggerConfiguration().ReadFrom.Configuration(builder.Configuration); - - if (options.IsDebug) loggingConfig.MinimumLevel.Debug(); - - Log.Logger = loggingConfig.CreateLogger(); + var logger = app.Services.GetRequiredService>(); using (logger.WithHostScope(LogEvent.INIT)) diff --git a/src/Queil.Ring.Protocol/Events/RunnableLogLine.cs b/src/Queil.Ring.Protocol/Events/RunnableLogLine.cs index 15a0ab6..537e18a 100644 --- a/src/Queil.Ring.Protocol/Events/RunnableLogLine.cs +++ b/src/Queil.Ring.Protocol/Events/RunnableLogLine.cs @@ -6,8 +6,8 @@ namespace Queil.Ring.Protocol.Events; [MessagePackObject] public class RunnableLogLine { - [property: Key(0)]public string RunnableId { get; set; } = null!; - [property: Key(1)]public string Line { get; set; } = null!; + [property: Key(0)]public string? RunnableId { get; init; } = null!; + [property: Key(1)]public string Line { get; init; } = null!; public ReadOnlySpan Serialize() => MessagePackSerializer.Serialize(this); public static RunnableLogLine Deserialize(ReadOnlySpan bytes) =>