Skip to content

Consider providing XUnitLoggerOptions property to provide custom implementation of WriteMessage #849

@scomtott

Description

@scomtott

Is your feature request related to a problem?

No

Describe the solution you'd like

I have written a custom XUnit runner reporter and had also written a custom XUnitLogger implementation that sent messages to this runner reporter when I found your library that does a much better job of the latter part.

It would be useful if a user could provide their own implementation of WriteMessage to, for example, emit messages as serialised content to be read by the runner reporter.

public class XUnitLoggerOptions
{
    public Func<LogLevel, int, string?, Exception?, IMessageSinkMessage>? WriteMessageToMessageSinkOverride { get; set; }
}

public partial class XUnitLogger
{
  private Func<LogLevel, int, string?, Exception?, IMessageSinkMessage>? _writeMessageToMessageSinkOverride { get; set; }

    public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
    {
        if (!IsEnabled(logLevel))
        {
            return;
        }

        ArgumentNullException.ThrowIfNull(formatter);
        if (formatter == null)
        {
            throw new ArgumentNullException(nameof(formatter));
        }

        string? message = formatter(state, exception);

        if (!string.IsNullOrEmpty(message) || exception != null)
        {
            if (_writeMessageToMessageSinkOverride != null)
            {
                _messageSinkAccessor?.MessageSink.OnMessage(_writeMessageToMessageSinkOverride(logLevel, eventId, message, exception);
            }
            else
            {
                WriteMessage(logLevel, eventId.Id, message, exception);
            }
        }
    }
}

I've obviously left out a lot of the implementation details in the above code snippet.

Describe alternatives you've considered

I know that I can provide a MessageSinkMessageFactory to intercept messages that are sent to the IMessageSink but this would involve parsing out a bunch of things that have already been added to the log message.

Additional context

I'm happy to implement this myself and raise a PR, I just wanted to get your thoughts on the issue first.

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature-requestA request for new functionality

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions