線程模擬用戶和服務器----模擬生成大量埋點日誌數據

模擬用戶和服務器的埋點日誌:

需要在model層寫兩個分別爲用戶和服務器的埋點日誌信息實體類封裝日誌信心,以此來快速生成埋點日誌。

模擬瀏覽器的日誌信息:

在這裏插入圖片描述
代碼如下:

public Events{
	private String eventCateGory; // 行爲種類
	private String position;
	private String time;
	private String pageName;
	private String msg;
	
	public Events() {
	}

	public Events(String eventCateGory, String position, String time, String pageName, String msg) {
		this.eventCateGory = eventCateGory;
		this.position = position;
		this.time = time;
		this.pageName = pageName;
		this.msg = msg;
	}

	public String getEventCateGory() {
		return eventCateGory;
	}

	public void setEventCateGory(String eventCateGory) {
		this.eventCateGory = eventCateGory;
	}

	public String getPosition() {
		return position;
	}

	public void setPosition(String position) {
		this.position = position;
	}

	public String getTime() {
		return time;
	}

	public void setTime(String time) {
		this.time = time;
	}

	public String getPageName() {
		return pageName;
	}

	public void setPageName(String pageName) {
		this.pageName = pageName;
	}

	public String getMsg() {
		return msg;
	}

	public void setMsg(String msg) {
		this.msg = msg;
	}
}


public BrowserInfo{
	private String broser;
	private String custid;
	private	Events events;
	
	public BrowserInfo() {}

	public BrowserInfo(String browser, String custid, Events cm) {
		this.browser = browser;
		this.custid = custid;
		this.cm = cm;
	}

	public String getBrowser() {
		return browser;
	}

	public void setBrowser(String browser) {
		this.browser = browser;
	}

	public String getCustid() {
		return custid;
	}

	public void setCustid(String custid) {
		this.custid = custid;
	}

	public Events getCm() {
		return cm;
	}
	

		
}

模擬服務器的日誌信息:

模擬服務器的日誌的信息我們需要導入log4j和jackson的依賴,在pom.xml導入:

 <!-- https://mvnrepository.com/artifact/log4j/log4j -->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.9.9</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.9</version>
    </dependency>

在resources文件夾下創建log4j.properties,並將日誌信息和格式指定

# 輸出debug級--日誌級別
log4j.rootLogger=debug,appender1

# 輸出到文件--日誌目的地--appender追加(默認追加模式)
log4j.appender.appender1=org.apache.log4j.RollingFileAppender
log4j.appender.appender1.File=d:/loginfo/text.log

# 採用是什麼樣的格式--日誌格局--PatternLayout(靈活指定佈局模式)
log4j.appender.appender1.layout=org.apache.log4j.PatternLayout

# 日誌輸出什麼樣的內容--日誌內容
log4j.appender.appender1.layout.ConversionPattern =%r [%t] [%p] %d{yyyy-MM-dd HH:mm:ss} -%c-%l-%m%n

用線程模擬用戶的行爲:

寫出線程類

public class LogService extends Thread{
	private MyStore ms; // 封裝製造瀏覽器和服務器端的日誌的具體類 
	
	// 生成線程時,我們需要它的名字和等級還有產生日誌的能力
	public LogService(String name, int level, MyStore store) {
		setName(name);
		setPriority(level);
		this.ms = store;
	}
	
	// 重寫啓動方法,進入同步代碼塊後
	@Override
	public void run() {
		String name = Thread.currentThread().getName();
		int circle = 300;
		if (name.equalsIgnoreCase("action")) {
			circle = 100000;
		}
		for (int i = 0; i < circle; i++){
			execute(name);
		}
	}
	public void execute(String threadName){
		// 鎖住的是ms單例對象資源,當兩個線程共同去搶ms時,只有一個能搶到
		synchronized (ms){
			ms.writeLog(threadName);
		}
	}

實現日誌產生的資源類:

public class MyStore {
	private static MyStore ms;
	private static Random random = new Random();
	private static SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd hh:mm:ss");
	private static ObjectMapper om  = new ObjectMapper();
	private static Date date;
	private static int tm = 1;
	private static long userid = 10000;
	private static Calendar cal = Calendar.getInstance();
	String[] browsers = {"souhuwyw: version123","wyw1:version124"};
	String[] pageName = {"list.html","index.html"};
	String[] msgs = {"hello0","ccc","huawei"};
	String [] eventName = {"href_click","button_click","txt_input"};
	static {
		cal.set(2000,1,1,0,0,0);
		date = cal.getTime();
	}
	
	// 對資源類設爲單例獲取
	public static MyStore getMyStore(){
		if (ms == null){
			ms = new MyStore();
		}
		return ms;
	}
	private MyStore(){}


	public void writeLog(String threadName){

		String msg = threadName.equalsIgnoreCase("action") ? makeActionLog() : makeServiceLog();
		RandomAccessFile raf = null;
		try {
			// 賦予文件讀寫權限
			raf = new RandomAccessFile("/opt/event.log","rw");
			long size = raf.length();
			raf.seek(size);
			raf.writeBytes(msg + "\r\n");

		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			try {
				raf.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	// 製造服務器日誌
	private String makeServiceLog(){
		userid = 10000 + random.nextInt(80000);
		cal.add(Calendar.HOUR,random.nextInt(1000));
		// 第一次轉date,第二次轉long
		String str = userid + "|event_login|" + cal.getTime().getTime() + "|192.168.56." + random.nextInt(256);
		return str;
	}

	//製造用戶行爲日誌
	private String makeActionLog(){
		int pos = random.nextInt(2);
		Events es = new Events(eventName[random.nextInt(3)],"128 65",
			sdf.format(date),"http://localhost/" + pageName[random.nextInt(2)],msgs[random.nextInt(3)]);
		BrowserInfo bi = new BrowserInfo(browsers[pos],userid + "",es);
		cal.add(Calendar.MINUTE,1);
		date = cal.getTime();
		userid = 10000 + random.nextInt(80000);
		String str = null;
		try {
			str = om.writeValueAsString(bi);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		return str;
	}
}

產生埋點日誌:

APP作爲主類,開始生成埋點日誌:

public class App {
    public static void main( String[] args ) {
		// 生成單例資源
        MyStore ms = MyStore.getMyStore();
        // 啓動線程打印日誌
        new LogService("action",10, ms).start();
        new LogService("system",1, ms).start();

    }


}

此方法爲將兩者數據寫到一個文件裏,所以需要對資源進行上鎖,不然會產生混亂寫的現象。
而現實中會寫到兩個各自不同的文件中,無需考慮上鎖,所以上述代碼僅爲測試,以及加深對線程的操作。

在這裏插入圖片描述
一共產生100300行數據,上述爲寫入成功的日誌信息,爲json格式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章