1.创建maven工程
log4j依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
fastjson依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.17</version>
</dependency>
完整pom.xml配置文件(因为要打成jar包至虚拟机下执行,需要配置胖包信息)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.kgc</groupId>
<artifactId>create_log</artifactId>
<version>1.0</version>
<name>create_log</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<main-class>cn.kgc.App</main-class>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assemply</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2.log4j配置文件
log4j.rootLogger = INFO,R
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=${flume.log.dir}/prolog.log
log4j.appender.R.MaxFileSize=512MB
log4j.appender.R.MaxBackupIndex=40
log4j.appender.R.layout=org.apache.log4j.TTCCLayout
log4j.appender.R.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n
3.java代码
package cn.kgc;
import com.alibaba.fastjson.JSON;
import org.apache.log4j.Logger;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class App
{
private static Logger logger;
private static Properties logConf = new Properties();
private static long lastModified = 0;
private static boolean goon = true;
private static ExecutorService singlePool;
private static String PATH,CONF_PATH;
private static long orderId = 0;
private static final int USER_ID_UPPER = 1000000;
private static final int CMM_ID_UPPER = 10000000;
private static Calendar c = Calendar.getInstance();
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static Random rand = new Random();
public static class OrderDetail{
private long cmmId;
private int buyNum;
public OrderDetail(){};
public OrderDetail(long cmmId, int buyNum) {
this.cmmId = cmmId;
this.buyNum = buyNum;
}
public long getCmmId() {
return cmmId;
}
public void setCmmId(long cmmId) {
this.cmmId = cmmId;
}
public int getBuyNum() {
return buyNum;
}
public void setBuyNum(int buyNum) {
this.buyNum = buyNum;
}
}
public static class Order{
private long orderId;
private long userId;
private String createDate;
private List<OrderDetail> details;
public Order(long orderId, long userId, String createDate) {
this.orderId = orderId;
this.userId = userId;
this.createDate = createDate;
this.details = new ArrayList<>();
}
public void setDetails(long cmmId,int buyNum){
this.details.add(new OrderDetail(cmmId,buyNum));
}
public long getOrderId() {
return orderId;
}
public long getUserId() {
return userId;
}
public String getCreateDate() {
return createDate;
}
public List<OrderDetail> getDetails() {
return details;
}
}
private static int parse(String key){
return Integer.parseInt(logConf.getProperty(key));
}
private static void readConf(File confFile) throws Exception {
lastModified = confFile.lastModified();
FileInputStream fis = new FileInputStream(confFile);
logConf.load(fis);
c.set(parse("year"),
parse("month"),
parse("day"),
parse("hour"),
parse("minute"),
parse("second"));
orderId = Long.parseLong(logConf.getProperty("orderId"));
goon = Boolean.parseBoolean(logConf.getProperty("goon"));
fis.close();
//单线程池侦听配置信息的修改状况
singlePool = Executors.newSingleThreadExecutor();
singlePool.submit(()->{
//System.err.println("侦听线程开启...");
while(goon){
File file = new File(CONF_PATH);
//如果文件被修改
if (lastModified!=file.lastModified()){
//System.err.println("配置文件被修改...开始读取配置...");
//重置修改时间
lastModified = file.lastModified();
try {
//读首行。更新goon的值
//如果要终止进程,将goon改为false即可
Properties pro = new Properties();
pro.load(new FileInputStream(CONF_PATH));
goon = Boolean.parseBoolean(pro.getProperty("goon"));
pro.clear();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//System.err.println("侦听线程释放");
});
}
private static void writeConf() throws IOException {
FileOutputStream fos = new FileOutputStream(CONF_PATH,false);
logConf.setProperty("orderId",String.valueOf(orderId));
logConf.setProperty("year",String.valueOf(c.get(Calendar.YEAR)));
logConf.setProperty("month",String.valueOf(c.get(Calendar.MONTH)+1));
logConf.setProperty("day",String.valueOf(c.get(Calendar.DATE)));
logConf.setProperty("hour",String.valueOf(c.get(Calendar.HOUR)));
logConf.setProperty("minute",String.valueOf(c.get(Calendar.MINUTE)));
logConf.setProperty("second",String.valueOf(c.get(Calendar.SECOND)));
logConf.store(fos, "modified at " + sdf.format(new Date()));
fos.close();
}
public static void main( String[] args ) throws Exception {
if (args.length<2) {
throw new RuntimeException("未提供日志或配置路径");
}
PATH = args[0];
CONF_PATH=args[1];
File dir = new File(PATH),confFile = new File(CONF_PATH);
if (!confFile.exists()||!confFile.isFile()) {
throw new RuntimeException(CONF_PATH+"不存在或非文件异常");
}
if (!dir.exists()) {
dir.mkdirs();
}
if (dir.isFile()){
throw new RuntimeException("必须提供路径,而你错误的提供了文件");
}
//设置jvm运行时环境变量
System.setProperty("flume.log.dir",PATH);
//初始化配置信息和日期
readConf(confFile);
logger = Logger.getLogger(App.class);
//System.err.println("开启日志输出...");
while(goon){
c.add(Calendar.SECOND,1+rand.nextInt(30));
Order order = new Order(++orderId, 1 + rand.nextInt(USER_ID_UPPER), sdf.format(c.getTime()));
for (int i = 0; i < 1 + rand.nextInt(5); i++) {
order.setDetails(1+rand.nextInt(CMM_ID_UPPER),1+rand.nextInt(3));
}
logger.info(JSON.toJSONString(order));
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//System.err.println("结束日志输出");
writeConf();
singlePool.shutdown();
//System.err.println("信息公布完成");
}
}