Gradle 前提だけど、他のビルドツールでもできるはず。
スタンドアロンアプリ
フォルダ構成
app/
|-build.gradle
`-src/main/
|-java/
| `-Main.java
`-resources/
`-log4j.xml
実装
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" >
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%m%n" />
</layout>
</appender>
<root>
<level value ="${log.level}" />
<appender-ref ref="stdout"/>
</root>
</log4j:configuration>
import org.apache.log4j.Logger;
public class Main {
public static void main(String[] args) {
boolean isRelease = Boolean.valueOf(System.getProperty("isRelease"));
if (isRelease) {
System.out.println("Release Mode");
System.setProperty("log.level", "INFO");
} else {
System.out.println("Develop Mode");
System.setProperty("log.level", "TRACE");
}
Logger logger = Logger.getLogger(Main.class);
logger.trace("trace message");
logger.debug("debug message");
logger.info("info message");
}
}
apply plugin: 'application'
mainClassName = 'Main'
repositories {
mavenCentral()
}
dependencies {
compile 'log4j:log4j:1.2.17'
}
startScripts {
defaultJvmOpts += ['-DisRelease=true']
}
動作確認
開発中の状態で実行
> gradle -q run
Develop Mode
trace message
debug message
info message
ビルドしてから実行
> gradle distZip
build/distributions/app.zip を解凍。
bin の下の起動ファイルを実行する。
> build\distributions\app\bin\app.bat
Release Mode
info message
説明
システムプロパティ isRelease
に true
が設定されているかどうかで処理を分岐している。
isRelease
の値は、 Gradle の Application プラグインにある startScripts.defaultJvmOpts
で設定することで、リリース後のみ true
が適用されるようにしている。
Log4j は ${xxxx}
という形式でシステムプロパティの値を参照できる。
これを利用して、 Log4j のロガーを最初に取得する前に、システムプロパティに必要な値を設定している。
ウェブアプリ
フォルダ構成
webapp/
|-build.gradle
`-src/main/
|-java/
| |-MyListener.java
| `-MyServlet.java
|-resources/
| `-log4j.xml
`-webapp/WEB-INF
`-web.xml
実装
- log4j.xml の実装はスタンドアロンのときと同じ。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<listener>
<listener-class>MyListener</listener-class>
</listener>
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/my-servlet</url-pattern>
</servlet-mapping>
</web-app>
import javax.servlet.ServletContextListener;
import javax.servlet.ServletContextEvent;
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
if (this.isRelease()) {
System.out.println("Release Mode");
System.setProperty("log.level", "INFO");
} else {
System.out.println("Develop Mode");
System.setProperty("log.level", "TRACE");
}
}
private boolean isRelease() {
return MyListener.class.getResource("/is_release") != null;
}
@Override public void contextDestroyed(ServletContextEvent sce) {/*no use*/}
}
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
public class MyServlet extends HttpServlet {
private static final Logger logger = Logger.getLogger(MyServlet.class);
@Override
public void doGet(HttpServletRequest req, HttpServletResponse res) {
logger.trace("trace message");
logger.debug("debug message");
logger.info("info message");
}
}
apply plugin: 'jetty'
repositories {
mavenCentral()
}
dependencies {
compile 'log4j:log4j:1.2.17'
providedCompile 'javax.servlet:servlet-api:2.5'
}
war {
doFirst {
def releaseFlagFile = new File(buildDir, 'tmp/release/is_release')
releaseFlagFile.with {
parentFile.mkdirs()
createNewFile()
}
classpath += files(releaseFlagFile.parent)
}
}
動作確認
開発中の状態で実行
> gradle jettyRun
:compileJava
:processResources
:classes
:jettyRun
Develop Mode
> Building 75% > :jettyRun > Running at http://localhost:8080/webapp
ブラウザを開いて http://localhost:8080/webapp/my-servlet
にアクセスする。
trace message
debug message
info message
生成したwarファイルで実行
> gradle jettyRunWar
:compileJava
:processResources
:classes
:war
:jettyRunWar
Release Mode
> Building 80% > :jettyRunWar > Running at http://localhost:8080/webapp
ブラウザを開いて http://localhost:8080/webapp/my-servlet
にアクセスする。
info message
説明
gradle war
したときだけ、クラスパス直下に is_release
というファイルを配置。
Web アプリ起動時に MyListener
が is_release
の存在をチェックしている。