AW: Ideas for a new RollingFileAppender

2013-08-26 Thread Dominik Psenner
I agree. The user has to be aware of that special file but I wouldn't make
it switchable because it implicitly limits the available configurations in
other places and the user probably does not know. We have a similar magic
toggle in the current RFA which is named staticLogFileName. That toggle
disables rolling over date when set.

 

Still, optional configuration values are a matter of agreement and we can
find sensible ones by asking the user list with a poll. I've lately spent
some time thinking about how a configuration of the new RFA could look like
(in XML) and this is what my brain came up with:

 

appender type=RFA2 name=RFA2.mine

logfileFormatlogs/mylogfile.log/logfileFormat

rollingConfiguration

 
fileCacheFile${appender.name}.cache/fileCacheFile

lockingModel type=minimal /

   rollingConditions

   rollingCondition
type=startup / !- rolls files on startup; this is equivalent to the
behaviour when one configures appendToFile=false in the current RFA --!

   rollingCondition
type=cron

   pattern*/5
* * */pattern !-roll every 5 minutes --!

   /rollingCondition

   rollingCondition
type=cron

 
pattern0,5,10,15,20,25,30,35,40,45,50,55 * * */pattern !-alternative
but semantically equivalent pattern --!

   /rollingCondition

   rollingCondition
type=cron 

   !-yet
another alternative but semantically equivalent pattern --!

   pattern
minute=*/5 hour=* day=* dow=* month=* /

   /rollingCondition

   rollingCondition
type=filesize

   maxFileSize
unit=mb5/maxFileSize !-roll if filesize exceeds 5mb --!

   /rollingCondition

/rollingConditions

   rollingStrategy
type=defaultRollingStrategy

   !-rolls a rolled file to the
specified file name format; ${datetime.original} would be the date/time when
the original logfile was first rolled --!

 
rolledLogfileFormatlogs/mylogfile-${datetime.original}-{$file.index}.log/
rolledLogfileFormat

   /rollingStrategy

   disposeConditions

   disposeCondition
type=filecount

 
maxFileCount10/maxfileCount !-dispose rolled files if there are 10
newer files --!

   /disposeCondition

   disposeCondition
type=fileage

   maxFileAge
unit=days30/maxFileAge

   /disposeCondition

/disposeConditions

disposeStrategy type=moveFile

 
disposedLogfileFormatlogs/old/mylogfile-${datetime}-${file.index}.log/dis
posedLogfileFormat

/disposeStrategy

/rollingConfiguration

/appender

 

I would for instance default these properties like this:

 

fileCachefile: may always default to ${appender.name}.cache

lockingModel: may default to minimal

rollingConditions: may default to file size exceeds 1mb

disposeStrategy: may default to delete file

 

Cheers

 

Von: d_k [mailto:mail...@gmail.com] 
Gesendet: Sonntag, 25. August 2013 18:41
An: Log4NET Dev
Betreff: Re: Ideas for a new RollingFileAppender

 

Hard tasks are fun, but I wouldn't want the next version to be stuck forever
because of it.

What if we make it optional?

If the user wishes to roll dynamic paths he should flip a switch and specify
a target path that should be writable.

I don't think you can make it totally headless because the user still needs
to be aware a file is written and he needs write permissions to it, so we
might as well make the default implementation work without creating files
and provide an implementation that persists the data locally.

So applications that upgrade to the new version behave the same.

 

 

On Fri, Aug 23, 2013 at 10:54 AM, Dominik Psenner dpsen...@gmail.com
mailto:dpsen...@gmail.com  wrote:

Good Morning,

 

I understand your point. That would be exactly how the current RFA behaves.
However, people are lazy and when something doesn't work they are first
frustrated and then they may throw the framework over board or ask silly
questions. The latter happens about once every month. It is not nice to have
the answer ready this is not supported and it won't ever be because then
discussions 

AW: Ideas for a new RollingFileAppender

2013-08-23 Thread Dominik Psenner
Good Morning,

 

I understand your point. That would be exactly how the current RFA behaves.
However, people are lazy and when something doesn't work they are first
frustrated and then they may throw the framework over board or ask silly
questions. The latter happens about once every month. It is not nice to have
the answer ready this is not supported and it won't ever be because then
discussions start about the why-not and may-not-be or could-we-not.

 

As I see it, the time has come that we should provide a solution that works.
There are times when documentation does solve an issue but this time it is
not. Of course this is not an easy task, but easy tasks are annoying anyway.
Hard tasks make the life tasty, don't they? :)

 

Cheers

 

Von: d_k [mailto:mail...@gmail.com] 
Gesendet: Dienstag, 20. August 2013 21:16
An: Log4NET Dev
Betreff: Re: Ideas for a new RollingFileAppender

 

Will it be reasonable to say that as long as the target folder path is
static log4net will clean up old files and if the target folder path is
dynamic it will clean them as long as the process is up?

 

On Thu, Aug 15, 2013 at 4:44 PM, Stefan Bodewig bode...@apache.org
mailto:bode...@apache.org  wrote:

On 2013-08-14, Dominik Psenner wrote:

 2013/8/14 Stefan Bodewig bode...@apache.org mailto:bode...@apache.org 

 The application runs for 3 days and thus log4net rolls the logfile 3
 times.

 Well, I live in a world where all log files of an application are kept
 inside the same folder :-)

 For me too, but I've seen enough to know better.

Might be a matter of educating the culprits.

Yes, I know things like this happen.


 More seriously, to me it sounds like a bit of feature creep.  I wouldn't
 consider my logging framework to be the one who's responsible for
 mailing non empty files on rolling.  That's the job of
 logrotate/logwatch or similar specialiced tools IMHO.  One could even
 argue disposal of logfiles should be out of scope.  Maybe that's just
 me.

 Yes and no. The framework should at least be able to prevent filesystem
 pollution by itself when told to clean up after itself.

I'm not sure I agree with that.  But arguing against that is almost
arguing against having a RollingFileAppender in the first place.  So
I'll give in.

Stefan

 



AW: Ideas for a new RollingFileAppender

2013-08-13 Thread Dominik Psenner

 Another issue that I just remembered now is that currently there's no way
to
 roll empty files on date/time boundaries. Rolling only happens when a log
 event is generated. If there's no log event, files won't be rolled. Thus
we
 should investigate if we should implement the appender as a buffering
async
 appender that does the rolling in his async work cycles and whose work
 cycles do not depend on the availability of log events.

 
Making the appender async is a major change and it has ramifications that
might prove problematic like unflushed buffers.
And if we make the buffer of size 1 then its really synchronous again, isn't
it?


Does a 'roll' create a new file? So if there are no log event the folder
will be polluted with empty files?
If a 'roll' does not create a file then we can make the decision to roll or
not as part of the logging process.

Whats wrong with rolling on logging events?


 Futher, the rolling file appender should probably receive a persistent
 storage where he can keep a set of rolled files he has rolled in the past.
 This way we eliminate the dark magic behind detecting rolled files. It
 allows the user also to modify or mix the rolling strategies and/or
rolling
 filename configuration from one instance to the next. The persistence will
 have to include a set of filenames. It would probably be nice to allow
 people configuring a relative filepath that will be stripped from the
 filenames. Otherwise we would break the usecase where a user moves an
 application from, let's say, drive C: to drive D: along with all logfiles
 because the rolled filenames would no longer be found and some files would
 become zombies that pollute the drive. Thus a persistable rolling history
 class could look alike:



 Public class RollingHistory {

   Public Liststring Files { get; }

I'm up for a clean way to roll but I think that a logging framework that
creates files other than logs is odd. And adding a dependency on some
persistent storage provider is also odd.

I think we can assume that applications that need to perform rolling on size
or date are probably long running which means we can save this information
in memory and in case the application crashed or restarts then yes, the old
files will remain on disk and it should be solved by a local policy because
it the exception, not the rule.
 

 To exchange information between the rolling strategies, rolling conditions
 and the rolling file appender itself we should probably use a data class.
 The name of it could be RollingContext and basically could be
implemented
 like:



 public class RollingContext {

   public RollingHistory RollingHistory { get; }

   public string Logfile { get; }

   public long CurrentLogfileSize { get; }





 That means that a rolling strategy could be an interface like:



 public interface RollingStrategy {

   public void DoRolling(RollingContext context);





 which either throws exceptions on failure or returns true|false to notify
 the caller that something went wrong and log the errors into the log4net
 internal debug log.



 The next topic is the rolling condition. The rolling condition decides if
 rolling should be done right now. Thus its interface should be something
 like:



 public interface IRollingCondition {

   public bool IsRollingConditionMet(RollingContext context);





 Concrete rolling conditions could be:



 * Roll if filesize exceeds a specific limit

 * Roll if a specific date/time condition is met
 == this is already kind of supported with an implementation of a
 cron-like syntax



 Making the rolling condition pluggable would greatly benefit others to
 invent their own rolling conditions. For example an implementation of
 IRollingCondition like:



 public class ManualRollingCondition implements IRollingCondition {

   public static bool RollOnNextCycle = false;

   public bool IsRollingConditionMet(RollingContext context) {

 if(RollOnNextCycle) {

   // reset roll on next cycle

   RollOnNextCycle = false;

   return true;

 }

return false;







 could let the application that uses log4net decide when a file should be
 rolled by a simple invoke to:



 ManualRollingCondition.RollOnNextCycle=true;



 And now we come to the disposal of old files. Since we have a persistent
set
 of old files we should pass it into the disposing logic and the interface
to
 it could look like:



 Public interface IDisposeStrategy {

   Public bool DoDisposal(RollingContext context);





 And a concrete implementation of it could be:



 Public class LimitNumberOfFilesDisposeStrategy implements IDisposeStrategy
{

Public int MaxNumberOfFiles { get; set; }

Public bool DoDisposal(RollingContext context) {

  // delete all files in history

  While(MaxNumberOfFiles  Context.RollingHistory.Count) {

If(Context.RollingHistory.Count == 0)

   Return true;

// delete oldest file and persist the history

// let it 

AW: Ideas for a new RollingFileAppender

2013-08-12 Thread Dominik Psenner
[good idea :-D]

-Ursprüngliche Nachricht-
Von: Stefan Bodewig [mailto:bode...@apache.org]
Gesendet: Montag, 12. August 2013 10:07
An: Log4NET Dev
Betreff: Ideas for a new RollingFileAppender

[just changing the subject :-)]

On 2013-08-12, Dominik Psenner wrote:

 Yesterday it became quite late and I had not the mental force to write
down
 my vision of the RFA reimplementation:



 The log filename should be determined dynamically to allow users
including
 information like %date, %time in the filename. It has often been
requested
 and up to now it is supported only marginally.



 Another issue that I just remembered now is that currently there's no way
to
 roll empty files on date/time boundaries. Rolling only happens when a log
 event is generated. If there's no log event, files won't be rolled. Thus
we
 should investigate if we should implement the appender as a buffering
async
 appender that does the rolling in his async work cycles and whose work
 cycles do not depend on the availability of log events.



 Futher, the rolling file appender should probably receive a persistent
 storage where he can keep a set of rolled files he has rolled in the
past.
 This way we eliminate the dark magic behind detecting rolled files. It
 allows the user also to modify or mix the rolling strategies and/or
rolling
 filename configuration from one instance to the next. The persistence
will
 have to include a set of filenames. It would probably be nice to allow
 people configuring a relative filepath that will be stripped from the
 filenames. Otherwise we would break the usecase where a user moves an
 application from, let's say, drive C: to drive D: along with all logfiles
 because the rolled filenames would no longer be found and some files
would
 become zombies that pollute the drive. Thus a persistable rolling history
 class could look alike:



 Public class RollingHistory {

   Public Liststring Files { get; }





 To exchange information between the rolling strategies, rolling
conditions
 and the rolling file appender itself we should probably use a data class.
 The name of it could be RollingContext and basically could be
implemented
 like:



 public class RollingContext {

   public RollingHistory RollingHistory { get; }

   public string Logfile { get; }

   public long CurrentLogfileSize { get; }





 That means that a rolling strategy could be an interface like:



 public interface RollingStrategy {

   public void DoRolling(RollingContext context);





 which either throws exceptions on failure or returns true|false to notify
 the caller that something went wrong and log the errors into the log4net
 internal debug log.



 The next topic is the rolling condition. The rolling condition decides if
 rolling should be done right now. Thus its interface should be something
 like:



 public interface IRollingCondition {

   public bool IsRollingConditionMet(RollingContext context);





 Concrete rolling conditions could be:



 * Roll if filesize exceeds a specific limit

 * Roll if a specific date/time condition is met
 == this is already kind of supported with an implementation of a
 cron-like syntax



 Making the rolling condition pluggable would greatly benefit others to
 invent their own rolling conditions. For example an implementation of
 IRollingCondition like:



 public class ManualRollingCondition implements IRollingCondition {

   public static bool RollOnNextCycle = false;

   public bool IsRollingConditionMet(RollingContext context) {

 if(RollOnNextCycle) {

   // reset roll on next cycle

   RollOnNextCycle = false;

   return true;

 }

return false;







 could let the application that uses log4net decide when a file should be
 rolled by a simple invoke to:



 ManualRollingCondition.RollOnNextCycle=true;



 And now we come to the disposal of old files. Since we have a persistent
set
 of old files we should pass it into the disposing logic and the interface
to
 it could look like:



 Public interface IDisposeStrategy {

   Public bool DoDisposal(RollingContext context);





 And a concrete implementation of it could be:



 Public class LimitNumberOfFilesDisposeStrategy implements
IDisposeStrategy {

Public int MaxNumberOfFiles { get; set; }

Public bool DoDisposal(RollingContext context) {

  // delete all files in history

  While(MaxNumberOfFiles  Context.RollingHistory.Count) {

If(Context.RollingHistory.Count == 0)

   Return true;

// delete oldest file and persist the history

// let it crash if someone has a logfile open and locked

// and let the invoker decide if he wants to retry later

Try {

  Delete(Context.RollingHistory.Oldest());

  Context.RollingHistory.Remove(Context.RollingHistory.Oldest());

  Context.RollingHistory.Persist();

 }

 Catch

  // internal logging

 Return false;

  }