Reputation: 20017
I am trying to implement SeriLog in ASP.NET core application (.NET framework)
Below are steps I performed so far-
1) Added below references in Project.json
"Serilog": "2.2.0",
"Serilog.Extensions.Logging": "1.2.0",
"Serilog.Sinks.RollingFile": "2.0.0",
"Serilog.Sinks.File": "3.0.0"
2) Added following lines to the constructor of your Startup class-
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.RollingFile(Path.Combine(env.ContentRootPath, "log-{Date}.txt"))
.CreateLogger();
3) Added following line to the configure method of your Startup class-
loggerFactory.AddSerilog();
4) Injecting the logger to HomeController like this-
ILogger logger;
public HomeController(ILogger logger)
{
this.logger = logger;
}
5) In About action, trying to log exception like this-
public IActionResult About()
{
ViewData["Message"] = "Your application description page.";
try
{
throw new Exception("Serilog Testing");
}
catch (System.Exception ex)
{
this.logger.Error(ex.Message);
}
return View();
}
On running my application, I am getting below error-
System.InvalidOperationException: Unable to resolve service for type 'Serilog.ILogger' while attempting to activate 'AspNetCore_SeriLog_trial1.Controllers.HomeController'. at Microsoft.Extensions.Internal.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method(Closure , IServiceProvider , Object[] ) at Microsoft.AspNetCore.Mvc.Internal.TypeActivatorCache.CreateInstance[TInstance](IServiceProvider serviceProvider, Type implementationType) at Microsoft.AspNetCore.Mvc.Controllers.DefaultControllerActivator.Create(ControllerContext controllerContext) at Microsoft.AspNetCore.Mvc.Controllers.DefaultControllerFactory.CreateController(ControllerContext context) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__26.MoveNext()
Could anyone please help me on this? Any configuration missing for Serilog?
Upvotes: 39
Views: 51771
Reputation: 1
My(!) Simplest solution for NET7.0 using the recommended Host.CreateApplicationBuilder(args); MS Learn: Worker services in .Net
NuGetPackages:
public static void Main(string[] args)
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console(LogEventLevel.Information)
.WriteTo.File(path:"logs/Dummylog-.txt",rollingInterval:RollingInterval.Day)
.CreateLogger();
var builder = Host.CreateApplicationBuilder(args);
var services = builder.Services;
builder.Logging.ClearProviders();
services.AddSerilog(Log.Logger)
.AddHostedService<Worker>();
IHost host = builder.Build();
host.Run();
}
in the Service i injected the Serilog(!).ILogger MS also has a ILogger interface, i could just write a using , but was lazy
private readonly Serilog.ILogger _logger;
public Worker(Serilog.ILogger logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.Information("Worker running at: {time}", DateTimeOffset.Now);
await Task.Delay(1000, stoppingToken);
}
}
}
Upvotes: 0
Reputation: 2453
I know this is an old Question, but I just ran into this problem and found a different solution.
I switched out Microsoft.Extensions.Logging
for Serilog
, but I missed removing it from the constructor parameter list.
public HomeController(IIdentityServerInteractionService interaction, IWebHostEnvironment environment, ILogger logger)
Once I removed that parameter, the error disappeared.
public HomeController(IIdentityServerInteractionService interaction, IWebHostEnvironment environment)
It looks like the OP was trying to inject the logger through the constructor, but instead should have created a specific logger for that controller. You can also make it static
so there's only 1 creation of the logger for every time this project runs, instead of 1 for every instance of the class.
public class HomeController : Controller
{
private static readonly ILogger Logger = Log.ForContext<HomeController>();
...
public HomeController(IIdentityServerInteractionService interaction, IWebHostEnvironment environment)
{
...
}
...
}
Apparently, what's happening is that the compiler tries to give the constructor a Microsoft.Extensions.Logging
logger by default, instead of trying to match the Serilog
logger the constructor is actually expecting, so that's where the error comes from.
Upvotes: -1
Reputation: 1289
If you need to use ILogger
(from Serilog
) instead of ILogger<HomeController>
(from Microsoft.Extensions.Logging
), you can register ILogger
on your Startup class:
services.AddSingleton(Log.Logger);
Upvotes: 49
Reputation: 39
I was getting this issue "unable to resolve service for type 'interface_name' while attempting to activate 'Controller_Name' ....
By adding the below line in startup.cs I have resolved the same:
services.AddScoped<interface_name, Controller_Name>();
Upvotes: -1
Reputation: 3031
Which of the following two lines do you have in your controller?
using Serilog;
using Microsoft.Extensions.Logging;
If it's the former (using Serilog;
) then that's probably your problem.
When you register the service, you're essentially saying "When a constructor asks for an Microsoft.Extensions.Logging.ILogger, pass them a Serilog instance because I'm using Serilog for my logging", but then in your constructor you aren't asking for Microsoft.Extensions.Logging.ILogger, you're asking for Serilog.ILogger and your application is getting confused, because you haven't defined an service to be injected for Serilog.ILoger
, you've defined one for Microsoft.Extensions.Logging.ILogger
Remember that you are implementing Microsoft's ILogger interface: your constructor doesn't need to know that you're using Serilog... in fact, you don't want it to! The entire point is that you can swap Serilog out for a different logger at any time without having to change your code.
Change using Serilog;
to using Microsoft.Extensions.Logging;
in your constructor, and you'll be requesting the correct service type
Upvotes: 15
Reputation: 1257
You missed to inject your interface in the controller constructor:
ILogger<HomeController> logger = null;
public HomeController(ILogger<HomeController> _logger)
{
logger = _logger;
}
In the Program.cs you have to add UseSerilog also:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseSerilog();
Upvotes: 0
Reputation: 17485
Try to do following thing in your controller.
ILogger<HomeController> logger = null;
public HomeController(ILogger<HomeController> _logger)
{
logger = _logger;
}
Upvotes: 42