论坛首页 Java企业应用论坛

一个Log生成工具小项目的实现

浏览 2082 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-11-01   最后修改:2011-11-02
    这两天的主要工作是用java写一个log生成工具,用于大数据量的测试。写这个工具,使用了:
  • Spring RMI:用于启动、关闭工具
  • Commons-logging + log4j,用于写log,其中重新实现了RollingFileAppender用于自定义log文件名
  • Math.random以及Ramdon,用于生成随机的数据
  • ScheduledThreadPoolExecutor用于多线程定时执行一些job,每个job负责生成相应的log文件
  • 泛型,每种log的生成器在运行时决定是哪一种log
  • Maven assembly plugin,用于打包,打成一个.zip包,解开后,运行里面的shell(linux下)或者bat(windows下)即可以运行
  • Windows bat的写法,用于写在windows下可执行bat文件


1. Spring RMI应用,在我的另外一篇文章中有介绍,而且工具也采用那个后台server框架。一个简单的JAVA后台程序框架

2. Commons-logging + log4j,这块没什么好讲的,自定义log文件名这一块详见自定义log4j生成的log文件名

3. 随机数的生成
3.1 在一个指定范围内生成随机整数
    public static final long getRandomNumber(long begin, long end) {
        return (long) (begin + (end - begin) * Math.random());
    }

3.2 生成指定长度的字符串
    public static final String randomString(int length) {
        if (length < 1) {
            return null;
        }
        if (randGen == null) {
            synchronized (initLock) {
                if (randGen == null) {
                    randGen = new Random();
                    numbersAndLetters = ("0123456789abcdefghijklmnopqrstuvwxyz"
                            + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
                            .toCharArray();
                }
            }
        }
        char[] randBuffer = new char[length];
        for (int i = 0; i < randBuffer.length; i++) {
            randBuffer[i] = numbersAndLetters[randGen.nextInt(71)];
        }
        return new String(randBuffer);
    }


4. ScheduledThreadPoolExecutor
    主要是使用其scheduleAtFixedRate方法。
引用

Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given period; that is executions will commence after initialDelay then initialDelay+period, then initialDelay + 2 * period, and so on. If any execution of the task encounters an exception, subsequent executions are suppressed. Otherwise, the task will only terminate via cancellation or termination of the executor. If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.


5. 泛型主要是我有不同的log,而且我有通用的接口方法和实现这个接口的Abstract类,在运行的时候才知道具体是哪种log生成器
public interface QosLogTool<T> extends Runnable {

    boolean isBatchMode();
    
    T getRandomQosLog();

    void setDelay(long delay);
    
    void setInterval(long interval);
    
    long getDelay();

    long getInterval();
}

public abstract class AbstractQosLogTool<T> implements QosLogTool<T> {

    protected boolean batchMode = false;


    public boolean isBatchMode() {
        return batchMode;
    }

    public void setBatchMode(boolean batchMode) {
        this.batchMode = batchMode;
    }

    protected int batchSize = 100;

    public int getBatchSize() {
        return batchSize;
    }

    public void setBatchSize(int batchSize) {
        this.batchSize = batchSize;
    }
    
    private long delay = 1000;
    
    public long getDelay() {
        return delay;
    }

    public void setDelay(long delay) {
        this.delay = delay;
    }
    
    private long interval = 5000;
    
    public long getInterval() {
        return interval;
    }

    public void setInterval(long interval) {
        this.interval = interval;
    }

    public void run() {
        if (isBatchMode() && batchSize > 0) {
            for (int i = 0; i < batchSize; i++) {
                printLog();
            }
        } else {
            printLog();
        }
    }

    protected abstract void printLog();

}

这样具体的log生成器只需要实现其printLog()和 getRandomQosLog()方法就可以了。

6. Maven assembly plugin,这个plugin非常方便生成直接可以运行的包,在pom.xml设置如下:
          <plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-assembly-plugin</artifactId>
				<configuration>
					<archive>
						<manifest>
						    <!-- 这里指定主程序入口 -->
							<mainClass>cn.lettoo.test.Launcher</mainClass>
						</manifest>
					</archive>
					<descriptors>
					    <!-- 这里指定装配文件 -->
						<descriptor>src/main/assembly/assembly.xml</descriptor>
					</descriptors>
				</configuration>
				<executions>
					<execution>
						<id>make-assembly</id>
						<phase>package</phase>
						<goals>
							<goal>single</goal>
						</goals>
					</execution>
				</executions>
			</plugin>


assembly.xml为装配文件
<assembly>
    <id>bin</id>
    <formats>
        <!-- 指定打zip包 -->
        <format>zip</format>
    </formats>
    <dependencySets>
        <dependencySet>
            <!-- copy jar文件到lib目录 -->
            <useProjectArtifact>true</useProjectArtifact>
            <outputDirectory>lib</outputDirectory>
        </dependencySet>
    </dependencySets>
    <!-- 下面主要是copy README.txt,以及配置文件到conf目录,还有运行脚本 -->
    <fileSets>
        <fileSet>
            <outputDirectory>/</outputDirectory>
            <includes>
                <include>README.txt</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>src/main/scripts</directory>
            <outputDirectory>/</outputDirectory>
        </fileSet>
        <fileSet>
            <directory>src/main/resources</directory>
            <outputDirectory>/conf</outputDirectory>
            <includes>
                <include>*.xml</include>
                <include>*.properties</include>
            </includes>
        </fileSet>
    </fileSets>
</assembly>


7. Windows下写一个bat文件直接运行,和linux shell一样,主要是对lib目录进行遍历拿到所有的*.jar文件,动态生成classpath,这样不需要以后增加jar后还要修改bat
set CLASSPATH=.;conf
setlocal enabledelayedexpansion
    for %%j in (lib/*.jar) do (
        set CLASSPATH=!CLASSPATH!;lib\%%j
    ) 
endlocal 

这里通过一个for循环来读取lib目录下所有的*.jar文件,并且加到classpath中去,linux shell是这样写的:
CLASSPATH=.:conf
for file in lib/*.jar;
do
   CLASSPATH=${CLASSPATH}:$file;
done
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics