Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move to Microsoft.Extensions.Logging #899

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
d3d3c9e
Migrate to Microsoft.Extensions.Logging
jkulubya Nov 24, 2024
e130f42
Mark old logger obsolete
jkulubya Nov 27, 2024
581d651
Make transitional classes obsolete
jkulubya Nov 27, 2024
ed7f591
Add message type to log scope
jkulubya Nov 27, 2024
57d7ae3
Forward to single constructor
jkulubya Dec 10, 2024
d6b4535
Delete nulllogger and nullloggerprovider
jkulubya Dec 10, 2024
3235611
Relax MEL version requirements to allow v6 to 8
jkulubya Dec 10, 2024
f66e557
Undo public API change in Send(string message)
jkulubya Dec 10, 2024
67e7fee
Merge transitional classes into existing log implementations
jkulubya Dec 11, 2024
b3ad725
Remove stray log
jkulubya Dec 12, 2024
231b790
Use NullLoggerProvider.Instance instead of constructing one
jkulubya Dec 12, 2024
e21307a
Use delegate overload for GetOrAdd
jkulubya Dec 12, 2024
2ed24b5
Ignore nullability error while implementing ILogger.BeginScope
jkulubya Dec 12, 2024
9ad26d3
Ignore nullability error while implementing ILogger.BeginScope
jkulubya Dec 12, 2024
40f336e
Make sure owned logging classes are disposed.
jkulubya Dec 12, 2024
841fcee
Naming
jkulubya Dec 12, 2024
ab4737e
Set min version of MEL.Abstractions to v6 and no upper limit
jkulubya Dec 13, 2024
4590b62
Use LoggerFactory constructor that disposes ILoggerProviders
jkulubya Dec 15, 2024
252bb00
Merge branch 'master' into ilogger
jkulubya Jan 5, 2025
283a3b8
Set ILogger.BeginScope type to match net6 and not later. Clears nulla…
jkulubya Jan 5, 2025
05c650b
Make NonSessionFileLogger obsolete
jkulubya Jan 5, 2025
d145d73
Refactor to set proper categories
jkulubya Jan 9, 2025
0f52aa0
Make log levels make sense
jkulubya Jan 9, 2025
cc7cc9e
Add serilog example project
jkulubya Jan 9, 2025
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
4 changes: 3 additions & 1 deletion AcceptanceTest/ATApplication.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using QuickFix;

namespace AcceptanceTest
Expand Down Expand Up @@ -169,7 +170,8 @@ public void FromApp(Message message, SessionID sessionId)
}
catch (System.Exception e)
{
Session.LookupSession(sessionId)?.Log.OnEvent($"Exception during FromApp: {e}\n while processing msg ({message})");
Session.LookupSession(sessionId)?.Log.Log(LogLevel.Error, e,
"Exception during FromApp: {Error}\n while processing msg ({Message})", e, message);
}
}

Expand Down
1 change: 1 addition & 0 deletions AcceptanceTest/AcceptanceTest.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
</ItemGroup>

<ItemGroup>
Expand Down
17 changes: 12 additions & 5 deletions AcceptanceTest/TestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using QuickFix;
using System.IO;
using System.Net;
using Microsoft.Extensions.Logging;
using QuickFix.Logger;
using QuickFix.Store;

Expand All @@ -23,11 +24,17 @@ public void Setup()
var testApp = new ATApplication();
var storeFactory = new MemoryStoreFactory();

ILogFactory? logFactory = settings.Get().Has("Verbose") && settings.Get().GetBool("Verbose")
? new FileLogFactory(settings)
: new NullLogFactory();

_acceptor = new ThreadedSocketAcceptor(testApp, storeFactory, settings, logFactory);
var loggerFactory = new LoggerFactory();
if (settings.Get().Has("Verbose") && settings.Get().GetBool("Verbose"))
{
loggerFactory.AddProvider(new FileLoggerProvider(settings));
}
else
{
loggerFactory.AddProvider(new NullLoggerProvider());
}

_acceptor = new ThreadedSocketAcceptor(testApp, storeFactory, settings, loggerFactory);

_acceptor.Start();
}
Expand Down
4 changes: 4 additions & 0 deletions Examples/Executor/Examples.Executor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,8 @@
</None>
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
</ItemGroup>

