Index: src/log4net/Appender/AndroidLogAppender.cs =================================================================== --- src/log4net/Appender/AndroidLogAppender.cs (revision 0) +++ src/log4net/Appender/AndroidLogAppender.cs (working copy) @@ -0,0 +1,65 @@ +using log4net.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +#if __ANDROID__ +using Android.Util; + +namespace log4net.Appender +{ + /// + /// Forward log messages to the Android Log. + /// + public class AndroidLogAppender : AppenderSkeleton + { + private struct Mapping { + public Mapping(Level original, LogPriority androidEquivalent) : this() + { + Original = original; + AndroidEquivalent = androidEquivalent; + } + + public Level Original {get; private set;} + public LogPriority AndroidEquivalent { get; private set; } + } + + private static readonly Mapping[] _orderedLevels; + + static AndroidLogAppender() + { + // NOTE: This are ordered by the Level, as log4net allows custom levels, + // so we only include the "corresponding" ones here. Append will find the + // best match for those custom levels (hence the use of Level.All below as well). + _orderedLevels = new Mapping[] { + new Mapping(Level.Verbose, LogPriority.Verbose), + new Mapping(Level.Debug, LogPriority.Debug), + new Mapping(Level.Info, LogPriority.Info), + new Mapping(Level.Warn, LogPriority.Warn), + new Mapping(Level.Error, LogPriority.Error), + // All the rest. (N.B. assert is the wtf android log level). + new Mapping(Level.All, LogPriority.Assert), + }; + } + protected override void Append(LoggingEvent loggingEvent) + { + // Retrieve the level which is at least as important as the one in the logging event. + // (i.e. we want levels that are one higher than DEBUG to be logged as INFO etc.) + var androidLevel = _orderedLevels.First(m => m.Original >= loggingEvent.Level).AndroidEquivalent; + + // TODO: Ensure that the log level is correct and maybe do another log if it is bad? + if(Log.IsLoggable(loggingEvent.LoggerName, androidLevel)) + { + var message = RenderLoggingEvent(loggingEvent); + // I'm fairly certain I can ignore the return value here... + Log.WriteLine(androidLevel, loggingEvent.LoggerName, message); + } + else + { + ErrorHandler.Error("Failed to log message for logger: {0} with log4net level of: {1} to android level of: {2} with tag of: {3} because Logger is off for this level and tag."); + } + } + } +} +#endif \ No newline at end of file Index: src/log4net/log4net.vs2010.csproj =================================================================== --- src/log4net/log4net.vs2010.csproj (revision 1606952) +++ src/log4net/log4net.vs2010.csproj (working copy) @@ -124,6 +124,7 @@ Code + Code --- C:/Work/log4net/log4net.android.csproj Thu Jul 3 16:40:45 2014 +++ C:/Work/log4net/log4net.android.csproj Fri Jul 4 11:19:01 2014 @@ -46,7 +46,6 @@ Code + Code --- C:/Work/log4net/log4net.iOS.csproj Fri Jul 4 11:19:01 2014 +++ C:/Work/log4net/log4net.iOS.csproj Wed Jul 2 09:15:27 2014 @@ -48,6 +48,7 @@ Code + Code