This code appears to doing two things:
1. Provide a custom setFile method to set the file name, buffer size, 
and the append and bufferedIO flags. It also always sets immediateFlush 
to false.
2. Only opens the file when fileNameConfigured is called.

Other than that it is just the standard FileAppender.

Given that, there really is no need for this in Log4j2.

I haven’t seen the code that calls setFile but you can use custom 
Lookups if required to provide the values for the file name, buffer 
size and flags. To be honest though, I’d be surprised if custom 
Lookups are really required. I’d guess you can probably accomplish 
what you need with the standard lookups.

As for delaying creating the file, that can be accomplished just by 
specifying createOnDemand=“true”.

Ralph

.

> On Aug 15, 2022, at 10:09 AM, Joel Griffith <jgrif...@nd.edu> wrote:
> 
> I guess I can.  90 lines isn't too big for an email, is it?
> 
> ***** start code *****
> 
> import java.io.BufferedWriter;
> import java.io.File;
> import java.io.FileNotFoundException;
> import java.io.FileOutputStream;
> import java.io.IOException;
> import java.io.Writer;
> 
> import org.apache.logging.log4j.core.appender.FileAppender;
> import org.apache.logging.log4j.status.StatusLogger;
> 
> public class LazyFileAppender extends FileAppender {
>    /**
>     * Override FileAppender.setFile to avoid creating an empty log file
> before
>     * the code has a chance to customize the file name.
>     */
>    public synchronized void setFile(String fileName, boolean append,
> boolean bufferedIO, int bufferSize)
>            throws IOException {
>        StatusLogger.debug("setFile called: {}, {}", fileName, append);
> 
>        if (this.qw != null) {
>            return;
>        }
> 
>        // set a stdout writer just in case
>        reset();
>        Writer fw = createWriter(System.out);
>        this.setQWForFiles(fw);
> 
>        this.fileName = fileName;
>        this.fileAppend = append;
>        this.bufferedIO = bufferedIO;
>        this.bufferSize = bufferSize;
>        StatusLogger.debug("setFile ended");
>    }
> 
>    /**
>     * Calling this method will signal this class that the log file name
>     * has been configured and that the file can now be opened.
>     * @throws IOException
>     */
>    public void fileNameConfigured() throws IOException {
>        StatusLogger.debug("fileNameConfigured called");
> 
>        // It does not make sense to have immediate flush and bufferedIO.
>        if (this.bufferedIO) {
>            setImmediateFlush(false);
>        }
> 
>        // Save file name since reset() sets it to null
>        String fileName = this.fileName;
> 
>        // Set to null to prevent parent class from closing System.out
>        this.qw = null;
>        reset();
>        this.fileName = fileName;
>        FileOutputStream ostream = null;
>        try {
>            //
>            // attempt to create file
>            //
>            ostream = new FileOutputStream(this.fileName, this.fileAppend);
>        }
>        catch (FileNotFoundException ex) {
>            //
>            // if parent directory does not exist then
>            // attempt to create it and try to create file
>            // see bug 9150
>            //
>            String parentName = new File(this.fileName).getParent();
>            if (parentName != null) {
>                File parentDir = new File(parentName);
>                if (!parentDir.exists() && parentDir.mkdirs()) {
>                    ostream = new FileOutputStream(this.fileName,
> this.fileAppend);
>                }
>                else {
>                    throw ex;
>                }
>            }
>            else {
>                throw ex;
>            }
>        }
>        Writer fw = createWriter(ostream);
>        if (this.bufferedIO) {
>            fw = new BufferedWriter(fw, this.bufferSize);
>        }
>        this.setQWForFiles(fw);
>        writeHeader();
>        StatusLogger.debug("fileNameConfigured ended");
>    }
> }
> 
> ***** end code *****
> 
> Joel
> 
> On Mon, Aug 15, 2022 at 11:33 AM Ralph Goers <ralph.go...@dslextreme.com>
> wrote:
> 
>> This is a problem. Log4j supports Lookups, which usually eliminate the
>> need
>> to override things like setFile since you can create a custom lookup to do
>> whatever needs to be done.
>> 
>> Is there any chance you can post the code so we can figure out what it
>> does?
>> 
>> Ralph
>> 
>>> On Aug 15, 2022, at 8:21 AM, Joel Griffith <jgrif...@nd.edu> wrote:
>>> 
>>> I don't know what the old appender does, in part because I'm not a good
>>> enough programmer to interpret it, and in part because the bulk of what
>> it
>>> does is contained in the source code of the classes that it subclasses,
>> and
>>> I don't have that v1 source code.
>>> 
>>> One thing I've figured out that it does is override the v1 FileAppender's
>>> setFile() method.  I've also figured out that the v2 FileAppender doesn't
>>> have that method.  So... I don't know what to do about that.
>>> 
>>> Joel
>>> 
>>> On Fri, Aug 12, 2022 at 7:18 PM Gary Gregory <garydgreg...@gmail.com>
>> wrote:
>>> 
>>>> Joel,
>>>> 
>>>> Is it possible to use Log4j 2's much richer feature set as is? Perhaps
>> you
>>>> could explain what is it your old appender does that requires custom
>> code.
>>>> 
>>>> Gary
>>>> 
>>>> On Fri, Aug 12, 2022, 15:35 Joel Griffith <jgrif...@nd.edu> wrote:
>>>> 
>>>>> I have a Java application containing a package written to use Log4j v1.
>>>> I
>>>>> am struggling to update this package to use Log4j v2 to remediate its
>>>>> security vulnerabilities.
>>>>> 
>>>>> The package contains a custom Appender that subclasses Log4j v1's
>>>>> FileAppender.  I am stumped at how to convert this file to Log4j v2.
>> In
>>>>> Log4j v2, the FileAppender class is 'final' and cannot be subclassed,
>> so
>>>> I
>>>>> cannot create a new version of the custom Appender that mirrors the
>>>> first.
>>>>> More importantly, perhaps, is that the Log4j v2 FileAppender is a
>> Plugin
>>>>> and completely different in structure from the Log4j v1 FileAppender.
>>>>> 
>>>>> I found this page that ostensibly explains how to extend Log4j:
>>>>> https://logging.apache.org/log4j/2.x/manual/extending.html#Appenders
>>>>> but it contains no information about actually extending Appenders or
>>>>> procedures for accomplishing an equivalent goal.
>>>>> 
>>>>> Is there any reasonable way of converting this custom Appender from
>> Log4j
>>>>> v1 to v2?
>>>>> 
>>>>> Thanks,
>>>>> Joel
>>>>> 
>>>> 
>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org
>> For additional commands, e-mail: log4j-user-h...@logging.apache.org
>> 
>> 


---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org
For additional commands, e-mail: log4j-user-h...@logging.apache.org

Reply via email to