Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
</ItemGroup>

<ItemGroup>
<None Include="..\..\LICENSE" Pack="true" PackagePath="" />
<None Include="..\..\LICENSE" Pack="true" PackagePath="" Visible="false" />
<None Include="README.md" Pack="true" PackagePath="" />
<None Include="../../assets/icon.png" Pack="true" PackagePath="" />
<None Include="../../assets/icon.png" Pack="true" PackagePath="" Visible="false" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0" />
</ItemGroup>

<ItemGroup>
<None Include="..\..\LICENSE" Pack="true" PackagePath="" />
<None Include="..\..\LICENSE" Pack="true" PackagePath="" Visible="false" />
<None Include="README.md" Pack="true" PackagePath="" />
<None Include="../../assets/icon.png" Pack="true" PackagePath="" />
<None Include="../../assets/icon.png" Pack="true" PackagePath="" Visible="false" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,16 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CodeOfChaos.Ansi" Version="0.1.7" />
<PackageReference Include="JetBrains.Annotations" Version="2024.3.0" />
<PackageReference Include="Serilog" Version="4.2.0" />
<PackageReference Include="Serilog.Sinks.Async" Version="2.1.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
</ItemGroup>

<ItemGroup>
<None Include="..\..\LICENSE" Pack="true" PackagePath="" />
<None Include="..\..\LICENSE" Pack="true" PackagePath="" Visible="false" />
<None Include="README.md" Pack="true" PackagePath="" />
<None Include="../../assets/icon.png" Pack="true" PackagePath="" />
<None Include="../../assets/icon.png" Pack="true" PackagePath="" Visible="false" />
</ItemGroup>
</Project>
13 changes: 13 additions & 0 deletions src/CodeOfChaos.Extensions.Serilog/ConsoleFormats.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// ---------------------------------------------------------------------------------------------------------------------
// Imports
// ---------------------------------------------------------------------------------------------------------------------
namespace CodeOfChaos.Extensions.Serilog;

// ---------------------------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------------------------
public static class ConsoleOutputTemplates {
public const string Default = "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}";
public const string DefaultShort = "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}";
public const string AnnaSasDevServer = "[{Timestamp:HH:mm:ss} {Level:u3} {Section,-8}] {Message:lj}{NewLine}";
}
32 changes: 32 additions & 0 deletions src/CodeOfChaos.Extensions.Serilog/ConsoleThemes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// ---------------------------------------------------------------------------------------------------------------------
// Imports
// ---------------------------------------------------------------------------------------------------------------------
using Serilog.Sinks.SystemConsole.Themes;
using CodeOfChaos.Ansi;

namespace CodeOfChaos.Extensions.Serilog;

