log4j log file in user home directory

2019-03-18 13:12发布

问题:

I am working on an application that will run on OSX and windows. I want the logs to be written to the users home directory. For OSX it will be under the /Users//Library/Application Support/MyApp/log directory, and under windows depending on the version under /Users//AppData/MyApp/log directory.

What is the best way I can do this? I have looked around for solutions for this, but nothing helpful or a solution I am comfortable using has come up.

Look forward to your inputs.

edit: Since the location of the log file depends on the OS, I am hoping to find a run time solution, possibly something like below

if (System.getProperty("os.name").contains("mac"))
    logFileLocation = System.getProperty("user.home") + "/Library/Application Support/MyApp/logs"
else
    logFileLocation = System.getenv("APPDATA") + "/MyApp/logs"

Thanks

回答1:

Change the ConsoleAppender to a FileAppender. As far as I know the write request will be redirected to appdata on windows OS. Not sure about MacOs.

URL mySource = MyAppMainClass.class.getProtectionDomain().getCodeSource().getLocation();
File rootFolder = new File(mySource.getPath());
System.setProperty("app.root", rootFolder.getAbsolutePath());

and edit log4j config like this

log4j.appender.NotConsole=org.apache.log4j.RollingFileAppender
log4j.appender.NotConsole.fileName=${app.root}/fileName.log

or for user home:

log4j.appender.NotConsole.fileName=${user.home}/fileName.log


回答2:

Thank you all for the inputs. based on the hint that Alex proposed I went with the following approach,

In log4j.properties I had the following configuration

log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.File=${userApp.root}/logs/myapp.log

and at the start of the application I have done this.

System.setProperty("userApp.root", getUserAppDirectory());

the getUserAppDirectory() method is defined as

static String getUserAppDirectory() {
    if (isMacOS())
        return System.getProperty("user.home") + "/Library/Application Support/myapp";
    else
        return System.getenv("APPDATA") + "/myapp";
}


回答3:

Possibly the cleanest approach would be to write your log4j configuration assuming a particular system property (say myapp.data.dir)

log4j.appender.logfile.fileName=${myapp.data.dir}/logs/myapp.log

and set that property in the appropriate way in the launcher for each platform. For example if you're using an .app bundle on Mac OS X then you can set system properties in Info.plist

<plist version="1.0">
<dict>
    <!-- ... -->
    <key>Java</key>
    <dict>
        <!-- ... -->
        <key>Properties</key>
        <dict>
            <key>apple.laf.useScreenMenuBar</key>
            <string>true</string>
            <key>myapp.data.dir</key>
            <string>$USER_HOME/Library/Application Support/MyApp</string>

or set it relative to the APPDATA environment variable on Windows (which would handle the difference between XP and 7). With a Launch4J .exe you could put -Dmyapp.data.dir="%APPDATA%\MyApp" in the .l4j.ini file.

You'd need explicit code to initialize log4j before you try and access any loggers

if(System.getProperty("myapp.data.dir") == null) {
  // fallback to ~/.myapp (sensible Linux default) if run without a launcher
  System.setProperty("myapp.data.dir", new File(
        System.getProperty("user.home"), ".myapp").getAbsolutePath());
}
// ensure log directory exists
new File(new File(System.getProperty("myapp.data.dir")), "logs").mkdirs();
// now it's safe to configure log4j
PropertyConfigurator.configure(this.getClass().getResource("/log4j.properties"));


回答4:

I have Solved path issue of log4j.xml in mac :

in windows we configure log4j in web.xml like :

    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>

    <context-param> 
        <param-name>log4jConfigLocation</param-name> 
        <param-value>file:${LOG4J_HOME}/conf/log4j.xml</param-value> 

<!--   Above path is that where we have stored log4j.xml file externally  -->
    </context-param> 

    <context-param>
        <param-name>log4jRefreshInterval</param-name>
        <param-value>6000</param-value>
    </context-param>

Where ${LOG4J_HOME} is user varible we use to set in window. like

user variable = LOG4J_HOME value = D:/LOG4J (in d drive we have created a folder of name Log4J we copied that path and gave as a value)

In mac we have envirenvirent variable set fasility by bash command, but it didint work anymore.

so for mac we have to create one folder any where and we have to give static path of that folder.

like in xml :

<listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>

    <context-param> 
        <param-name>log4jConfigLocation</param-name> 
        <param-value>file:/Users/vardhaman/Desktop/LOG4J/conf/log4j.xml</param-value> 
<!--   Above path is that where we have stored log4j.xml file externally  to get this path go up to the log4j.xml file in external device and right click select get info, where we will get path, copy that path -->

    </context-param> 

    <context-param>
        <param-name>log4jRefreshInterval</param-name>
        <param-value>6000</param-value>
    </context-param>

Same way we have to do in log4j.xml file

In window we use to do like :

<appender name="CLICK-SPRING" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="${LOG4J_HOME}/logs/CLICK/CLICK-spring.log"/>
        <param name="Append" value="true"/>
        <param name="Threshold" value="DEBUG"/>
        <param name="MaxFileSize" value="100MB"/>
        <param name="MaxBackupIndex" value="10" />
        <layout class="org.apache.log4j.PatternLayout">
          <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %p [%t] %C{1}.%M(%L) | %m%n"/>
        </layout>
    </appender> 

In mac :

in place of value we have to copy static path up to folder LOG4J, or you can create any folder.

<appender name="CLICK-SPRING" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="Users/vardhaman/Desktop/LOG4J/logs/CLICK/CLICK-spring.log"/>
        <param name="Append" value="true"/>
        <param name="Threshold" value="DEBUG"/>
        <param name="MaxFileSize" value="100MB"/>
        <param name="MaxBackupIndex" value="10" />
        <layout class="org.apache.log4j.PatternLayout">
          <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %p [%t] %C{1}.%M(%L) | %m%n"/>
        </layout>
    </appender> 


标签: java log4j