</Project>
12 changes: 9 additions & 3 deletions Examples/Executor/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Microsoft.Extensions.Logging;
using QuickFix;
using QuickFix.Logger;
using QuickFix.Store;
Expand Down Expand Up @@ -27,9 +28,14 @@ static void Main(string[] args)
SessionSettings settings = new SessionSettings(args[0]);
IApplication executorApp = new Executor();
IMessageStoreFactory storeFactory = new FileStoreFactory(settings);
ILogFactory logFactory = new ScreenLogFactory(settings);
//ILogFactory logFactory = new FileLogFactory(settings);
ThreadedSocketAcceptor acceptor = new ThreadedSocketAcceptor(executorApp, storeFactory, settings, logFactory);
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.SetMinimumLevel(LogLevel.Trace);
builder.AddProvider(new ScreenLoggerProvider(settings));
builder.AddProvider(new FileLoggerProvider(settings));
});
ThreadedSocketAcceptor acceptor =
new ThreadedSocketAcceptor(executorApp, storeFactory, settings, loggerFactory);
HttpServer srv = new HttpServer(HttpServerPrefix, settings);

acceptor.Start();
Expand Down
4 changes: 4 additions & 0 deletions Examples/SimpleAcceptor/Examples.SimpleAcceptor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,8 @@
</None>
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
</ItemGroup>

</Project>
8 changes: 6 additions & 2 deletions Examples/SimpleAcceptor/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Microsoft.Extensions.Logging;
using QuickFix;
using QuickFix.Logger;
using QuickFix.Store;
Expand Down Expand Up @@ -30,8 +31,11 @@ static void Main(string[] args)
SessionSettings settings = new SessionSettings(args[0]);
IApplication app = new SimpleAcceptorApp();
IMessageStoreFactory storeFactory = new FileStoreFactory(settings);
ILogFactory logFactory = new FileLogFactory(settings);
IAcceptor acceptor = new ThreadedSocketAcceptor(app, storeFactory, settings, logFactory);
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddProvider(new FileLoggerProvider(settings));
});
IAcceptor acceptor = new ThreadedSocketAcceptor(app, storeFactory, settings, loggerFactory);

acceptor.Start();
Console.WriteLine("press <enter> to quit");
Expand Down
4 changes: 4 additions & 0 deletions Examples/TradeClient/Examples.TradeClient.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,8 @@
</None>
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
</ItemGroup>

</Project>
10 changes: 7 additions & 3 deletions Examples/TradeClient/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Microsoft.Extensions.Logging;
using QuickFix.Logger;
using QuickFix.Store;

Expand Down Expand Up @@ -31,9 +32,12 @@ static void Main(string[] args)
QuickFix.SessionSettings settings = new QuickFix.SessionSettings(file);
TradeClientApp application = new TradeClientApp();
IMessageStoreFactory storeFactory = new FileStoreFactory(settings);
ILogFactory logFactory = new ScreenLogFactory(settings);
//ILogFactory logFactory = new FileLogFactory(settings);
QuickFix.Transport.SocketInitiator initiator = new QuickFix.Transport.SocketInitiator(application, storeFactory, settings, logFactory);
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddProvider(new ScreenLoggerProvider(settings));
// builder.AddProvider(new FileLogProvider(settings));
});
QuickFix.Transport.SocketInitiator initiator = new QuickFix.Transport.SocketInitiator(application, storeFactory, settings, loggerFactory);

// this is a developer-test kludge. do not emulate.
application.MyInitiator = initiator;
Expand Down
33 changes: 28 additions & 5 deletions QuickFIXn/AbstractInitiator.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Threading;
using System.Collections.Generic;
using System;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using QuickFix.Logger;
using QuickFix.Store;

Expand All @@ -20,22 +22,43 @@ public abstract class AbstractInitiator : IInitiator
private readonly SessionFactory _sessionFactory;
private Thread? _thread;

protected readonly NonSessionLog _nonSessionLog;
protected readonly ILogger _nonSessionLog;

public bool IsStopped { get; private set; } = true;

