Git Product home page Git Product logo

liblog's Introduction

Hi there ๐Ÿ‘‹

liblog's People

Contributors

adamralph avatar austinlparker avatar bartelink avatar bbrandt avatar cd21h avatar cerebrate avatar chrishimsworth avatar damianh avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar ericnewton76 avatar flytzen avatar jericho avatar jhorv avatar kendallmiller avatar lahma avatar matthewvukomanovic avatar petemounce avatar pm7y avatar pomma89 avatar ragingkore avatar ramonsmits avatar remyboyer avatar samcragg avatar snakefoot avatar stevenbonepgh avatar timmurphy avatar yevgeniyredko avatar yyjdelete avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

liblog's Issues

Method name not outputing correctly in Log4Net logger.

When logging using Log4Net when outputting the method name where the logger is used the method name is CallSite.Target rather than the actual method name used.

For example using a Log4Net layout like the following results in incorrect behaviour.

<layout type="log4net.Layout.PatternLayout">
    <!-- &#x9; == TAB character as a seperator between each field.-->
    <param name="ConversionPattern" value="[${COMPUTERNAME}]&#x9;[%date{ISO8601}]&#x9;[%-5level]&#x9;[%thread]&#x9;[%logger]&#x9;[%method]&#x9;[%property{NDC}]&#x9;[%message %exception] &#x9;%newline" />
</layout>

This outputs the following, CallSite.Target should contain the method name.

[NL-DEV]    [2015-01-22 16:29:20,242]   [DEBUG] [6] [zhapi.Bootstrapper]    [CallSite.Target]   [(null)]    [Enabling CORS Support ]

LogProvider.GetCurrentClassLogger() vulnerable to JIT inlining

See scriptcs/scriptcs#1009 (comment)

As I began to mention last night, the way we're using LibLog in scriptcs is rather unusual, resulting in us providing ILog extension methods. Anyway, one of those methods is a direct equivalent of LogProvider.GetCurrentClassLogger().

Due to the conclusions that the JIT compiler arrives at, the extension method happens to get inlined which alters the stack and caused the StackFrame stuff to blow up with an NRE. The cause of the issue was very hard to determine because the stack trace was very misleading. I just happened to notice that we were only getting the failure in Release and not Debug, so I took a punt on that method, shoved [MethodImpl(MethodImplOptions.NoInlining)] onto it, and hey presto, it fixed the problem.

Anyway, I'm not sure if anyone's run into this with LibLog. I guess not, and that's probably just a lucky outcome of the JIT, but I wonder if it may be worth putting the attribute on that method now to insulate it against a different JIT heuristic in the future. After all, .NET 4.6 is getting a new 64-bit JIT and who knows what that might do, in it's final form, against this method? I suppose if you're ever playing with StackFrame in a method like this it's probably a very good idea to deterministically prevent inlining to keep the method behaving as you want it to.

GlobalContext/ThreadContext

Hi,
Nice project!

I have a question - I want to set some GlobalContext/ThreadContext variables in case the user uses log4net. I can't see any method which supports this. Castle's logging interface seem to support this using an interface named IExtendedLogger which has a property that allows access to these contexts.

Are there any plans to add support for this to LibLog? will you accept a pull request for this kind of feature?

Thanks

Is it possible to target Core CLR?

Hi

