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);
}
}
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".
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.
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.
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
MyContentFinder.cs
MyComponent.cs
All I get logged from the above is:
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:
Is this a bug?
Thanks, Adam.
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
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:
Umbraco will then pass in an instance of ILogger when it constructs your controller using LightInject. Hope that helps.
Cheers, Adam.
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.
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.
When using the UmbracoLogWrapper instance in the service, call goes through fine, however, log file remains empty.
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.
Using 8.10.1 composition.Logger seems to work.
Not sure what version this may have worked from...
is working on a reply...