12

I am using Serilog - RollingFile Sink, but it stores all data in a single file for a day. In my application, 1 GB log is written in a day. So I want to roll log file on the basis of date and size.

How can I configure RollingFile Sink to roll files based on date and size?

user1780538
  • 900
  • 3
  • 13
  • 22
  • Serilog does not support rolling when the file reaches a specific size. Rather, if the fileSizeLimitBytes is reached before the end of the day, logging will stop for that day. – Rob Davis Oct 03 '16 at 21:22
  • I have the same need and still looking for a solution. The alternative rolling sink posted by Caio does not appear to support multi-threading either. One possible workaround is to have your tool(s) break up the log file at the end or whatever interval you need. – GrayDwarf Aug 02 '17 at 16:25

7 Answers7

22

Nowadays Serilog.Sinks.RollingFile package is deprecated in favor of Serilog.Sinks.File (see the github project readme intro). Serilog.Sinks.File package has been upgraded to support file rolling. You can use the following Serilog config to enable rolling both by time and size:

"Serilog": {
    "Using": ["Serilog.Sinks.File"],
    "MinimumLevel": "Debug",
    "WriteTo": [
        {
            "Name": "File",
            "Args": {
                "path": "logs/log.txt",
                "rollingInterval": "Day",
                "rollOnFileSizeLimit": true,
                "fileSizeLimitBytes": "512",
                "retainedFileCountLimit": 3,
                "formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog"
            }
        }
    ]
  }

Then you will get something like this:

enter image description here

victorm1710
  • 1,263
  • 14
  • 11
3

From the documentation:

To avoid bringing down apps with runaway disk usage the rolling file sink limits file size to 1GB by default. The limit can be changed or removed using the fileSizeLimitBytes parameter.

.WriteTo.RollingFile("log-{Date}.txt", fileSizeLimitBytes: null)

The example shows removing the limit by setting it to null. In your case, set it to an appropriate size.

UPDATE

Yes, based on your comment I looked at the source code and it looks like the RollingFileSink's lowest unit of measure is a day so having more than one on the same day seems to be not supported. However, and I didn't look closely, it looks like the OpenFile methods in RollingFileSink.cs does something with sequence numbers. You might want to take a peek and see what that code is doing.

PatrickSteele
  • 14,489
  • 2
  • 51
  • 54
  • 3
    fileSizeLimitBytes ensures the size of the file. It means after reaching this limit logging will be stopped. New file is not created after reaching this limit. – user1780538 Oct 03 '16 at 13:20
1

I believe you're looking for this alternative implementation of the RollingFile sink:

Serilog Rolling File Sink (alternative)

This is a rolling file sink that allows you to specify roll over behaviour based on file size. https://github.com/BedeGaming/sinks-rollingfile

C. Augusto Proiete
  • 24,684
  • 2
  • 63
  • 91
  • It rolls file on size. e.g. if logger is initialized on 12-10-2016, it creates a new file but it uses the same file on 13-10-2016 until the file reaches specified size. I want to roll file on the basis of both date and size. I want to create a new file per day and when the file reaches specified size, a new file should be created with date and no. in the file name. e.g. Api-20161012-0002.log – user1780538 Oct 12 '16 at 18:15
1

In appsettings.json you should write something like that:

{
"Serilog": {

  "Using": ["Serilog.Sinks.File"],
  "MinumumLevel": {
    "Default": "Error",
    "Override": {
      //"Microsoft": "Warning",
      //"System": "Warning",  
      "Microsoft.AspNetCore.Authentication": "Verbose",
      "WebApplicationLogger1.Startup": "Warning",
      "WebApplicationLogger1.Pages": "Warning"
    }
  },
  "WriteTo": [
    {
      "Name": "RollingFile",
      "Args": {
        "rollingInterval": "Day",  // --> THIS IS THAT YOU NEED
        "pathFormat": "C:\\Logfiles\\File-{Date}.log",
        "restrictedToMinimumLevel": "Warning"   
      }
     }
   ],
  }
}
Aryan Firouzian
  • 1,940
  • 5
  • 27
  • 41
1

This is my solution

private readonly Serilog.ILogger _logger; //= Log.ForContext( "Name", "Weather" );

