Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Roll on year/month/day/hour/minute, on file size, or on a combination of both #35

Merged
merged 20 commits into from
Oct 16, 2017

Conversation

nblumhardt
Copy link
Member

@nblumhardt nblumhardt commented Oct 13, 2017

Fixes serilog/serilog-sinks-rollingfile#33, Fixes serilog/serilog-sinks-rollingfile#52.

This PR introduces some additional parameters to WriteTo.File().

First, rollOnFileSizeLimit, causes additional log files to be created when the file size limit is reached. E.g.:

    .WriteTo.File("log.txt", rollOnFileSizeLimit: true)

will roll the file from log.txt to log_001.txt, log_002.txt and so-on when fileSizeLimitBytes is reached (the default is 1 GB). Old files will be cleaned up as per retainedFileCountLimit - the default is 31.

A second parameter, rollingInterval, rolls the file by RollingInterval.Year, Month, Day, Hour or Minute into log20180101.txt, log20180102.txt and so on.

    .WriteTo.File("log.txt", rollingInterval: RollingInterval.Hour)

If neither parameter is supplied, the behavior is exactly as before - the file name is static and no additional files will ever be created.

If both parameters are specified, the first file for a rolling interval will be named like log20180101.txt, rolling into log20180101_001.txt, log20180101.txt_002.txt and so on, until the next interval when the counter resets.

If either parameter is supplied, and the log file can't be opened, the suffix _NNN will be appended to find a filename that is available.

Goals

  • Address the need for roll-on-size
  • Bring the code for RollingFileSink into the same package as FileSink so that they can be extended and refactored in future (e.g. for many of the other long-standing items in https://github.com/serilog/serilog-sinks-rollingfile/issues)
  • Simplify the user experience (most users find File first, but really want RollingFile - very few apps use File
  • Move away from -{Date} path templates - they're misleading, as formatting information is not supported, and the placeholder can only appear in a very limited portion of the path
  • Re-use the rolling file sink code to get things unblocked quickly; the port to the new rolling scheme was very direct - where given the choice, I made the existing patterns work instead of introducing new code
  • Update to VS2017 tooling

Non-goals

  • Introduce much more flexibility - the combined codebases need some attention before adding code
  • Replace Serilog.Sinks.RollingFile - new apps should move to File, but there's no reason existing apps should move if the functionality over there is satisfactory

Breaking changes/evolution

  • The *Sink classes added in this PR are internal; the existing ones like FileSink are now marked [Obsolete] so that they too can become internal in a far-future release, to support some refactoring and improvement of the architecture
  • The default output template has been modernized with :u3 short level names and :lj message formatting (this is the reason for the major version bump)

I'm sure I'll think of more :-)

@nblumhardt
Copy link
Member Author

(Could use more test coverage; the tests are mostly for the scenarios that overlap with Serilog.Sinks.RollingFile - will loop back and try to add some more when possible.)

@optical
Copy link
Member

optical commented Oct 13, 2017

Awesome work @nblumhardt! This will let me retire my forked sink with a messy implementation of these features.

@ritasker
Copy link

Looks great thanks. 👍

@nblumhardt
Copy link
Member Author

Great, thanks for taking a look!

Any thoughts on naming, anything else? I guess the surface area is pretty low. My current thinking is that I'll try adding a few more tests, then merge this through to open up to wider feedback.

@nblumhardt
Copy link
Member Author

Add: fix whatever is breaking the Travis build to that list :-)

@@ -0,0 +1,31 @@
// Copyright 2013-2016 Serilog Contributors
Copy link
Member

@tsimbalar tsimbalar Oct 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpicking : Year is now 2017 :) (also seen in several other files)

/// <param name="fileSizeLimitBytes">The approximate maximum size, in bytes, to which a log file will be allowed to grow.
/// For unrestricted growth, pass null. The default is 1 GB. To avoid writing partial events, the last event within the limit
/// will be written in full even if it exceeds the limit.</param>
/// <param name="buffered">Indicates if flushing to the output file can be buffered or not. The default
/// is false.</param>
/// <param name="shared">Allow the log file to be shared by multiple processes. The default is false.</param>
/// <param name="flushToDiskInterval">If provided, a full disk flush will be performed periodically at the specified interval.</param>
/// <param name="rollingInterval">The interval at which logging will roll over to a new file.</param>
/// <param name="rollOnFileSizeLimit">If <code>true</code>, a new file will be created when the file size limit is reached. Filenames
/// will have a number appended in the format <code>_NNNNN</code>, with the first filename given no number.</param>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the file is formatted with int.ToString("000"), I guess it should say "_NNN" here

@@ -92,6 +189,12 @@ public static class FileLoggerConfigurationExtensions
/// is false.</param>
/// <param name="shared">Allow the log file to be shared by multiple processes. The default is false.</param>
/// <param name="flushToDiskInterval">If provided, a full disk flush will be performed periodically at the specified interval.</param>
/// <param name="rollingInterval">The interval at which logging will roll over to a new file.</param>
/// <param name="rollOnFileSizeLimit">If <code>true</code>, a new file will be created when the file size limit is reached. Filenames
/// will have a number appended in the format <code>_NNNNN</code>, with the first filename given no number.</param>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, shouldn't it be _NNN ?

}

[Fact]
public void AssemblyVersionIsFixedAt200()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does that test pass, considering current File Sink (nuget package) version is at least v3.2.0+ ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all the feedback!

This one does pass - both sinks have had a frozen assembly version since 2.0.0, as a mitigation against the endless stream of binding redirect issues people hit (and report) otherwise :-)

[Fact]
public void TheLogFileIncludesDateToken()
{
var roller = new PathRoller("Logs\\log-.txt", RollingInterval.Day);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't backslashes problematic on Linux ? You should probably use Path.Combine , or maybe Path.DirectorySeparatorChar for the tests to work cross-platform

Copy link
Member

@tsimbalar tsimbalar Oct 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also maybe Path.GetInvalidFileNameChars can be useful to avoid generating invalid filenames no matter the platform

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh well, I see it's covered :) 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the check; yes, just hacking away at this between other jobs today, missed your comment but have it covered now.

return new DateTime(instant.Year, 0, 0, 0, 0, 0, instant.Kind);
case RollingInterval.Month:
return new DateTime(instant.Year, instant.Month, 0, 0, 0, 0, instant.Kind);
case RollingInterval.Day:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see a lot of ArgumentOutOfRangeException coming with the sample project, probably
new DateTime(instant.Year, 1, 1, 0, 0, 0, instant.Kind);
new DateTime(instant.Year, instant.Month, 1, 0, 0, 0, instant.Kind);
are needed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, fixing now 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Adding some tests....)

@nblumhardt
Copy link
Member Author

Finally made myself get WSL back up and running, instead of working in the dark, think everything should be running smoothly now.

@nblumhardt
Copy link
Member Author

README updated: https://github.com/nblumhardt/serilog-sinks-file/blob/af88bceba9ef183e0e9520606541066c2fdf6d89/README.md

Time to push this through to dev? What do you think, folks? :-)

@skomis-mm
Copy link

Didn't spot any issues more, looks great 👍

@nblumhardt
Copy link
Member Author

Thanks @skomis-mm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

One log file per month Feature to roll on file size and date
5 participants