I need build a java project to compare performance of apache log4j and Logback. The following codes are the building procedures based on [Gradle]http://www.gradle.org/) and sbt.
sbt
mkdir myproject
cd myproject
cat <<EOF > build.sbt
name := "MyProject"
version := "0.1"
EOF
mkdir project
echo 'addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.5.0")' > project/plugins.sbt
sbt eclipse
Note that the blank line between "name" & "version" in build.sbt is mandatory for Scala syntax. Now start eclipse, import this proect, create new packages (com.boco.logb) and Java files (LoggerOneThread.java) in "src/main/java" folder, and config files (log4j.properties and logback.xml) in src/resources folder. slf4j looks for log implementations based on jars in classpath instead of conifg files, so we add both 2 config files into resource folder.
The LoggerOneThread.java file:
package com.boco.logb;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoggerOneThread {
public static final long TOTAL_TIMES = 4000 * 1000;
private static final Logger logger = LoggerFactory
.getLogger(LoggerOneThread.class);
public static void main(String[] args) {
long start = System.nanoTime();
for (int i = 1; i < TOTAL_TIMES; i++) {
logger.debug("This is a test message. This is another test message.");
}
long estimatedTime = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime()
- start);
System.out.println("Write " + TOTAL_TIMES + " logs takes time "
+ estimatedTime + " s.");
}
}
Log4j config file log4j.properties:
log4j.rootLogger = DEBUG, FILE
log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.File=log4j.log
log4j.appender.FILE.Append=true
log4j.appender.FILE.MaxFileSize=50MB
log4j.appender.FILE.MaxBackupIndex=10
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%d{MM-dd HH:mm:ss.SSS} [%t] %p %c - %m%n
Logback config file logback.xml:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logback.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>logback.log.%i</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>11</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>50MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%date{MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
Add following dependencies into build.sbt.log4j:
libraryDependencies ++= Seq(
"org.slf4j" % "slf4j-api" % "1.7.7",
"org.slf4j" % "slf4j-log4j12" % "1.7.7",
"log4j" % "log4j" % "1.2.17"
)
And the following into build.sbt.logback:
libraryDependencies ++= Seq(
"org.slf4j" % "slf4j-api" % "1.7.7",
"ch.qos.logback" % "logback-classic" % "1.1.2",
"ch.qos.logback" % "logback-core" % "1.1.2"
)
Now delete .classpath file under project home folder,
run sbt eclipse
again to refresh classpath.
When coding completed, copy build.sbt.log4j (or build.sbt.logback) as build.sbt,
run sbt run
to run this project.
Run sbt package
to create jar file under target folder.
Some other settings in build.sbt:
organization := "org.leechau"
Gradle
-
Install gradle plugin for Eclipse, and create a Gradle Project "MyProject" in Eclipse, choose "Java Quickstart" as Sample project;
-
Add following lines into auto-created build.gradle file for log4j test:
apply plugin: 'application' dependencies { compile 'org.slf4j:slf4j-api:1.7.7', 'log4j:log4j:1.2.17', 'org.slf4j:slf4j-log4j12:1.7.7' } mainClassName = "com.boco.logb.LoggerOneThread"
-
Refresh dependencies: [Gradle -> Refresh Dependencies] in context menu;
-
Run log4j test:
cp build.gradle build.gradle.log4j gradle clean run
-
For logback test, create a new file build.gradle.logback based on build.gradle.log4j, but use the following dependencies:
compile 'org.slf4j:slf4j-api:1.7.7', 'ch.qos.logback:logback-classic:1.1.2', 'ch.qos.logback:logback-core:1.1.2'
The config files log4j.properties and logback.xml, and Java file LoggerOneThread.java are identical to that in sbt section.
- Run logback test:
cp build.gradle.logback build.gradle gradle clean run
Eclipse Interface
How to creat Eclipse setting files (.classpath and .project) so that we can import this project into Eclipse, editing and debuging in it.
For gradle, add apply plugin: 'eclipse'
into build.gradle and
run gradle cleanEclipse eclipse
;
For sbt, add addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.5.0")
(for sbt 0.13) into $PROJECT_HOME/project/plugins.sbt, and run sbt eclipse
;
Run Program
gradle
// run log4j test
cp build.gradle.log4j build.gradle
gradle clean run
// run logback test
cp build.gradle.logback build.gradle
gradle clean run
sbt
// run log4j test
cp build.sbt.log4j build.sbt
sbt clean run
// run logback test
cp build.sbt.logback build.sbt
sbt clean run
If you have multiple main entry in source files, you can use 'runMain com.boco.logb.LoggerOneThread' instead of "run" to run a specific program.
Conclusion
Gradle is mainly for building of Groovy and Java project, while sbt is mainly for building of Scala and Java project. So far Gradle has better support for building Java project. For example, it's very convenient to build production zip or tar files with Gradle's application plugin (via the "distZip" task), while there's no corresponding plugin in sbt. It's convenient to add or remove dependencies within Eclipse with the Gradle plugin of Eclipse (not the eclipse plugin of Gradle), while there's no sbt plugin of Eclipse (sbteclipse of typesafehub is a eclipse plugin of sbt). So we have to refresh build path of dependencies manually when developing a project in Eclipse created by sbt.