Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Adam Nelson 27 posts 186 karma points c-trib
    Jul 04, 2019 @ 05:34
    Adam Nelson
    0

    Bug with Current.Logger - or maybe I'm using it wrong

    Hey folks,

    I'm trying to use Current.Logger, but everywhere I try it it's wired up to an instance of DebugDiagnostics Logger, which doesn't write to serilog.

    Consider the following code:

    UserComposer.cs

    using LightInject;
    using Umbraco.Core;
    using Umbraco.Core.Composing;
    using Umbraco.Core.Logging;
    using Umbraco.Web;
    using Umbraco.Web.Routing;
    
    [RuntimeLevel(MinLevel = RuntimeLevel.Run)]
    public class MyUserComposer : IUserComposer
    {
        /* Can't use injection inside composers - they need a parameterless constructor
        private readonly ILogger _logger;
        public MyUserComposer(ILogger logger)
        {
            _logger = logger;
        } */
    
        public void Compose(Composition composition)
        {
            composition.ContentFinders().InsertBefore<ContentFinderByUrl, MyContentFinder>();
            composition.Components().Append<MyComponent>();
    
            // Does not log to serilog - goes to DebugDiagnosticsLogger
            Current.Logger.Info<MyUserComposer>("LOGGING: Composer using Current.Logger");
    
            // System.InvalidOperationException: No factory has been set
            // Current.Factory.GetInstance<IProfilingLogger>().Info<MyUserComposer>("LOGGING: Composer using Current.Factory.GetInstance"); 
    
            // Umbraco.Core.Exceptions.BootFailedException: Boot failed.
            // System.InvalidOperationException: Unable to resolve type: Umbraco.Core.Logging.IProfilingLogger, service name: 
            // var container = composition.Concrete as LightInject.ServiceContainer;
            // container.GetInstance<IProfilingLogger>().Info<MyUserComposer>("LOGGING: Composer using LightInject container.GetInstance"); 
    
            // System.InvalidOperationException: Unable to resolve type: Umbraco.Core.Logging.ILogger, service name: 
            // container.GetInstance<ILogger>().Info<MyUserComposer>("LOGGING: Composer using LightInject container.GetInstance"); 
        }
    }
    

    MyContentFinder.cs

    using Umbraco.Core.Composing;
    using Umbraco.Core.Logging;
    using Umbraco.Web.Routing;
    
    public class MyContentFinder : IContentFinder
    {
        private readonly ILogger _logger;
    
        public MyContentFinder(ILogger logger)
        {
            _logger = logger;
        }
    
        public bool TryFindContent(PublishedRequest request)
        {
            // Does not log to serilog - goes to DebugDiagnosticsLogger
            Current.Logger.Info<MyContentFinder>("LOGGING: ContentFinder TryFindContent() using Current.Logger");
    
            // Logs correctly
            _logger.Info<MyContentFinder>("LOGGING: ContentFinder TryFindContent() using constructor injected logger");
    
            return false;
        }
    }
    

    MyComponent.cs

    using Umbraco.Core.Composing;
    using Umbraco.Core.Logging;
    
    public class MyComponent : IComponent
    {
        private readonly ILogger _logger;
    
        public MyComponent(ILogger logger)
        {
            _logger = logger;
        }
    
        public void Initialize()
        {
            // Does not log to serilog - goes to DebugDiagnosticsLogger
            Current.Logger.Info<MyComponent>("LOGGING: component Initialize() using Current.Logger");
    
            // Logs correctly
            _logger.Info<MyComponent>("LOGGING: component Initialize() using constructor injected logger");
        }
    
        public void Terminate()
        {
            // Does not log to serilog - goes to DebugDiagnosticsLogger
            Current.Logger.Info<MyComponent>("LOGGING: component Terminate() using Current.Logger");
    
            // Logs correctly
            _logger.Info<MyComponent>("LOGGING: component Terminate() using constructor injected logger");
        }
    }
    

    All I get logged from the above is:

    LOGGING: component Initialize() using constructor injected logger

    LOGGING: ContentFinder TryFindContent() using constructor injected logger

    In all cases whenever I try to use Current.Logger it's wired up to DebugDiagnosticsLogger and not serilog. And I can't get an instance of IProfilingLogger or ILogger from the LightInject in my composer.

    The reason I'm trying to access ILogger in a composer is so I can register a third party service that accepts its own kind of logging (ILogging for example) in its constructor and I can satisfy that with a simple adaptor that takes an ILogger but implements ILogging and calls through to the Umbraco logger.

    For example, trying to register IThirdPartyService where the concrete implementation takes an instance of their custom ILogging interface:

    composition.Register<ILogging>(f => new MyLoggingAdaptor(f.GetInstance<ILogger>()));
    composition.Register<IThirdPartyService>(f => new ThirdPartyService(Current.Factory.GetInstance<ILogger>());
    
    public class MyLoggingAdaptor : ILogging
    {
        private readonly ILogger _logger;
    
        public MyLoggingAdaptor(ILogger logger)
        {
            _logger = logger;
        }
    
        public void WriteInfoMessage(string message)
        {
            _logger.Info<MyLoggingAdaptor>(message);
        }
    }
    

    Is this a bug?

    Thanks, Adam.

  • Heather Floyd 603 posts 1001 karma points MVP 5x c-trib
    Aug 26, 2019 @ 23:12
    Heather Floyd
    0

    Hi Adam!

    Did you ever figure out what was going on? I'm not trying to do anything wild with Logging, but I've found that when I use "Current.Logger" in my custom code, my messages just aren't showing up via the back-office "Log Viewer".

    ~Heather

  • Adam Nelson 27 posts 186 karma points c-trib
    Aug 26, 2019 @ 23:24
    Adam Nelson
    0

    Hi Heather,

    No I didn't find a solution for Current.Logger. You can use constructor injection in your controller (if it's a controller you're writing) to pass in an instance of ILogger which you can log with:

    using Umbraco.Core.Logging;
    
    public class YourController : RenderMvcController
    {
        private readonly ILogger _logger;
    
        public YourController(ILogger logger)
        {
            _logger = logger;
        }
    
        ..your code..
    }
    

    Umbraco will then pass in an instance of ILogger when it constructs your controller using LightInject. Hope that helps.

    Cheers, Adam.

  • Heather Floyd 603 posts 1001 karma points MVP 5x c-trib
    Oct 19, 2019 @ 18:13
    Heather Floyd
    0

    Thanks, Adam. Your posts really helped me to understand better why my custom logs weren't working.

    I feel that unless the Logger is explicitly changed by the developer, Current.Logger should be of type {Umbraco.Core.Logging.Serilog.SerilogLogger}

    I've added an issue here: https://github.com/umbraco/Umbraco-CMS/issues/6774 if you'd like to comment.

  • Vocko 1 post 71 karma points
    Sep 12, 2019 @ 04:13
    Vocko
    0

    I have the same problem, trying to use Current.Logger doesn't produce any (custom) log records. The standard Umbraco logging seems to go through.

    Using Umbraco 8.1.2.

    composition.RegisterFor<IMyService, MyService>(new MyService(new UmbracoLogWrapper(Current.Logger)));
    

    When using the UmbracoLogWrapper instance in the service, call goes through fine, however, log file remains empty.

  • Jeff Nelson 1 post 71 karma points
    May 06, 2020 @ 03:41
    Jeff Nelson
    0

    I ran into this issue also. It seems that during the lifecycle when the compose method is hit the wrong logger is registered with DI. You can get around this by accessing Serilog directly.

    enter image description here

  • Mike Chambers 635 posts 1252 karma points c-trib
    Jan 18, 2021 @ 18:26
    Mike Chambers
    1

    Using 8.10.1 composition.Logger seems to work.

    public void Compose(Composition composition)
    {
         composition.Logger.Warn<Startup>("Some Message");      
    }
    

    Not sure what version this may have worked from...

Please Sign in or register to post replies

Write your reply to:

Draft