public WeatherForecastController() {
  string subPath = Path.Combine( DateTime.Now.ToString( "yyyy" ), DateTime.Now.ToString( "MM" ) ) + $"/{DateTime.Now.ToString("dd")}_Weather";
  _logger = Log.ForContext( "Name", subPath );
}

  .UseSerilog( ( hostingContext, loggerConfiguration ) => loggerConfiguration
    .ReadFrom.Configuration( hostingContext.Configuration )
    .Enrich.FromLogContext()
    .WriteTo.Console()
    .WriteTo.Map(
      "Name",
      "Request",
      ( name, wt ) => {
        if (name == "Request")
          wt.RollingFile( Path.Combine( $"{hostingContext.Configuration["LogPath"]}/{{Date}}-{name}.txt" ) );
        else
          wt.File( $"{hostingContext.Configuration["LogPath"]}/{name}.txt" );
      } )
  );   
Dharman
  • 30,962
  • 25
  • 85
  • 135
Garrod Ran
  • 318
  • 3
  • 5
  • I get the following: Error - CS1061 - 'LoggerSinkConfiguration' does not contain a definition for 'Map' and no accessible extension method 'Map' accepting a first argument of type 'LoggerSinkConfiguration' could be found (are you missing a using directive or an assembly reference?) – George 2.0 Hope Mar 13 '22 at 11:09
  • Where did you specify the size limit before rollover? – Markus Apr 06 '22 at 08:25
  • RollingFile is unknown. Can you paste a more complete code sample or include details of any additional packages that are needed? – Battlefury Sep 15 '22 at 10:57
  • builder.Host.UseSerilog( ( hostingContext, loggerConfiguration ) => loggerConfiguration .ReadFrom.Configuration( hostingContext.Configuration ) .Enrich.FromLogContext() .WriteTo.Console() .WriteTo.Map( "Name", "Request", ( name, wt ) => { if (name == "Request") wt.File( Path.Combine( $"{hostingContext.Configuration["LogPath"]}/Request/{name}.txt" ), rollingInterval: RollingInterval.Day ); else wt.File( $"{hostingContext.Configuration["LogPath"]}/{name}.txt" ); } ) ); – Garrod Ran Dec 09 '22 at 18:22
0

The current version also implements rolling hourly. That might be another solution to your ploblem.

{Hour} Creates a file per hour. Filenames use the yyyyMMddHH format.

like: .WriteTo.RollingFile("log-{Date}.Hour")

BennyBechDk
  • 934
  • 7
  • 13
0

My file still doesn't roll and I've followed all the setup instructions. I don't think this simple thing can be so hard to setup, can someone point out what I have wrong?

I have the latest of the following packages installed and my app runs on .Net Core 3.1:

  • Serilog.AspNetCore
  • Serilog.Enrichers.Environment
  • Serilog.Enrichers.Thread
  • Serilog.Settings.Configuration
  • Serilog.Sinks.Console
  • Serilog.Sinks.File
  • Serilog.Sinks.RollingFileAlternate

This is my code in Program.cs

public class Program
{
    // For Serilog docs refer to https://github.com/serilog/serilog-aspnetcore
    public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .Build();

    public static int Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .ReadFrom.Configuration(Configuration)
            .CreateLogger();

        try
        {
            Log.Information("Starting web host");
            CreateWebHostBuilder(args).Build().Run();
            return 0;
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host terminated unexpectedly");
            return 1;
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        return WebHost.CreateDefaultBuilder(args)
            .UseSerilog()
            //add configiration calling the method below
            .ConfigureAppConfiguration(SetupConfiguration)
            .UseStartup<Startup>();
    }

    public static void SetupConfiguration(WebHostBuilderContext ctx, IConfigurationBuilder builder)
    {
        //removing the default configuration options
        builder.Sources.Clear();

        builder.SetBasePath(ctx.HostingEnvironment.ContentRootPath)
               .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
               .AddJsonFile($"appsettings.{ctx.HostingEnvironment.EnvironmentName}.json", optional: true)
               .AddXmlFile("app.config");
    }
}

And here's my appsettings.config part:

"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
"MinimumLevel": "Information",
"WriteTo": [
  {
    "Name": "RollingFileAlternate",
    "Args": { "path": "../Logs/MyLog_dev.log" },
    "RollingInterval": "RollingInterval.Day",
    "RetainedFileCountLimit": 20,
    "fileSizeLimitBytes": 1000000,
    "rollOnFileSizeLimit": true
  }
],
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
Ninos
  • 224
  • 4
  • 18