I am attempting to use LibLog with new preview of VS 2015.
I 'dropped' LibLog.cs into new (poorly named) "ASP NET 5 Class Library" project (which will be renamed to ".NET Class Library (Cross-platform)" and have attempted to target Core CLR...

After a number of added references, I am left with 2 unresolved references and 1 error.
Below is my project.json file as a reference and 3 compiler errors I have encountered....

  1. Is it even feasible targeting much restrictive "asnetcore50" ?
  2. If yes, any hints on how I may go about resolving the errors?

Thanks
z.

errors

    Error   CS0246  The type or namespace name 'StackFrame' could not be found (are you missing a using directive or an assembly reference?)    AspNet5ClassLibrary1.ASP.NET Core 5.0   LibLog.cs   379
    Error   CS0117  'Delegate' does not contain a definition for 'CreateDelegate'   AspNet5ClassLibrary1.ASP.NET Core 5.0   LibLog.cs   1910
    Error   CS1061  'Type' does not contain a definition for 'Assembly' and no extension method 'Assembly' accepting a first argument of type 'Type' could be found (are you missing a using directive or an assembly reference?)   AspNet5ClassLibrary1.ASP.NET Core 5.0   LibLog.cs   1919

project.json

{
    "version": "1.0.0-*",
    "dependencies": {

    },

    "frameworks": {
        "net45": {
            "dependencies": {
            }
        },
        "aspnet50": {
            "dependencies": {
            }
        },
        "aspnetcore50": {
            "dependencies": {
                "System.Runtime": "4.0.20-beta-*",
                "System.Runtime.Extensions": "4.0.10-beta-*",
                "System.Collections": "4.0.10-beta-*",
                "System.Console": "4.0.0-beta-*",
                "System.Diagnostics.Process": "4.0.0-beta-*",
                "System.Diagnostics.Tools": "4.0.0-beta-*",
                "System.Diagnostics.Contracts": "4.0.0-beta-*",
                "System.Diagnostics.Debug": "4.0.0-beta-*",
                "System.Diagnostics.TraceSource": "4.0.0-beta-*",
                "System.Diagnostics.FileVersionInfo": "4.0.0-beta-*",
                "System.Linq": "4.0.0-beta-*",
                "System.Linq.Expressions": "4.0.0-beta-*",
                "System.Globalization": "4.0.10-beta-*",
                "System.Text.RegularExpressions": "4.0.10-beta-*",
                "System.Dynamic.Runtime": "4.0.0-beta-*",
                "System.Reflection": "4.0.10-beta-*",
                "System.Reflection.Primitives": "4.0.0-beta-*",
                "System.Reflection.TypeExtensions": "4.0.0-beta-*",
                "System.Reflection.Extensions": "4.0.0-beta-*"
            }
        }
    }
}

XML Documentation

When generating documentation using Sandcastle Help File Builder after installing the LibLog.cs, I noticed there were a few missing doc comments. One was on the Logger delegate, the other is a missing Namespace comment.

I'd suggest adding something like this for the namespace comment - adding the version like in the sample would be great (if possible):
/// <summary>
/// Logging mechanism provided by using <see href="https://github.com/damianh/LibLog">LibLog</see> version 4.2.3. For documentation on how
/// to use, configure, or modify logging in this library, visit the <see href="https://github.com/damianh/LibLog">LibLog Project Site</see>.
/// </summary>
[CompilerGenerated]
internal class NamespaceDoc
{
}

Great library!

Custom event properties

I'm using LibLog as part of an IdentityServer implementation and am using NLog as my logging provider. We need to log a number of custom fields to be able to troubleshoot potential issues with users. NLog allows custom fields with a Properties dictionary and the event-context layout renderer. Is this supported via LibLog?

I don't see anything that would allow this, but I may have missed it.

Thanks so much.

NullReferenceException when using IsDebugEnabled

Hi!

I get the following error using Logger.IsDebugEnabled()

ERROR MyUtilities.MyService (null) - Failed to generate log message
System.NullReferenceException: Object reference not set to an instance of an object.
   at MyUtilities.Logging.LoggerExecutionWrapper.<>c__DisplayClass2.<Log>b__0() 
in c:\...\MyUtilities\App_Packages\LibLog.1.3\Logging.cs:line 330

The code:

public class MyService {
    private static readonly ILog Logger = LogProvider.For<MyService>(); 

    public void MyMethod() {
        if (Logger.IsDebugEnabled())
            Logger.Debug("This is my debug message");
    }
}

What should be the accessibility of the various LogProvider get logger methods?

In v1-3, LogProvider.For<>(), LogProvider.GetCurrentClassLogger() and LogProvider.GetLogger() were public and available to all.

Reports in the field were of people doing var logger = YourLib.Logging.LogProvider.For<>() in their code causing undesirable coupling.

In v4 the intention was to make them internal to prevent this but there is a scenario where this fails: where people have one solution with several projects and they only want to use one LibLog from their Core project (and they aren't using [InternalsVisibleTo]

Options are:

  1. Make them public and add an xml comment something along the lines of "If you don't own this library, it is advisable that you don't calling this."
  2. Make them internal only and encourage [InternalsVisibleTo] which will have it's own side effects.
  3. ??

v4 is delisted pending fixing of this

Ping @SimonCropp @adamralph

Mono compiler warnings

App_Packages/LibLog.3.1/LibLog.cs(652,38): error CS0414: Warning as Error: The private field `ScriptCs.Logging.LogProviders.NLogLogProvider.NLogLogger._logger' is assigned but its value is never used

App_Packages/LibLog.3.1/LibLog.cs(871,38): error CS0414: Warning as Error: The private field `ScriptCs.Logging.LogProviders.Log4NetLogProvider.Log4NetLogger._logger' is assigned but its value is never used

JSON Escaping in xxxFormat calls

e.g.

Logger.InfoFormat("{0}\n {1}", "Client validation success", json);

2015-04-21 15:26:54.160 +02:00 [Information] "Client validation success"
"{
"ClientId": "client",
"ClientName": "Client Credentials Flow Client",
"ClientCredentialType": "SharedSecret"
}"

Does not happen when using Format and concat the string manually.

automatically test new logging nugets

I am not sure if you already do this but it is probably valuable for you to setup a custom daily CI build that does a nuget update on all the logging lobs your support and runs through your standard suite of tests. This means as soon as a new incompatible version of any of those libs is released you will know in in an automated way.

LoupeLogger skipLevel

Is it me or the default skipLevel in the loupeLogger should be set to 2 ?
With the default setting of 1 i get the all my log locations refer to LigLog.cs

Log4Net Log level initialized to null

Hi @damianh, thanks for the excellent library. Trying to write a blog about it and created a sample console project with log4net to test it out, but the logger is initialized with level=null However, the EffectiveLevel is set correctly to what's configured in the log4net.config file. Please tell me it's something silly I did an not a bug? Happy to supply any files you may need, though the setup is pretty basic. Any help would be really appreciated.

Would be nice with a factory for logproviders that work accross libs that use liblog

In our solution we use idsrv3 and a few of my own libs that all have used liblog.

From the developer point of view when using multiply libs that use liblog one has to configure at startup the logproviders for all of them.

ns1.Logging.LogProvider.SetCurrentLogProvider(...);
ns2.Logging.LogProvider.SetCurrentLogProvider(...);
ns3.Logging.LogProvider.SetCurrentLogProvider(...);
ns4.Logging.LogProvider.SetCurrentLogProvider(...);

Due to it's not a shared library that is used I need to implement my log provider for each of the using libs since they have their own dll ect. The problem that i have is the enum for loglvl that exists in all libs that use liblog. Maybe someone can do some magic using a primitive type?

If someone has a workaround with reflection that would work for me also.

Example:

public class MultiDiagnosticsTraceLogProvider : ILogProvider, 
    SInnovations.ConfigurationManager.Logging.ILogProvider, 
    SInnovations.Azure.MessageProcessor.Core.Logging.ILogProvider, 
    SInnovations.Azure.TableStorageRepository.Logging.ILogProvider
{
    public Logger GetLogger(string name)
    {
        return new DiagnosticsTraceLogger(name).Log;
    }
    SInnovations.ConfigurationManager.Logging.Logger SInnovations.ConfigurationManager.Logging.ILogProvider.GetLogger(string name)
    {
        return new DiagnosticsTraceLogger(name).Log; //this cannot be reused.
    }

    SInnovations.Azure.MessageProcessor.Core.Logging.Logger SInnovations.Azure.MessageProcessor.Core.Logging.ILogProvider.GetLogger(string name)
    {
        throw new NotImplementedException();
    }

    SInnovations.Azure.TableStorageRepository.Logging.Logger SInnovations.Azure.TableStorageRepository.Logging.ILogProvider.GetLogger(string name)
    {
        throw new NotImplementedException();
    }
}

and

public class DiagnosticsTraceLogger : ILog
{
    private readonly string _name;
    private static string fullPattern = Regex.Replace(DateTimeFormatInfo.CurrentInfo.FullDateTimePattern, "(:ss|:s)", "$1.fff");

    public DiagnosticsTraceLogger(string name)
    {
        this._name = string.Format("[{0}]", name);
    }

    public bool Log(Ascend.Common.Logging.LogLevel logLevel, Func<string> messageFunc, Exception exception = null, params object[] formatParameters)
    {
        if (messageFunc != null)
        {
            if (exception == null)
            {
                string message = string.Format("{0}: {1} -- {2}", this._name, DateTimeOffset.UtcNow.ToString(fullPattern), string.Format(messageFunc(), formatParameters));
                TraceMsg(logLevel, message);
            }
            else
            {
                string str2 = string.Format("{0}: {1} -- {2}\n{3}", new object[] { this._name, DateTimeOffset.UtcNow.ToString(fullPattern), string.Format(messageFunc(), formatParameters), exception });
                TraceMsg(logLevel, str2);
            }
        }
        return true;
    }

    private static void TraceMsg(Ascend.Common.Logging.LogLevel logLevel, string message)
    {
        switch (logLevel)
        {
            case Ascend.Common.Logging.LogLevel.Trace:
            case Ascend.Common.Logging.LogLevel.Debug:
                Trace.WriteLine(message, logLevel.ToString());
                return;

            case Ascend.Common.Logging.LogLevel.Info:
                Trace.TraceInformation(message);
                return;

            case Ascend.Common.Logging.LogLevel.Warn:
                Trace.TraceWarning(message);
                return;

            case Ascend.Common.Logging.LogLevel.Error:
                Trace.TraceError(message);
                return;

            case Ascend.Common.Logging.LogLevel.Fatal:
                Trace.TraceError(string.Format("FATAL : {0}", message));
                return;
        }
    }
}

Reloading base log provider seems to break liblog.

Using NLog, if I reconfigure the logger via code, it seems as if Liblog loses the references it needs in order to build log sinks. No promises, but will try to build a simplistic reproduction of this.

Should LibLog support password masking scenarios

As my library is developing, i'm running into an issue that i do not think i want the users of the library to have to implement... password masking.

In my case, it could be a json string or a connectionString, like you would use for SQL server.

Digging into the source code, it looks like the most practical place to implement the masking would be under LogMessageFormatter.SimulateStructuredLogging(messageFunc, formatParameters) {...}, and then in the serilog provider {TBD}.

I have some code that could be a basis of this, if interested (regex may need to be refactored a slight bit, but it is functional).

Support LIBLOG_PROVIDERS_ONLY for libs with their own logging API

Originally titled 'scriptcs use case'. After discussion, it seems there is a potential for a new feature here so I've updated the title accordingly.

Whether this is just an FYI, a discussion or a proposal for a feature I don't know, but I'm going to leave it here FWIW.

We are in the process of adopting LibLog for scriptcs (elbowing out Common.Logging).

The way logging has been done scriptcs historically is slightly different to most cases. Instead of using static log provision, i.e. private static readonly ILog log = LogProvider.For<Foo>(); etc, we inject logging types via constructors (currently ILog but we are taking advantage of the breaking change of removing Common.Logging to change to ILogProvider). When using the core library, it is the responsibility of the consumer to pass an ILogProvider instance when constructing any objects which demand it. When using the hosting library, an IoC container is used to provide all the services required so an ILogProvider only needs to be passed once. (There is also an outstanding issue to remove this burden from consumers who don't care by providing an overload which uses a default logger internally.)

The way we have adopted LibLog is to install it in our central Contracts library, which contains chiefly interfaces and some light abstract classes. It is the ILogProvider interface defined here which is used by all dependent libraries and indeed is the interface designed for consumption by script packs, modules and scripts when they demand an injected instance. I.e. it the officially supported interface for logging in scriptcs. Now, this does immediately couple the ecosystem to LibLog but, if the interfaces change in the future, we accept the burden of deciding whether to propagate the breaking change or hide/customise the LibLog interfaces as we see fit. For convenience, we also expose a DefautLogProvider which wraps the internal LibLog providers and a NullLogProvider.

Now, the pros and cons of constructor vs static logging provision can be debated, but it does have the advantage that when a custom logger is specified, as indeed it is when the hosting lib is used from scriptcs.exe, there is no need to adapt and propagate the library specific ILogProvider to the lower level libs. I did spike conversion of the whole thing to static log provision but I decided to abandon it since logging injection for script packs, modules and scripts is something we do want to support, so ultimately we will always end up doing this using centrally defined logging interaces in the Contracts library. Having each lib with it's own LibLog with all the adaptation required to get a provider all the way down into Contracts and the adaptation to get it back out as a Contracts interface just seemed like complete overkill.

So, the bottom line is, for this use case, we hack out about 60 lines of LibLog to reduce the API to only that which is required to support it. You can see the change here https://github.com/adamralph/scriptcs/commit/2ee8d6916ccd2e9ab855a7517558995fd612d169

To summarise:

  • LogExtensions stays public - the removal of the conditional comp there isn't strictly necessary
  • LogProvider becomes internal
  • All redundant LogProvider fields and methods are removed

Why am I raising this issue? Good question. I guess I'm looking for opinion on the above and/or a consideration of whether you'd like to support a conditional compilation symbol which could give us just the API required for this use case without having to customise LibLog after installation. I concede that it's likely few projects are using LibLog in this way, but I believe the approach of constructor based log provision, as opposed to static log provision, can be regarded as a general pattern.

</walloftext>

SeriLog provider moved back down the list

I noticed in 1.4 that the SerilogLogProvider has been moved down the list in

private static ILogProvider ResolveLogProvider()

Would it be possible to move it back up to the top as SeriLog can sit over the top of Log4Net, etc.

Compilation Error on line 1886 of LibLog.cs

While working on another issue I'm seeing a compilation error on this line:

            if (formatParameters == null || !formatParameters.Length == 0)
            {
                return messageBuilder;
            }

Due to the ! in front of "formatParameters.Length". The specific compilation error in VS 2013 is:

Error 1 Operator '!' cannot be applied to operand of type 'int' C:\Development\Git\LibLog\src\LibLog\LibLog.cs 1886 45 LibLog

which would be trivial to resolve by wrapping the expression in parenthesis, but I think the logic is wrong - I think the goal was to test for null or zero length in which case the ! is a typo.

log4net LogicalThreadContext support

This is somehow related to #49 I've opened before.

log4net's NDC and MDC classes which are used by LibLog use the ThreadContext static class (see the implementation).
ThreadContext is implemented using a [ThreadStatic] variable. This doesn't work well with the asyc/await feature since you might return to a different thread than the one you started on.

In order to solve this, we can use log4net's LogicalThreadContext - we just need to use the exact same implementation in the referenced NDC and MDC files, but replace everywhere ThreadContext with LogicalThreadContext.
This will use the CallContext class and therefore will not suffer with async/await issues.

Note that this is the default behavior of Serilog's implementation (see here).

Everything Should be Internal

Right now liblog leaks. At the very least there should be a compiler flag like LIBLOG_INTERNAL (tinyioc does this as well)

Be able to Disable all logging for a given Lib

"I want to just disable console logging, actually all logging, in tests. I'd like Console logger to remain in use in shipped assembly.", paraphrased from @leastprivilege

I propose a public static void LogProvider.Disable() and that will mean for every subsequent call to GetLogger() a Noop logger is returned. I can see this being of use to Lib consumers who may just want to turn off logging for a lib they are consuming.

Point of note - this will be static mutable state. This needs to be considered when leveraging parallel testing.

A corresponding public static void LogProvider.Enable() would be needed also.

When using with Serilog, not able to format messages to output objects using the @ operator

Would it be possible to change this so when you pass in a list of object params, it is down to each logging provider to decide how to format the message and parameters/args?
For example, most would use string.Format(CultureInfo.InvariantCulture, message, args)) before writing the message, but for Serilog, you could pass the message and args and it would correctly format the message.

Support extension methods for string format

An example (taken from https://github.com/Catel/Catel/blob/develop/src/Catel.Core/Catel.Core.Shared/Logging/Extensions/LogExtensions.debug.cs#L30):

        /// <summary>
        /// Writes the specified message as debug message.
        /// </summary>
        /// <param name="log">The log.</param>
        /// <param name="messageFormat">The message format.</param>
        /// <param name="args">The formatting arguments.</param>
        public static void Debug(this ILog log, string messageFormat, params object[] args)
        {
            string message = messageFormat ?? string.Empty;
            if (args != null && args.Length > 0)
            {
                message = string.Format(message, args);
            }

            log.Debug(message);
        }

LibLog is logging it's own Stack Trace and not the actual log

When I log data in my application and I want the Method Name and Class Name I'm getting the LibLog data and not my application data - Method Name = Log , and Class Name = LoggerExecutionWrapper.

After some debugging it seems that the problem is in the IsInTypeHierarchy method(line 1213) which returns the wrong result so the Stack Trace includes the LibLog data.
I wrote my own method to check if the types in the Stack Trace are part of the LibLog namespace, if so, I'm creating a new Stack Trace without them.

I'm using LibLog 4.2 + log4net

Thanks

Avoiding Allocations

Love the idea behind LibLog.

Would you be open to some changes to avoid unnecessary allocations when a particular log level isn't enabled?

public interface ILog
{
    // New
    IsTraceEnabled { get; }
    IsDebugEnabled { get; }
    IsInfoEnabled { get; }
    IsWarnEnabled { get; }
    IsErrorEnabled { get; }
    IsFatalEnabled { get; }
}
public static class LogExtensions
{
    public static void Debug(this ILog logger, string message)
    {
        GuardAgainstNullLogger(logger);
        if (logger.IsDebugEnabled) // Avoids allocating the func
        {
            logger.Log(LogLevel.Debug, () => message);
        }
    }

    // Provide overloads to avoid allocating the params object[] for a common number of arguments
    // and use generics to avoid boxing
    public static void DebugFormat<T>(this ILog logger, string message, T arg)
    {
        GuardAgainstNullLogger(logger);
        if (logger.IsDebugEnabled)
        {
            logger.Log(LogLevel.Debug, () => string.Format(CultureInfo.InvariantCulture, message, arg));
        }
    }

    public static void DebugFormat<T1, T2>(this ILog logger, string message, T1 arg1, T2 arg2)
    {
        GuardAgainstNullLogger(logger);
        if (logger.IsDebugEnabled)
        {
            logger.Log(LogLevel.Debug, () => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2));
        }
    }

    public static void DebugFormat<T1, T2, T3>(this ILog logger, string message, T1 arg1, T2 arg2, T3 arg3)
    {
        GuardAgainstNullLogger(logger);
        if (logger.IsDebugEnabled)
        {
            logger.Log(LogLevel.Debug, () => string.Format(CultureInfo.InvariantCulture, message, arg1, arg2, arg3));
        }
    }
}

CA1065 Analysis Issues

Running code analysis on a solution that is implementing LibLog is bringing up CA1065 because the internal classes (e.g. internal class SerilogLogger) is throwing an exception during static construction. According to the dialog:

'SerilogLogProvider.SerilogLogger.SerilogLogger()' creates an exception of type 'InvalidOperationException'. Exceptions should not be raised in this type of method. If this exception instance might be raised, change this method's logic so it no longer raises an exception.

Would it be better if we annotate the liblog code with a suppression for this exception, or is there a way to follow the suggestion here and refactor the static constructor to not need to throw an exception?

Remove the ConsoleLogger

LibLog's goal is to provide a simple logging abstract and support for several of the most popular loggers. Of course, all these loggers have console sinks. Does having a ColouredConsoleLoggerstep outside LibLog's remit? Should it, or should it not, be doing any actual output at all (Console, System.Diagnostics, etc)?

Does using OpenNestedContext/OpenMappedContext require explicit SetCurrentLogProvider() call?

I've noticed that both, OpenNestedContext() and OpenMappedContext(), return a no-op if CurrentLogProvider is null. The latter, however, only ever gets set by calling LogProvider.SetCurrentLogProvider() explicitly. Hence, if I've got code like the example from the Wiki in my library:

public class MyClass
{
    private static readonly ILog Logger = LogProvider.For<MyClass>(); 

    public MyClass()
    {
        using(LogProvider.OpenNestedContext("message"))
        using(LogProvider.OpenMappedContext("key", "value"))
        {
            Logger.Info(....);
        }
    }
}

... the OpenXXXContext calls are simply being ignored. I'm wondering now what the suggested usage pattern is. Am I supposed to put a line like this in some init code of my library?

LogProvider.SetCurrentLogProvider(LogProvider.ResolveLogProvider());

I would have expected that CurrentLogProvider was set implicitly the first time ResolveLogProvider() gets called. Am I completely misunderstanding something?

I've come across this when I was using a LibLog-enabled library from a log4net client which used a "[%property{NDC}]" conversion pattern - which, however, always returned "[(null)]" until I added the explicit call to SetCurrentLogProvider() above to the library.

If this is how I am supposed to use LibLog, that's okay, but I didn't find it very intuitive and think it should be documented.

SourceContext not outputing correctly in Serilog logger

When logging using Seirlog when outputting the $sourcecontext property in the output template its not replacingith correctly with the context

serilog is configured as per

        Log.Logger = New LoggerConfiguration() _
            .Enrich.With(New ThreadIdEnricher()) _
            .Enrich.FromLogContext _
            .Enrich.WithMachineName _
            .Enrich.WithProcessId _
            .MinimumLevel.Is(Events.LogEventLevel.Debug) _
            .WriteTo.ColoredConsole(outputTemplate:=logLayout) _
            .WriteTo.File(logFileName, outputTemplate:=logLayout) _
            .CreateLogger()

outputTemplate is

{Timestamp:HH:mm} [{Level}] ({ThreadId}) ({SourceContext})  {Message}{NewLine}{Exception}

the context should be there eg.

11:01 [Information] (8) (AIMIE.MaintenanceService.Program)  OnStart at 03/05/2015 11:01:37

Include F# port in same package

Porting to F# would make a nice up-for-grabs issue

surce packages that include n langs get the extra files added by default, but only those of languages that can be compiled within the current active project will end up as <Compile Include=" in the .project file so people typically don't go any further wrt separating out into e.g. having separate source packages per languages.

Ditto VB :P

Multiple log "sinks"

Not sure if anyone has come across this or not, but am wanting to provide the ability to direct the log output into multiple sinks (e.g. NLog and Elmah). Is there functionality to do this today, and if not, is there any way where we can provide the functionality? Is this even a concern of LibLog, or should this be owned/handled outside of the LibLog context?

Proposal - create a PCL version

I don't need this (yet) but if there is anyone out there who thinks they may need this leave a ๐Ÿ‘ In anycase, I have doubts that the reflection / dynamic stuff will work; if so, it would be of limited use.

Be notified when SetCurrentLogProvider is called.

The use case is that if you have a component B that uses LibLog but also has child components C & D (possibly ILMerged and internalized) that also use LibLog , if consumer A sets B's CurrentLogProvider, then B may wish to forward that LogProvider to C & D.

If C & D are using different versions of LibLog, B will need to adapt accordingly.

FormatException when message containes { } inside

given this message "Query language substitutions: {'true'='1', 'false'='0', 'yes'=''Y'', 'no'=''N''}" LogMessageFormatter.SimulateStructuredLogging throws format exception

I think its not a responsibility of a caller to escape {}. This line came from nhibernate. it was tested in 3.1 version.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.