// ---------------------------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------------------------
public static class ConsoleThemes {
public static readonly AnsiConsoleTheme AnnaSasDevTheme = new(
new Dictionary<ConsoleThemeStyle, string> {
[ConsoleThemeStyle.Text] = AnsiColor.AsFore("white"),
[ConsoleThemeStyle.SecondaryText] = AnsiColor.AsFore("silver"),
[ConsoleThemeStyle.TertiaryText] = AnsiColor.AsFore("gray"),
[ConsoleThemeStyle.Invalid] = AnsiColor.AsFore("gold"),
[ConsoleThemeStyle.Null] = AnsiColor.AsFore("coral"),
[ConsoleThemeStyle.Name] = AnsiColor.AsFore("slategray"),
[ConsoleThemeStyle.String] = AnsiColor.AsFore("aqua"),
[ConsoleThemeStyle.Number] = AnsiColor.AsFore("mediumpurple"),
[ConsoleThemeStyle.Boolean] = AnsiColor.AsFore("coral"),
[ConsoleThemeStyle.Scalar] = AnsiColor.AsFore("coral"),
[ConsoleThemeStyle.LevelVerbose] = AnsiColor.AsFore("silver"),
[ConsoleThemeStyle.LevelDebug] = AnsiColor.AsFore("rose"),
[ConsoleThemeStyle.LevelInformation] = AnsiColor.AsFore("white"),
[ConsoleThemeStyle.LevelWarning] = AnsiColor.AsFore("gold"),
[ConsoleThemeStyle.LevelError] = AnsiColor.AsFore("white") + AnsiColor.AsBack("rose"),
[ConsoleThemeStyle.LevelFatal] = AnsiColor.AsFore("white") + AnsiColor.AsBack("maroon")
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// ---------------------------------------------------------------------------------------------------------------------
// Imports
// ---------------------------------------------------------------------------------------------------------------------
using Serilog.Core;
using Serilog.Events;

namespace CodeOfChaos.Extensions.Serilog.Enrichers;
// ---------------------------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------------------------
public class PaddedSectionEnricher : ILogEventEnricher {
public int MaxLength { get; } = 8;

// -----------------------------------------------------------------------------------------------------------------
// Constructors
// -----------------------------------------------------------------------------------------------------------------
public PaddedSectionEnricher() { }
public PaddedSectionEnricher(int maxLength) => MaxLength = maxLength;

// -----------------------------------------------------------------------------------------------------------------
// Methods
// -----------------------------------------------------------------------------------------------------------------
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) {
if (!logEvent.Properties.TryGetValue("Section", out LogEventPropertyValue? sectionProperty)) {
// If "Section" is not defined, fallback to default value
sectionProperty = new ScalarValue(string.Empty);
}

string sectionValue = sectionProperty.ToString().Trim('"'); // Remove quotes and trim

// Left-pad as required to a max of 8 characters
string paddedSection = sectionValue.PadLeft(MaxLength)[..MaxLength];

LogEventProperty paddedProperty = propertyFactory.CreateProperty("Section", paddedSection);
logEvent.AddOrUpdateProperty(paddedProperty);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// ---------------------------------------------------------------------------------------------------------------------
// Imports
// ---------------------------------------------------------------------------------------------------------------------
using Serilog.Core;
using Serilog.Events;

namespace CodeOfChaos.Extensions.Serilog.Enrichers;
// ---------------------------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------------------------
public class TruncateSourceContextEnricher : ILogEventEnricher {
public int MaxLength { get; } = 8;

// -----------------------------------------------------------------------------------------------------------------
// Constructors
// -----------------------------------------------------------------------------------------------------------------
public TruncateSourceContextEnricher() { }
public TruncateSourceContextEnricher(int maxLength) => MaxLength = maxLength;

// -----------------------------------------------------------------------------------------------------------------
// Methods
// -----------------------------------------------------------------------------------------------------------------
public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) {
if (!logEvent.Properties.TryGetValue("SourceContext", out LogEventPropertyValue? sourceContextValue)
|| sourceContextValue is not ScalarValue { Value: string sourceContext }) return;

string truncatedSourceContext = sourceContext.Length > MaxLength + 3
? string.Concat("...", sourceContext.AsSpan(sourceContext.Length - MaxLength, MaxLength))
: sourceContext;

var truncatedProperty = new LogEventProperty("SourceContext", new ScalarValue(truncatedSourceContext));
logEvent.AddOrUpdateProperty(truncatedProperty);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// ---------------------------------------------------------------------------------------------------------------------
// Imports
// ---------------------------------------------------------------------------------------------------------------------
using CodeOfChaos.Extensions.Serilog.Enrichers;
using Serilog;
using Serilog.Core;
using Serilog.Events;
using Serilog.Sinks.SystemConsole.Themes;

namespace CodeOfChaos.Extensions.Serilog;

// ---------------------------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------------------------
public static class LoggerConfigurationExtensions {
public static LoggerConfiguration WriteToAsyncConsole(
this LoggerConfiguration loggerConfiguration,
LogEventLevel restrictedToMinimumLevel = LogEventLevel.Verbose,
string outputTemplate = "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}",
IFormatProvider? formatProvider = null,
LoggingLevelSwitch? levelSwitch = null,
LogEventLevel? standardErrorFromLevel = null,
ConsoleTheme? theme = null,
bool applyThemeToRedirectedOutput = false,
object? syncRoot = null
) {
loggerConfiguration.WriteTo.Async(lsc => lsc.Console(
restrictedToMinimumLevel,
outputTemplate,
formatProvider,
levelSwitch,
standardErrorFromLevel,
theme,
applyThemeToRedirectedOutput,
syncRoot
));
return loggerConfiguration;
}

public static LoggerConfiguration WithPaddedSectionEnricher(this LoggerConfiguration loggerConfiguration, int maxLength = 8)
=> loggerConfiguration.Enrich.With(new PaddedSectionEnricher(maxLength));

public static LoggerConfiguration WithTruncateSourceContextEnricher(this LoggerConfiguration loggerConfiguration, int maxLength = 8)
=> loggerConfiguration.Enrich.With(new TruncateSourceContextEnricher(maxLength));

// -----------------------------------------------------------------------------------------------------------------
// Opinionated configurations
// -----------------------------------------------------------------------------------------------------------------
public static LoggerConfiguration AsAnnaSasDevServerConsole(this LoggerConfiguration loggerConfiguration) {
return loggerConfiguration
.WithPaddedSectionEnricher()
.WriteToAsyncConsole(
outputTemplate: ConsoleOutputTemplates.AnnaSasDevServer,
theme: ConsoleThemes.AnnaSasDevTheme
);
}
}
3 changes: 3 additions & 0 deletions src/CodeOfChaos.Extensions.Serilog/LoggerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,7 @@ public static void ExitFatal(this ILogger logger, int exitCode, string messageTe
logger.Fatal(messageTemplate, propertyValues);
throw new ExitApplicationException(exitCode, messageTemplate);
}


public static ILogger ForSectionProperty(this ILogger logger, string sectionName) => logger.ForContext("Section", sectionName);
}
4 changes: 2 additions & 2 deletions src/CodeOfChaos.Extensions/CodeOfChaos.Extensions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
</PropertyGroup>

<ItemGroup>
<None Include="..\..\LICENSE" Pack="true" PackagePath="" />
<None Include="..\..\LICENSE" Pack="true" PackagePath="" Visible="false" />
<None Include="README.md" Pack="true" PackagePath="" />
<None Include="../../assets/icon.png" Pack="true" PackagePath="" />
<None Include="../../assets/icon.png" Pack="true" PackagePath="" Visible="false" />
</ItemGroup>

</Project>
71 changes: 71 additions & 0 deletions src/CodeOfChaos.Extensions/ReaderWriterLockSlimExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// ---------------------------------------------------------------------------------------------------------------------
// Imports
// ---------------------------------------------------------------------------------------------------------------------
// ReSharper disable once CheckNamespace
namespace System.Threading;
// ---------------------------------------------------------------------------------------------------------------------
// Code
// ---------------------------------------------------------------------------------------------------------------------
public static class ReaderWriterLockSlimExtensions {

// -----------------------------------------------------------------------------------------------------------------
// Methods
// -----------------------------------------------------------------------------------------------------------------
public static IDisposable Read(this ReaderWriterLockSlim rwLock) {
rwLock.EnterReadLock();
return new ReadReleaser(rwLock);
}

public static IDisposable Write(this ReaderWriterLockSlim rwLock) {
rwLock.EnterWriteLock();
return new WriteReleaser(rwLock);
}

public static UpgradableReadReleaser UpgradeableRead(this ReaderWriterLockSlim rwLock) {
rwLock.EnterUpgradeableReadLock();
return new UpgradableReadReleaser(rwLock);
}

public static IDisposable? TryRead(this ReaderWriterLockSlim rwLock, int millisecondsTimeout, Action? onTimeout = null) {
if (rwLock.TryEnterReadLock(millisecondsTimeout)) {
return new ReadReleaser(rwLock);
}

onTimeout?.Invoke();// Handle timeout scenario
return null;
}

public static IDisposable? TryWrite(this ReaderWriterLockSlim rwLock, int millisecondsTimeout, Action? onTimeout = null) {
if (rwLock.TryEnterWriteLock(millisecondsTimeout)) {
return new WriteReleaser(rwLock);
}

onTimeout?.Invoke();// Handle timeout scenario
return null;
}

public static IDisposable? TryUpgradeableRead(this ReaderWriterLockSlim rwLock, int millisecondsTimeout, Action? onTimeout = null) {
if (rwLock.TryEnterUpgradeableReadLock(millisecondsTimeout)) {
return new UpgradableReadReleaser(rwLock);
}

onTimeout?.Invoke();// Handle timeout scenario
return null;
}

// -----------------------------------------------------------------------------------------------------------------
// Helper Class
// -----------------------------------------------------------------------------------------------------------------
private readonly struct ReadReleaser(ReaderWriterLockSlim rwLock) : IDisposable {
public void Dispose() => rwLock.ExitReadLock();
}

private readonly struct WriteReleaser(ReaderWriterLockSlim rwLock) : IDisposable {
public void Dispose() => rwLock.ExitWriteLock();
}

public readonly struct UpgradableReadReleaser(ReaderWriterLockSlim rwLock) : IDisposable {
public ReaderWriterLockSlim Lock { get; } = rwLock;
public void Dispose() => Lock.ExitUpgradeableReadLock();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2024.3.0"/>
<PackageReference Include="Moq" Version="4.20.72"/>
<PackageReference Include="TUnit" Version="0.5.28" />
<PackageReference Include="TUnit" Version="0.6.0" />
<PackageReference Include="Bogus" Version="35.6.1"/>
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2024.3.0"/>
<PackageReference Include="Moq" Version="4.20.72"/>
<PackageReference Include="TUnit" Version="0.5.28" />
<PackageReference Include="TUnit" Version="0.6.0" />
<PackageReference Include="Bogus" Version="35.6.1"/>
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2024.3.0"/>
<PackageReference Include="Moq" Version="4.20.72"/>
<PackageReference Include="TUnit" Version="0.5.28" />
<PackageReference Include="TUnit" Version="0.6.0" />
<PackageReference Include="Bogus" Version="35.6.1"/>
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="2024.3.0"/>
<PackageReference Include="Moq" Version="4.20.72"/>
<PackageReference Include="TUnit" Version="0.5.28" />
<PackageReference Include="TUnit" Version="0.6.0" />
<PackageReference Include="Bogus" Version="35.6.1"/>
</ItemGroup>

Expand Down