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 22 posts 158 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 482 posts 627 karma points MVP c-trib
    19 days ago
    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 22 posts 158 karma points c-trib
    19 days ago
    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.

  • Vocko 1 post 71 karma points
    3 days ago
    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.

Please Sign in or register to post replies

Write your reply to:

Draft