You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Feb 12, 2025. It is now read-only.
Bug description
Remote logging config is slow and eventually fails silently. (~10-15 sec) On Android - Maui 8.
Expected behavior
Setting config enables remote logging, or throws @ config if failure.
Actual behavior
Setting config for a remote syslog results in an internal error resulting in no logs sent. The internal nLog.Syslog.Targets code is mis-identifying Android OS as OSX.
Internal logs from nLog:
[DOTNET] 2024-09-04 12:51:10.7680 Warn [Syslog] SendAsync failed Exception: System.ApplicationException: Socket option syscall error value: '-1'
[DOTNET] at NLog.Targets.Syslog.MessageSend.Interop.ThrowOnError(Int32 error)
[DOTNET] at NLog.Targets.Syslog.MessageSend.Interop.SetSockOptSysCall(Socket socket, SocketOptionLevel optionLevel, SocketOptionName optionName, Int32 optionValue)
>>>[DOTNET] at NLog.Targets.Syslog.MessageSend.SocketInitializationForOsx.ApplyKeepAliveValues(Socket socket, KeepAliveConfig keepAliveConfig) <<<<<<
[DOTNET] at NLog.Targets.Syslog.MessageSend.SocketInitialization.SetKeepAlive(Socket socket, KeepAliveConfig keepAliveConfig)
[DOTNET] at NLog.Targets.Syslog.MessageSend.Tcp.Init(IPEndPoint ipEndPoint)
[DOTNET] at NLog.Targets.Syslog.MessageSend.MessageTransmitter.<PrepareForSendAsync>b__19_0(Task _)
[DOTNET] at NLog.Targets.Syslog.Extensions.TaskExtensions.<>c__DisplayClass1_0`1[[System.Threading.Tasks.Task, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<Then>b__0(Task t, Object c)
[DOTNET] at System.Threading.Tasks.ContinuationResultTaskFromTask`1[[System.Threading.Tasks.Task`1[[System.Threading.Tasks.Task, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].InnerInvoke()
[DOTNET] at System.Threading.Tasks.Task.<>c.<.cctor>b__281_0(Object obj)
[DOTNET] at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
[DOTNET] --- End of stack trace from previous location ---
[DOTNET] at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
[DOTNET] at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
From debugging my app-code, Android is returning as "UNIX" from: Environment.OSVersion.Platform, resulting in the above code defaulting to OSx as the OS, which explains why my Maui app does still log from the iOS package.
System.Runtime.InteropServices.RuntimeInformation.RuntimeIdentifier; does return a value that could correctly ID Android: "android-arm64", but does not match existing internal conventions for identifying the OS @ runtime.
To reproduce
Simply try to configure a syslog target on Android (Maui 8).
Additional context
NLog version: 5.3.2
NLog.Targets.Syslog version 7.0.0
NLog configuration used
Inline c#
DeviceId=deviceIdentifier;varmachineName=variable1??"pre-login-shared";varprogramName=user??"[unknown]";varconfig=newNLog.Config.LoggingConfiguration();varpapertrailTarget=newNLog.Targets.Syslog.SyslogTarget();config.AddTarget("syslog",papertrailTarget);papertrailTarget.MessageCreation.Facility=Facility.Local7;papertrailTarget.MessageCreation.Rfc5424.Hostname=machineName;papertrailTarget.MessageCreation.Rfc5424.AppName=programName;papertrailTarget.MessageSend.Protocol=ProtocolType.Tcp;papertrailTarget.MessageSend.Tcp.Server="[redacted]";papertrailTarget.MessageSend.Tcp.Port=[redacted];papertrailTarget.MessageSend.Tcp.Tls.Enabled=true;// Only allow debug logging in debug mode, so we don't open a security hole by accidentally// logging sensitive debug information
#if DEBUGvarrule=newNLog.Config.LoggingRule("*",NLog.LogLevel.Debug,papertrailTarget);
#else
varrule=newNLog.Config.LoggingRule("*",NLog.LogLevel.Info,papertrailTarget);
#endif
config.LoggingRules.Add(rule);NLog.LogManager.Configuration=config;
Any other context about the problem
The above inline-config has worked for both Android and iOS for years in Xamarin.Forms, only while porting our stack to Maui/.Net 8 did we see this issue. I expect that with the older mono-runtime that our Xamarin stack used, Android was identifying as Linux, and so worked as expected? I have not yet confirmed that. The Xamarin code where this was compiled previously was .NetStandard 2.1, and the new code base is all .Net8, but I did some testing to revert the logging project back to .NetStandard 2.1 without a change in the outcome.
The only idea I have ATM is to allow some sort of optional injection for identifying the OS instead of relying on only .Net 8 Core API's that don't know about mobile os's, but fallback to the current impl if the injection site is left null. Allowing some sort of optional injection would allow for application-code to map from mobile OS to the correct equivalent Windows/Linux/OSx desktop variant, but not disrupt current server/desktop code?
Ok, finally back to this. Disappointed there has been 0 activity here...
This change looks like it un-breaks setting up a TCP socket on Xamarin.Android/Maui.
public static SocketInitialization ForCurrentOs()
{
// Android/Maui returns " Linux 4.14.276-g6ef255005cea-ab9062920 #1 SMP PREEMPT Wed Sep 14 08:05:09 UTC 2022" here. On the devices I tested on.
// we'll use this below.
string rt = RuntimeInformation.OSDescription;
bool isMac = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
Debug.WriteLine($"===== NLog.Targets.Syslog detected OS: {rt}");
Debug.WriteLine($"isMac: {isMac}");
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return new SocketInitializationForWindows();
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
||
rt.ToLower().Contains("linux"))
{
return new SocketInitializationForLinux();
}
return new SocketInitializationForOsx();
}
This isn't robust... since it still defaults to OSX if no specific detection made prior, and in my testing, iOS returns rt = "Darwin x.y.z ...." from OSDescription, so could proactively detect Apple-family OS's ...
It really only works for iOS because Apple's config is last/default, currently, so doesn't really need to change, I suppose.
A more complete/robust solution to officially support Maui would be to add an injection site to override this method impl, and then inject it from a new wrapper lib (NLog.Targets.Syslog.Maui, for example) that has Maui dependencies and can get specific Maui-supported platform info and correctly detect the OS, which Maui already has API's to do reliably.... And provides Maui-friendly initializaiton. 🤔
Bug description
Remote logging config is slow and eventually fails silently. (~10-15 sec) On Android - Maui 8.
Expected behavior
Setting config enables remote logging, or throws @ config if failure.
Actual behavior
Setting config for a remote syslog results in an internal error resulting in no logs sent. The internal
nLog.Syslog.Targets
code is mis-identifying Android OS as OSX.Internal logs from nLog:
This is the section of code responsible for identifying the OS @ runtime:
https://github.com/luigiberrettini/NLog.Targets.Syslog/blob/8187976cd29cb1baef5447163b1b305681576fad/src/NLog.Targets.Syslog/MessageSend/SocketInitialization.cs#L12C9-L19C10
From debugging my app-code, Android is returning as "UNIX" from:
Environment.OSVersion.Platform
, resulting in the above code defaulting to OSx as the OS, which explains why my Maui app does still log from the iOS package.System.Runtime.InteropServices.RuntimeInformation.RuntimeIdentifier;
does return a value that could correctly ID Android: "android-arm64", but does not match existing internal conventions for identifying the OS @ runtime.To reproduce
Simply try to configure a syslog target on Android (Maui 8).
Additional context
Inline c#
The above inline-config has worked for both Android and iOS for years in Xamarin.Forms, only while porting our stack to Maui/.Net 8 did we see this issue. I expect that with the older mono-runtime that our Xamarin stack used, Android was identifying as Linux, and so worked as expected? I have not yet confirmed that. The Xamarin code where this was compiled previously was .NetStandard 2.1, and the new code base is all .Net8, but I did some testing to revert the logging project back to .NetStandard 2.1 without a change in the outcome.
The only idea I have ATM is to allow some sort of optional injection for identifying the OS instead of relying on only .Net 8 Core API's that don't know about mobile os's, but fallback to the current impl if the injection site is left null. Allowing some sort of optional injection would allow for application-code to map from mobile OS to the correct equivalent Windows/Linux/OSx desktop variant, but not disrupt current server/desktop code?
This is Maui's list of OS's:
https://github.com/dotnet/maui/blob/5c0e6d64a11e3912c94c5d2591c44e986909fa23/src/Essentials/src/Types/DevicePlatform.shared.cs#L65
The text was updated successfully, but these errors were encountered: