Good morning

 

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 List<string> 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;

     }

     Return true;

   }

}

 

Some of the ideas above are already implemented in the patch, but there are
several things that are not yet finished.

 

Von: Dominik Psenner [mailto:dpsen...@gmail.com] 
Gesendet: Sonntag, 11. August 2013 22:59
An: Log4NET Dev
Betreff: Re: Creating a development environment for resolving LOG4NET-367

 

This is something that wouldn't work right now:

 

<appender>

 <rollingfileappender>

 
<filename>C:/fancydirectory/%processid/%username/%year/%month/mylogfile.log<
/filename>

  <locking>inter-process</locking>

  <rollOn><date where="hour%3==0" /></rollOn>

 
<rollTo>C:/fancydirectory/%processid/%username/%year/%month/%filenumber/mylo
gfile.log</rollTo>

  <dispose><files where="filenumber > 50" /></dispose>

 </rollingfileappender>

</appender>

 

but we want it to work in the future. Of couse the syntax may be different,
but it should be easy enough to write down how the RFA has to behave. Right
now there are too many fancy flicks and switches that do things magically.

 

Cheers

 

2013/8/11 Dominik Psenner <dpsen...@gmail.com <mailto:dpsen...@gmail.com> >

See the inlines..

 

2013/8/10 d_k <mail...@gmail.com <mailto:mail...@gmail.com> >

Paperizing ideas sounds good. How does the log4net project handle
requirements? JIRA?

 

Yes

 

Are there any requirements other than the ones under the 'supercedes' list?

 

Yes and no. It should be a rolling file appender that handles things smarter
than the current one. If there are ideas they are welcome.

 

It should roll files (obvious) on "rolling conditions" with a "rolling
strategy" and dispose old files with a "dispose strategy".

 

The rolling condition, rolling strategy and dispose strategy should be
pluggable and configurable (i.e. they are interfaces that can be implemented
in different ways).

 

It should support dynamic filenames that may change over time

 

It should support changes to the rolling strategy in respect of disposal of
old files (i.e. between process instances).

 

It should support all currently supported locking strategies.

 

For now I can't think of more.

 

 


I'm afraid I don't have a 'vision' for the RFA-NG but I think we can take
the patch under log4net-patches, make sure to fix the 'supercedes' list and
off we go.

I wouldn't want to spend time on a grand design because we can't tell how
long will it take, and I think it is better to ship a less than perfect
RFA-NG and fix it later on when we'll know what we want than to postpone the
next release indefinitely.

 

We have a RFA that does not what we want. We don't need another one. If we
reimplement it now and release it, we have another RFA with a public api we
do not want to change - sounds familiar.

 


BTW, no offense, but is there a chance it will be easier to fix the current
RFA than to rewrite it?

 

There are things that are unfixable with the current implementation without
breaking the public API and that's something we dont want.

 


Is there a way to measure a given implementation of any RFA to determine if
its good enough?

 

It's good enough when it boils eggs and toast my bread .. just joking. ;-)
It's good enough when it does what we want from it.

 

 

On Fri, Aug 9, 2013 at 8:00 PM, Dominik Psenner <dpsen...@gmail.com
<mailto:dpsen...@gmail.com> > wrote:

Howdie,

 

the patch there is mainly a first implementation showing the road we would
like to go. There are many things to be discussed and I would start with
paperizing the ideas before starting the implementation. The
reimplementation should solve all known current issues of the rolling file
appender.

 

The patches repository is nothing else than a repository that holds patches
that can be applied to the log4net source, which is located at apache.org
<http://apache.org> 's svn. It's there to materialize the ideas without
requiring write permissions to the actual svn and can be used as a sandbox
to play with ideas.

 

I started off with an implementation as a patch and wanted to improve that
patch until it is stable enough to join the log4net appenders in svn.

 

Cheers

 

2013/8/9 d_k <mail...@gmail.com <mailto:mail...@gmail.com> >

Hi,

So I think I got a working development environment for log4net.

I installed mercurial and forked the log4net-crew repository
(https://bitbucket.org/NachbarsLumpi/log4net-crew) and the log4net-patches
repository (https://bitbucket.org/NachbarsLumpi/log4net-patches) and applied
the RFA-NG patch with 'hg import'.

Should I prefer to use http://svn.apache.org/viewvc/logging/log4net/trunk
over https://bitbucket.org/NachbarsLumpi/log4net-crew? Will svn and
mercurial coexist peacefully?

Do I need anything else to start developing?

Should I create my own RFA-NG2 patch? Or perhaps RFA-NG-NNN for each bug in
the supercedes list of LOG4NET-367
(https://issues.apache.org/jira/browse/LOG4NET-367)?

Are there any common pitfalls I should avoid?





 

-- 
Dominik Psenner
## OpenPGP Key Signature #################################
# Key ID: B469318C                                       #
# Fingerprint: 558641995F7EC2D251354C3A49C7E3D1B469318C  #
##########################################################

 





 

-- 
Dominik Psenner
## OpenPGP Key Signature #################################
# Key ID: B469318C                                       #
# Fingerprint: 558641995F7EC2D251354C3A49C7E3D1B469318C  #
##########################################################





 

-- 
Dominik Psenner
## OpenPGP Key Signature #################################
# Key ID: B469318C                                       #
# Fingerprint: 558641995F7EC2D251354C3A49C7E3D1B469318C  #
##########################################################

Reply via email to