模拟用户和服务器的埋点日志:
需要在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格式。