Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Logging Serilog在达到最大文件大小之前创建文件_Logging_Asp.net Core 2.1_Serilog - Fatal编程技术网

Logging Serilog在达到最大文件大小之前创建文件

Logging Serilog在达到最大文件大小之前创建文件,logging,asp.net-core-2.1,serilog,Logging,Asp.net Core 2.1,Serilog,我使用.NETCore2.1创建了一个API,并使用Serilog在API级别记录所有方法类型的每个响应和请求:Get、Post。。。尽管有响应代码;下面是添加到中间件类的代码: var request = context.Request; var stopWatch = Stopwatch.StartNew(); var requestTime = DateTime.UtcNow; var requestBodyContent = await ReadRequestBo

我使用.NETCore2.1创建了一个API,并使用Serilog在API级别记录所有方法类型的每个响应和请求:Get、Post。。。尽管有响应代码;下面是添加到中间件类的代码:

var request = context.Request;
    var stopWatch = Stopwatch.StartNew();
    var requestTime = DateTime.UtcNow;
    var requestBodyContent = await ReadRequestBody(request);
    var originalBodyStream = context.Response.Body;
    generalError = Configuration["generalError"];

        using (var memStream = new MemoryStream())
        {
            HttpResponse response = context.Response;
            response.Body = memStream;
            await next(context);
            stopWatch.Stop();

            string responseBodyContent = null;
            responseBodyContent = ReadResponseBody(memStream);
            memStream.CopyTo(originalBodyStream);

            string infoToLog = "\r\n" +
                               "------------------------ \r\n" +
                               "Elapsed Milliseconds: " + stopWatch.ElapsedMilliseconds + "\r\n" +
                               "Status Code: " + context.Response.StatusCode + "\r\n" +
                               "Method: " + request.Method + "\r\n" +
                               "Path: " + request.Path + "\r\n" +
                               "QueryString: " + request.QueryString.ToString() + "\r\n" +
                               "Request Body: " + requestBodyContent + "\r\n" +
                               "Response Body: " + responseBodyContent + "\r\n" +
                               "------------------------" + "\r\n\r\n";

            Log.Logger = new LoggerConfiguration()
                .WriteTo.Async(a => a.File("Logs/myapp.log",
                          rollOnFileSizeLimit: true,                                  
                          fileSizeLimitBytes: Convert.ToInt32(Configuration["MaxLogFileSize"])))
                            //shared:true,
                .CreateLogger();

            if (context.Response.StatusCode == 200)
            {
                Log.Information(infoToLog);                        
            }
            else {
                Log.Error(infoToLog);                        
            }

            Log.CloseAndFlush();

            context.Response.Body = originalBodyStream;
        }
如您所见,我实现了一种滚动日志记录方法,该方法仅在达到最大文件大小问题后创建新文件。
主要问题是,发布后,当API从移动应用程序调用时,我们意识到许多日志文件是同时创建的,而没有达到最大文件大小,更具体地说,当多个方法应该同时记录时。我们能解决这个问题吗

您正在中间件中的每个webrequest上实例化一个新的记录器,我认为您也在使用
log.CloseAndFlush()关闭日志文件,当我认为如果我回忆起文档,它应该是一个单例

根据我的记忆,您只需要在应用程序引导期间创建记录器。我就是这样做的(program.cs with.NET core 2.2):

公共类程序
{
私有静态只读字符串_applicationName=System.Reflection.Assembly.GetEntryAssembly().GetName().Name;
公共静态IConfiguration配置=新配置生成器()
.SetBasePath(目录.GetCurrentDirectory())
.AddJsonFile(“appsettings.json”,可选:true,重载更改:true)
.AddJsonFile($“appsettings.{Environment.GetEnvironmentVariable(“ASPNETCORE_Environment”)}.json),重载更改:true,可选:true)
.AddenEnvironmentVariables()
.Build();
公共静态int Main(字符串[]args)
{
//塞里洛格
Logger.Logger=新的LoggerConfiguration()
.ReadFrom.Configuration(配置)
.Enrich.FromLogContext()的
.CreateLogger();
尝试
{
if(string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable(“ASPNETCORE_Environment”))
抛出新异常(“未设置宿主环境变量”);
Log.Information($“引导应用程序:{u applicationName}”);
CreateWebHostBuilder(args.Build().Run();
Log.Information($“优雅地关闭应用程序:{u applicationName}”);
返回0;//返回0,表示成功关机。
}
捕获(例外e)
{
警告($“主机{u应用程序名}-意外终止。”);
日志。致命(e.Message);
return 1;//返回none零表示失败。
}
最后
{
Log.CloseAndFlush();
}
}
公共静态IWebHostBuilder CreateWebHostBuilder(字符串[]args)=>
WebHost.CreateDefaultBuilder(args)
.UseStartup()
.UseConfiguration(配置)
.useserlog();
}
因此,当您确实想记录一些东西时,只需使用Serilog导入
并调用
Log.Information(“您的消息”)

更多信息请参见:的底部或

编辑

这是我的配置,将console指定为sink(您也可以添加更多类似文件、elasticsearch、seq…其他),我还覆盖了Microsofts的默认记录器,只显示日志级别或更高级别的警告:

  "Serilog": {
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "System": "Warning"
      }
    },  
    "WriteTo": [
      {
        "Name": "Console",
        "Args": {
          "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss} {Level:u3}] {Message:lj} {SourceContext}>{NewLine}{Exception}"
        }
      }
    ]
  },
更新

那么,您将日志放在教程中说的
//TODO:Save log to selected datastore
(将日志保存到所选数据存储)的位置,这在serilog术语中只是指
log.Information(“您的消息”)。在我的示例中,我已经用
//serilog
标记了serilog部分-因此,如果您想将记录器配置为也记录到文件中,只需将您的配置部分添加到该文件中,就像您的配置部分一样:

//serilog
Logger.Logger=新的LoggerConfiguration()
.ReadFrom.Configuration(配置)
.Enrich.FromLogContext()的
.WriteTo.Async(a=>a.File(“Logs/myapp.log”,
rollOnFileSizeLimit:是的,
fileSizeLimitBytes:Convert.ToInt32(配置[“MaxLogFileSize”]))
.CreateLogger();
您还可以通过使用
appsettings.json
-进行配置来添加该部分,如果您不想使用该部分
.ReadFrom.configuration(configuration).exprich.FromLogContext()
只需将其删除即可

因此,您的中间件代码如下所示:

var-request=context.request;
var stopWatch=stopWatch.StartNew();
var requestTime=DateTime.UtcNow;
var requestBodyContent=await ReadRequestBody(请求);
var originalBodyStream=context.Response.Body;
generalError=配置[“generalError”];
使用(var memStream=new MemoryStream())
{
HttpResponse response=context.response;
response.Body=memStream;
等待下一个(上下文);
秒表;
字符串responseByContent=null;
responseBodyContent=ReadResponseBody(memStream);
memStream.CopyTo(originalBodyStream);
字符串infoToLog=“\r\n”+
“---------------------------\r\n”+
已用毫秒数:“+stopWatch.ElapsedMilliseconds+”\r\n+
状态代码:“+context.Response.StatusCode+”\r\n+
方法:“+请求。方法+”\r\n+
路径:“+请求。路径+”\r\n+
QueryString:“+request.QueryString.ToString()+”\r\n+
请求正文:“+requestBodyContent+”\r\n+
响应正文:“+ResponseByContent+”\r\n+
"---------------