Skip to content

Commit 45577bb

Browse files
committed
Add first iteration of to file logging
1 parent 9b3996d commit 45577bb

File tree

4 files changed

+92
-0
lines changed

4 files changed

+92
-0
lines changed

AzzyBot-Next/Extensions/ServiceRegistering.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Text;
55
using System.Threading.Tasks;
66
using AzzyBot.Database;
7+
using AzzyBot.Logging;
78
using AzzyBot.Services;
89
using AzzyBot.Services.Modules;
910
using AzzyBot.Settings;
@@ -23,6 +24,7 @@ public static class ServiceRegistering
2324
public static void AzzyBotLogging(this ILoggingBuilder logging, bool isDev = false, bool forceDebug = false)
2425
{
2526
logging.AddConsole();
27+
logging.AddFile(Path.Combine("Logs", $"AzzyBot_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log"));
2628
logging.AddFilter("Microsoft.EntityFrameworkCore.Database", (isDev || forceDebug) ? LogLevel.Debug : LogLevel.Warning);
2729
logging.AddFilter("Microsoft.EntityFrameworkCore.Database.Command", (isDev || forceDebug) ? LogLevel.Debug : LogLevel.Warning);
2830
logging.AddFilter("Microsoft.EntityFrameworkCore.Infrastructure", (isDev || forceDebug) ? LogLevel.Debug : LogLevel.Warning);

AzzyBot-Next/Logging/FileLogger.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using System;
2+
using System.IO;
3+
using System.Threading;
4+
using Microsoft.Extensions.Logging;
5+
6+
namespace AzzyBot.Logging;
7+
8+
public sealed class FileLogger(string filePath) : ILogger, IDisposable
9+
{
10+
private readonly string _filePath = filePath;
11+
private readonly SemaphoreSlim _semaphore = new(1, 1);
12+
13+
#pragma warning disable CS8633 // Nullability in constraints for type parameter doesn't match the constraints for type parameter in implicitly implemented interface method'.
14+
public IDisposable? BeginScope<TState>(TState? state) => null;
15+
#pragma warning restore CS8633 // Nullability in constraints for type parameter doesn't match the constraints for type parameter in implicitly implemented interface method'.
16+
17+
public bool IsEnabled(LogLevel logLevel) => true;
18+
public void Dispose() => Dispose(true);
19+
20+
public void Dispose(bool disposing)
21+
{
22+
if (disposing)
23+
_semaphore.Dispose();
24+
}
25+
26+
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
27+
{
28+
ArgumentNullException.ThrowIfNull(formatter, nameof(formatter));
29+
30+
_semaphore.Wait();
31+
32+
string message = formatter(state, exception);
33+
string logMessage = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} [{logLevel}] {message}{Environment.NewLine}";
34+
35+
if (string.IsNullOrWhiteSpace(logMessage))
36+
{
37+
_semaphore.Release();
38+
return;
39+
}
40+
41+
try
42+
{
43+
File.AppendAllText(_filePath, logMessage);
44+
}
45+
finally
46+
{
47+
_semaphore.Release();
48+
}
49+
}
50+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System.Collections.Concurrent;
2+
using System.Collections.Generic;
3+
using Microsoft.Extensions.Logging;
4+
5+
namespace AzzyBot.Logging;
6+
7+
public sealed class FileLoggerProvider(string filePath) : ILoggerProvider
8+
{
9+
private readonly string _filePath = filePath;
10+
private readonly ConcurrentDictionary<string, FileLogger> _loggers = new();
11+
12+
public ILogger CreateLogger(string categoryName)
13+
{
14+
return _loggers.GetOrAdd(categoryName, name => new FileLogger(_filePath));
15+
}
16+
17+
public void Dispose()
18+
{
19+
foreach (KeyValuePair<string, FileLogger> logger in _loggers)
20+
{
21+
logger.Value.Dispose();
22+
}
23+
24+
_loggers.Clear();
25+
}
26+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Microsoft.Extensions.Logging;
2+
3+
namespace AzzyBot.Logging;
4+
5+
public static class LoggingBuilderExtensions
6+
{
7+
public static ILoggingBuilder AddFile(this ILoggingBuilder builder, string filePath)
8+
{
9+
using FileLoggerProvider fileLoggerProvider = new(filePath);
10+
builder.AddProvider(fileLoggerProvider);
11+
12+
return builder;
13+
}
14+
}

0 commit comments

Comments
 (0)