[Obsolete("Use \"Microsoft.Extensions.Logging.ILoggerFactory\" instead of \"QuickFix.Logger.ILogFactory\".")]
protected AbstractInitiator(
IApplication app,
IMessageStoreFactory storeFactory,
SessionSettings settings,
ILogFactory? logFactoryNullable,
IMessageFactory? messageFactoryNullable)
ILogFactory? logFactoryNullable = null,
IMessageFactory? messageFactoryNullable = null)
{
_settings = settings;
var logFactory = logFactoryNullable ?? new NullLogFactory();
ILoggerFactory logFactory = logFactoryNullable is null
? NullLoggerFactory.Instance
: new LogFactoryAdapter(logFactoryNullable, settings);
var msgFactory = messageFactoryNullable ?? new DefaultMessageFactory();
_sessionFactory = new SessionFactory(app, storeFactory, logFactory, msgFactory);
_nonSessionLog = new NonSessionLog(logFactory);
_nonSessionLog = logFactory.CreateLogger("QuickFix");

HashSet<SessionID> definedSessions = _settings.GetSessions();
if (0 == definedSessions.Count)
throw new ConfigError("No sessions defined");
}

protected AbstractInitiator(
IApplication app,
IMessageStoreFactory storeFactory,
SessionSettings settings,
ILoggerFactory? logFactoryNullable = null,
IMessageFactory? messageFactoryNullable = null)
{
_settings = settings;
var logFactory = logFactoryNullable ?? new NullLoggerFactory();
jkulubya marked this conversation as resolved.
Show resolved Hide resolved
jkulubya marked this conversation as resolved.
Show resolved Hide resolved
var msgFactory = messageFactoryNullable ?? new DefaultMessageFactory();
_sessionFactory = new SessionFactory(app, storeFactory, logFactory, msgFactory);
_nonSessionLog = logFactory.CreateLogger("QuickFix");

HashSet<SessionID> definedSessions = _settings.GetSessions();
if (0 == definedSessions.Count)
Expand Down
6 changes: 3 additions & 3 deletions QuickFIXn/AcceptorSocketDescriptor.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Net;
using QuickFix.Logger;
using Microsoft.Extensions.Logging;

namespace QuickFix
{
Expand All @@ -15,7 +15,7 @@ internal class AcceptorSocketDescriptor
public AcceptorSocketDescriptor(
IPEndPoint socketEndPoint,
SocketSettings socketSettings,
NonSessionLog nonSessionLog)
ILogger nonSessionLog)
{
Address = socketEndPoint;
SocketReactor = new ThreadedSocketReactor(Address, socketSettings, this, nonSessionLog);
Expand All @@ -26,7 +26,7 @@ public AcceptorSocketDescriptor(
IPEndPoint socketEndPoint,
SocketSettings socketSettings,
SettingsDictionary sessionDict,
NonSessionLog nonSessionLog) : this(socketEndPoint, socketSettings, nonSessionLog)
ILogger nonSessionLog) : this(socketEndPoint, socketSettings, nonSessionLog)
{ }

internal void AcceptSession(Session session)
Expand Down
4 changes: 2 additions & 2 deletions QuickFIXn/ClientHandlerThread.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Net.Sockets;
using System.Threading;
using System;
using QuickFix.Logger;
using Microsoft.Extensions.Logging;

namespace QuickFix
{
Expand Down Expand Up @@ -36,7 +36,7 @@ internal ClientHandlerThread(
long clientId,
SocketSettings socketSettings,
AcceptorSocketDescriptor? acceptorDescriptor,
NonSessionLog nonSessionLog
ILogger nonSessionLog
) {
Id = clientId;
_socketReader = new SocketReader(tcpClient, socketSettings, this, acceptorDescriptor, nonSessionLog);
Expand Down
1 change: 1 addition & 0 deletions QuickFIXn/Logger/CompositeLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace QuickFix.Logger;
/// <summary>
/// File log implementation
/// </summary>
[Obsolete("Use Microsoft.Extensions.Logging instead.")]
internal class CompositeLog : ILog
{
private readonly ILog[] _logs;
Expand Down
4 changes: 3 additions & 1 deletion QuickFIXn/Logger/CompositeLogFactory.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System.Linq;
using System;
using System.Linq;

namespace QuickFix.Logger;

/// <summary>
/// Allows multiple log factories to be used with QuickFIX/N.
/// For example, you could log events to the console and also log all events and messages to a file.
/// </summary>
[Obsolete("Use Microsoft.Extensions.Logging instead")]
public class CompositeLogFactory : ILogFactory
{
private readonly ILogFactory[] _factories;
Expand Down
1 change: 1 addition & 0 deletions QuickFIXn/Logger/FileLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace QuickFix.Logger;
/// <summary>
/// File log implementation
/// </summary>
[Obsolete("Use Microsoft.Extensions.Logging instead")]
public class FileLog : ILog
{
private readonly object _sync = new();
Expand Down
5 changes: 4 additions & 1 deletion QuickFIXn/Logger/FileLogFactory.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
namespace QuickFix.Logger;
using System;

namespace QuickFix.Logger;

/// <summary>
/// Creates a message store that stores messages in a file
/// </summary>
[Obsolete("Use Microsoft.Extensions.Logging instead")]
public class FileLogFactory : ILogFactory
{
private readonly SessionSettings _settings;
Expand Down
97 changes: 97 additions & 0 deletions QuickFIXn/Logger/FileLogger.cs
jkulubya marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
using System;
using Microsoft.Extensions.Logging;
using QuickFix.Fields.Converters;
using QuickFix.Util;

namespace QuickFix.Logger;

public class FileLogger : ILogger, IDisposable
{
private readonly object _messagesLock = new();
private readonly object _eventsLock = new();

private System.IO.StreamWriter _messageLog;
private System.IO.StreamWriter _eventLog;

private readonly string _messageLogFileName;
private readonly string _eventLogFileName;

/// <summary>
///
/// </summary>
/// <param name="fileLogPath">
/// All back or forward slashes in this path will be converted as needed to the running platform's preferred
/// path separator (i.e. "/" will become "\" on windows, else "\" will become "/" on all other platforms)
/// </param>
/// <param name="sessionId"></param>
internal FileLogger(string fileLogPath, SessionID sessionId)
{
string prefix = Prefix(sessionId);

string normalizedPath = StringUtil.FixSlashes(fileLogPath);

if (!System.IO.Directory.Exists(normalizedPath))
System.IO.Directory.CreateDirectory(normalizedPath);

_messageLogFileName = System.IO.Path.Combine(normalizedPath, prefix + ".messages.current.log");
_eventLogFileName = System.IO.Path.Combine(normalizedPath, prefix + ".event.current.log");

_messageLog = new System.IO.StreamWriter(_messageLogFileName, true);
_eventLog = new System.IO.StreamWriter(_eventLogFileName, true);

_messageLog.AutoFlush = true;
_eventLog.AutoFlush = true;
}

public static string Prefix(SessionID sessionId)
{
System.Text.StringBuilder prefix = new System.Text.StringBuilder(sessionId.BeginString)
.Append('-').Append(sessionId.SenderCompID);
if (SessionID.IsSet(sessionId.SenderSubID))
prefix.Append('_').Append(sessionId.SenderSubID);
if (SessionID.IsSet(sessionId.SenderLocationID))
prefix.Append('_').Append(sessionId.SenderLocationID);
prefix.Append('-').Append(sessionId.TargetCompID);
if (SessionID.IsSet(sessionId.TargetSubID))
prefix.Append('_').Append(sessionId.TargetSubID);
if (SessionID.IsSet(sessionId.TargetLocationID))
prefix.Append('_').Append(sessionId.TargetLocationID);

if (SessionID.IsSet(sessionId.SessionQualifier))
prefix.Append('-').Append(sessionId.SessionQualifier);

return prefix.ToString();
}

public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception,
Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel)) return;
if (eventId == LogEventIds.IncomingMessage || eventId == LogEventIds.OutgoingMessage)
{
lock (_messagesLock)
{
_messageLog.WriteLine(
$"{DateTimeConverter.ToFIX(DateTime.UtcNow, TimeStampPrecision.Millisecond)} : {formatter(state, exception)}");
}
}
else
{
lock (_eventsLock)
{
_eventLog.WriteLine(
$"{DateTimeConverter.ToFIX(DateTime.UtcNow, TimeStampPrecision.Millisecond)} : {formatter(state, exception)}");
}
}
}

public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None;

public IDisposable? BeginScope<TState>(TState state) where TState : notnull => default!;

public void Dispose()
{
_messageLog.Dispose();
_eventLog.Dispose();
}
}
Loading