这是我的控制器:
public class BlogController : Controller
{
private IDAO<Blog> _blogDAO;
private readonly ILogger<BlogController> _logger;
public BlogController(ILogger<BlogController> logger, IDAO<Blog> blogDAO)
{
this._blogDAO = blogDAO;
this._logger = logger;
}
public IActionResult Index()
{
var blogs = this._blogDAO.GetMany();
this._logger.LogInformation("Index page say hello", new object[0]);
return View(blogs);
}
}
Run Code Online (Sandbox Code Playgroud)
如你所见,我有2个依赖项,a IDAO和aILogger
这是我的测试类,我使用xUnit来测试和Moq来创建mock和stub,我可以DAO轻松模拟,但是ILogger我不知道该怎么做所以我只是传递null并注释掉调用登录控制器当跑步测试.有没有办法测试,但仍然以某种方式保持记录器?
public class BlogControllerTest
{
[Fact]
public void Index_ReturnAViewResult_WithAListOfBlog()
{
var mockRepo = new Mock<IDAO<Blog>>();
mockRepo.Setup(repo => repo.GetMany(null)).Returns(GetListBlog());
var controller = new BlogController(null,mockRepo.Object);
var result = controller.Index(); …Run Code Online (Sandbox Code Playgroud) 我已经更新了原来问题的内容,因为我开始在试图帮助我的人们中引起一些困惑。
我正在使用库“Microsoft.ApplicationInsights.AspNetCore”将日志发送到Azure。使用该库的挑战之一是,在为该库创建服务之前,它不会向 Azure 发送任何日志事件。
先有鸡还是先有蛋的情况是,我需要在 Net Core 6 Web 应用程序启动过程的最早阶段(即在 App Insights 需要运行的服务实际创建之前)写入日志并将其发送到 Azure。
我需要在应用程序启动过程的早期阶段写入日志的原因是捕获用户登录的详细信息,其中一旦 .Net Core 应用程序启动,就会弹出 Microsoft 登录页面。
在下面的代码示例中,您可以看到我创建了记录器工厂的实例,以便我可以在构建和启动其余服务之前在program.cs文件中本地写入一些日志。尽管使用此方法适用于写入控制台,但不会将任何事件发送到 App Insights。我认为这是因为在创建所需的服务(位于program.cs 文件的后期阶段)之前,应用程序见解库尚未建立。
var builder = WebApplication.CreateBuilder(args);
// I create an instance of logger factory
using var loggerFactory = LoggerFactory.Create(loggingBuilder => loggingBuilder
.SetMinimumLevel(LogLevel.Trace)
.AddConsole()
.AddApplicationInsights(builder.Configuration["APPINSIGHTS_CONNECTIONSTRING"]));
// I use the logger factory to create an instance of Ilogger
ILogger logger = loggerFactory.CreateLogger<Program>();
// This code section here is related to Microsoft Identity Web library and is responsible for
// triggering …Run Code Online (Sandbox Code Playgroud) 由于最近引入了 Program.cs 启动代码的新结构,该文档让我有点困惑。
在官方提供的Serilog.AspNetCore示例和示例Serilog.Sentry中,他们使用.UseSerilog()了WebHostBuilder. 我找不到这个方法。
这是我尝试过的:
using Serilog;
var builder = WebApplication.CreateBuilder(args);
// adding services...
builder.Logging.AddSerilog(); // <- is this even necessary?
var app = builder.Build();
app.UseSerilogRequestLogging();
// configure request pipeline
app.Run();
Run Code Online (Sandbox Code Playgroud)
但是如何/在哪里配置接收器,例如调试、控制台、哨兵……?我觉得文档有点过时,或者我只是有点盲目。
我已经使用 Host 创建了一个 .NET Core 3.1 项目,IoC 容器IServiceCollection使用ILogger<T>来自Microsoft.Extensions.Logging. 我现在需要实现更高级的日志记录并决定使用 Serilog。
我认为从 .NET 内置记录器切换到 Serilog 会轻而易举。但令我惊讶的是,Serilog 正在使用它自己的ILogger界面——太糟糕了!所以现在我需要更新所有地方以使用 Serilog ILogger,或者使用 .NET CoreILogger<T>接口实现 Serilog 。
我的问题是 - 真的不可能将 Serilog 与 ILogger 接口一起使用Microsoft.Extensions.Logging吗?会聪明很多!
我已经Main像这样配置了控制台应用程序
var services = new ServiceCollection()
.AddLogging(logging => logging.AddConsole())
.BuildServiceProvider();
Run Code Online (Sandbox Code Playgroud)
然后我尝试在另一个类中使用它
private readonly ILogger _logger;
public MyClass(ILogger logger)
{
_logger = logger;
}
public void MyFunc()
{
_logger.Log(LogLevel.Error, "My Message");
}
Run Code Online (Sandbox Code Playgroud)
System.InvalidOperationException:'无法解析类型为'Microsoft.Extensions.Logging.ILogger的服务'
根据以下Yaakov的评论和Github的评论进行编辑,我能够通过此操作正确解决它
public MyClass(ILogger<MyClass> logger)
{
_logger = logger;
}
Run Code Online (Sandbox Code Playgroud)
我本来希望在初始时使用它,BuildServiceProvider但看起来每次要使用记录器(或创建自己的ILogger)时都必须重复此操作。
我在 .NET Core 3.1 辅助服务应用程序中使用 NLog。按照 NLog 的教程,我插入了一个 nlog.config 文件来管理配置。
现在我很困惑,因为我有三点配置日志记录:
在我需要在依赖注入上下文中创建记录器的代码中
// Other code...
services.AddScoped<IApplyJcdsCommandsJob, ApplyJcdsCommandsJob>(provider =>
{
var loggerFactory = LoggerFactory.Create(builder =>
{
builder
.ClearProviders()
.AddFilter("Microsoft", Microsoft.Extensions.Logging.LogLevel.Trace)
.AddFilter("System", Microsoft.Extensions.Logging.LogLevel.Trace)
.AddFilter("ApplyJcdsCommandsJob", Microsoft.Extensions.Logging.LogLevel.Trace)
//.AddConsole()
//.AddEventLog();
.AddNLog(configuration);
});
Microsoft.Extensions.Logging.ILogger logger = loggerFactory.CreateLogger<CommandsJob>();
return new CommandsJob(logger);
})
// Other code...
Run Code Online (Sandbox Code Playgroud)
在 appSettings.json 中
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Trace",
"System": "Trace",
"Microsoft": "Trace"
}
}
}
Run Code Online (Sandbox Code Playgroud)
在 NLog.config 中
nuget 包安装生成的默认配置文件:
<!-- a section of the config -->
<targets> …Run Code Online (Sandbox Code Playgroud)我使用 vs 2019 作为控制台应用程序(dotnet core 3.1),
Install-Package Microsoft.Extensions.Logging.Console -Version 3.1.2
Run Code Online (Sandbox Code Playgroud)
和这段代码:
using Microsoft.Extensions.Logging;
class Program
{
static void Main(string[] args)
{
var loggerFactory = LoggerFactory.Create(builder =>
{
builder
.AddFilter("Microsoft", LogLevel.Information)
.AddFilter("System", LogLevel.Information)
.AddFilter("TestRx.Program", LogLevel.Information)
.AddConsole();
});
ILogger logger = loggerFactory.CreateLogger<Program>();
logger.LogInformation("Example log message");
}
}
Run Code Online (Sandbox Code Playgroud)
它在控制台上没有打印任何内容,为什么?
我正在为自己做一个有趣的项目来学习 blazor、很多核心概念和一般实践。
我正在尝试为 FakeItEasy 实现记录器扩展,以更轻松地测试 Microsoft 的 ILogger。基于https://dev.azure.com/BrideButler/Bride%20Butler%20Open%20Source/_git/FakeItEasy.DotnetCore.LoggerExtensions?path=%2FFakeItEasy.DotnetCore.LoggerExtensions%2FLoggerExtensions.cs但现在尝试让它工作对于.NET 5。现在这FormattedLogValues是内部的,这段代码不再起作用。
目标是在我的测试中拥有类似的东西(而不是使用 Moq),
_logger.VerifyLog(LogLevel.Information, "Get Weather Called").MustHaveHappenedOnceExactly();
或者A.CallTo(() => _logger.Log(LogLevel.Information, "Get Weather Called").MustHaveHappenedOnceExactly();它不必有语法糖,但我想让它与 FakeItEasy 而不是 Moq 一起使用。
以下是所有涉及的代码。当然,我在第一行Microsoft.Extensions.Logging.ILogger.Log1[System.Object] vsMicrosoft.Extensions.Logging.ILogger 1[Server.Controllers.WeatherForecastController].Log1[Microsoft.Extensions.Logging.FormattedLogValues]` 中看到了一些差异,但我不知道如何“修复”这个问题,因为我不完全理解出了什么问题。
我的问题显然是,我应该做什么来解决它,但也很好奇我缺少什么部分。
我的错误如下:
Assertion failed for the following call:
Microsoft.Extensions.Logging.ILogger.Log`1[System.Object]
(
logLevel: Information,
eventId: <Ignored>,
state: <e => e.ToString().Contains(value(Server.Tests.Extensions.LoggerExtensions+<>c__DisplayClass2_0`1[Server.Controllers.WeatherForecastController]).message)>,
exception: <Ignored>,
formatter: <Ignored>
)
Expected to find it once exactly but didn't find it among the calls:
1: Microsoft.Extensions.Logging.ILogger`1[Server.Controllers.WeatherForecastController].Log`1[Microsoft.Extensions.Logging.FormattedLogValues]
(
logLevel: Information, …Run Code Online (Sandbox Code Playgroud) 我创建了一个简单的 Serilog 接收器项目,如下所示:
namespace MyApp.Cloud.Serilog.MQSink
{
public class MessageQueueSink: ILogEventSink
{
private readonly IMQProducer _MQProducerService;
public MessageQueueSink(IMQProducer mQProducerService)
{
_MQProducerService = mQProducerService;
}
public void Emit(LogEvent logEvent)
{
_MQProducerService.Produce<SendLog>(new SendLog() { LogEventJson = JsonConvert.SerializeObject(logEvent)});
}
}
}
Run Code Online (Sandbox Code Playgroud)
消费微服务的启动方式如下:
var configurationBuilder = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
var appSettings = configurationBuilder.Get<AppSettings>();
configurationBuilder = new ConfigurationBuilder().AddJsonFile("ExtendedSettings.json").Build();
Host.CreateDefaultBuilder(args)
.UseMyAppCloudMQ(context => context.UseSettings(appSettings.MQSettings))
.UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration))
.ConfigureServices((hostContext, services) =>
{
services
.AddHostedService<ExtendedProgService>()
.Configure<MQSettings>(configurationBuilder.GetSection("MQSettings"))
})
.Build().Run();
Run Code Online (Sandbox Code Playgroud)
appsettings.json 的 serilog 部分如下所示:
"serilog": {
"Using": [ "Serilog.Sinks.File", "Serilog.Sinks.Console", "MyApp.Cloud.Serilog.MQSink" ], …Run Code Online (Sandbox Code Playgroud) 我在 .net 框架项目中使用 Microsoft.Extensions.Logging 中的 ILogger。现在我想在容器中注册 ILogger 但我不能。所有答案都是关于 .net core 的。我尝试
var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
//first try
builder.RegisterGeneric(typeof(Logger<>)).As(typeof(ILogger<>));
IServiceCollection services = new ServiceCollection();
//second try
services.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
IContainer container = builder.Build();
httpConfig.DependencyResolver = new AutofacWebApiDependencyResolver(container);
Run Code Online (Sandbox Code Playgroud)
我的班级也是
public class TestController : ApiController
{
private readonly ILogger<TestController > _logger;
private readonly IService _service;
public TestController (IService service, ILogger<TestController > logger)
{
_service = service;
_logger = logger;
}
}
Run Code Online (Sandbox Code Playgroud)
di 是正确的,因为其他服务已注入正确的。当我在构造函数中包含记录器时,我收到消息尝试创建“TestController”类型的控制器时发生错误。确保控制器具有无参数公共构造函数。