Symptoms
An exception can be thrown on startup from GatewayHttpListenerInstaller (such as the exception below, but this is logger-specific) due to logging statements that are misunderstood by certain logger implementations. Specifically, NLog and the Microsoft.Extensions.Logging.Console implementation don't appear to work, but there may be others.
Who's affected
Anyone running the Gateway component with a logger that doesn't support repeated logging tokens, such as NLog.
Root cause
While string.Format("{0}-{0}", "a")
will use the same token and result in a-a
, using logger.InfoFormat("{0}-{0}", "a")
has uneven results depending on the logger implementation being used.
In NLog:
logger.InfoFormat("{0} - {0}", "a", "b"); // Result: "a-a"
logger.InfoFormat("{0} - {0}", "a"); // Result: Exception, wants 2nd param even though it won't use it
Original bug report
Describe the bug
Description
When execute EnableInstaller() In line 49 and 57 of GatewayHttpListenerInstaller.cs the format of the string on calling log.information throws an exception
System.AggregateException: An error occurred while writing to logger(s). (Index (zero based) must be greater than or equal to zero and less than the size of the argument list.)
Expected behavior
The log is write in configured loggers.
Actual behavior
The string in log information is wrong formated
Versions
Nservicebus.Gateway 4.0.0
Steps to reproduce
Use EnableInstallers without admin privileges and debug level sets as "Information".
Relevant log output
System.AggregateException: An error occurred while writing to logger(s). (Index (zero based) must be greater than or equal to zero and less than the size of the argument list.)
---> System.FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list.
at System.Text.ValueStringBuilder.AppendFormatHelper(IFormatProvider provider, String format, ParamsArray args)
at System.String.FormatHelper(IFormatProvider provider, String format, ParamsArray args)
at System.String.Format(IFormatProvider provider, String format, Object[] args)
at Microsoft.Extensions.Logging.LogValuesFormatter.Format(Object[] values)
at Microsoft.Extensions.Logging.FormattedLogValues.ToString()
at Microsoft.Extensions.Logging.LoggerExtensions.MessageFormatter(FormattedLogValues state, Exception error)
at OpenTelemetry.Logs.OpenTelemetryLogger.Log[TState](LogLevel logLevel, EventId eventId, TState state, Exception exception, Func`3 formatter)
at Microsoft.Extensions.Logging.Logger.<Log>g__LoggerLog|13_0[TState](LogLevel logLevel, EventId eventId, ILogger logger, Exception exception, Func`3 formatter, List`1& exceptions, TState& state)
--- End of inner exception stack trace ---
at Microsoft.Extensions.Logging.Logger.ThrowLoggingError(List`1 exceptions)
at Microsoft.Extensions.Logging.Logger.Log[TState](LogLevel logLevel, EventId eventId, TState state, Exception exception, Func`3 formatter)
at Microsoft.Extensions.Logging.LoggerExtensions.Log(ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, String message, Object[] args)
at Microsoft.Extensions.Logging.LoggerExtensions.Log(ILogger logger, LogLevel logLevel, String message, Object[] args)
at Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(ILogger logger, String message, Object[] args)
at NServiceBus.Extensions.Hosting.Logger.InfoFormat(String format, Object[] args) in /_/src/NServiceBus.Extensions.Hosting/Logging/Logger.cs:line 52
at NServiceBus.Installation.GatewayHttpListenerInstaller.Install(String identity, CancellationToken cancellationToken) in /_/src/NServiceBus.Gateway/Installer/GatewayHttpListenerInstaller.cs:line 57
at NServiceBus.HostingComponent.RunInstallers(CancellationToken cancellationToken) in /_/src/NServiceBus.Core/Hosting/HostingComponent.cs:line 74
at NServiceBus.ExternallyManagedContainerHost.Start(IServiceProvider serviceProvider, CancellationToken cancellationToken) in /_/src/NServiceBus.Core/Hosting/ExternallyManagedContainerHost.cs:line 45
at NServiceBus.Extensions.Hosting.NServiceBusHostedService.StartAsync(CancellationToken cancellationToken) in /_/src/NServiceBus.Extensions.Hosting/NServiceBusHostedService.cs:line 30
at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
Additional Information
Workarounds
Setup the log leven on warning.
Possible solutions
Additional information