package DataCollection;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import Entity.LogRecord;
import Entity.MatchedRecord;
import Util.JDBCConnection;
/**
* 责采集环境的处理与数据采集,分析处理。所有的采集任务有该类完成, 主要获取本机IP,复制备份并清空日志文件,读取日志文件,解析日志文件,
* 匹配处理日志登录/登出记录获取用户登录时间,在线用户下次匹配。
*
* @author soft01
*
*/
@SuppressWarnings("unused")
public class DataCollector {
private static ArrayList<LogRecord> logins = new ArrayList<LogRecord>();
private static ArrayList<LogRecord> logouts = new ArrayList<LogRecord>();
private static final String URL = "wtmpx200901230001";
private int day = Integer.parseInt(URL.substring(11, 13));
private static Properties pro = new Properties();
private String sourcefile = null;
/** 采集源文件名 */
private String destinationpath = null;
/** 采集源文件临时备份目录 */
private String command = null;
/** 采集源备份指令,在unix下是mv 在DOS下是move该指令还必须依赖shell */
private String historyfile = null;
/** 上次没有匹配的文件名,不含路径,路径采用destinationpath */
/**
* 读取初始化配置文件unix_server.properties
*
* @throws
*
*/
public void init() {
File f = null;
try {
f = new File("unix_server.properties");
pro.load(new FileInputStream(f));
} catch (FileNotFoundException e1) {
System.out.println("配置文件未找到!" + f.getPath());
System.exit(0);
} catch (IOException e2) {
System.out.println("配置文件加载失败!");
System.exit(0);
}
}
/**
* 读取要采集服务器的IP,该IP用属性文件配置。
*
* @return 返回属性文件中配置的本机的IP地址数据
*/
public String getNativeIP() {
String ip = pro.getProperty("ip");
return ip;
}
/**
* 负责调用Runtime执行mv shell指令进行日志文件的备份并清空原始文件。
* 备份的文件名wtmpx+年(4位)+月(2位)+日(2位)+时(2位), 比如wtmpx2008053013.
*
* @return 返回的是采集数据源的备份文件(包含路径)
*/
public String initlog() throws IOException {
// 获取日期时间,并格式化,便于文件备份使用
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmm");
String time = simpleDateFormat.format(date);
// 得到采集的数据目录,在unix服务器上是/usr/adm
sourcefile = pro.getProperty("sourcefile");
System.out.println(sourcefile);
destinationpath = pro.getProperty("destinationpath");
command = pro.getProperty("command");
historyfile = pro.getProperty("historyfile");
sourcefile = (sourcefile == null) ? "/home/soft01/DMS/bin/adm/wtmpx"
: sourcefile;// 采集源路径没有设置,则用usr/adm作为缺省路径。
destinationpath = destinationpath == null ? "/home/soft01/DMS/bin/history/"
: destinationpath;// 备份路径没有设置,则备份到当前路径。
command = command == null ? "mv" : command;
String destfile = "wtmpx" + time;// 备份文件名
String cmdstr = command + " " + sourcefile + " " + destinationpath
+ destfile;
System.out.println(cmdstr);
// 判定源是否存在
if (!new File(sourcefile).exists()) {
System.out.println("采集源不存在!");
throw new IOException("采集源不存在!");
}
// 判定目标目录是否存在,不存在就创建。
File tmpdestpath = new File(destinationpath);
if (!tmpdestpath.exists()) {
tmpdestpath.mkdirs();
}
Runtime r = Runtime.getRuntime();
try {
// 内部指令不能单独启动一个进程,必须依赖shell
// 请参考DOS的cmd 与 Unix的sh
Process p = r.exec(cmdstr);
p.waitFor();// 等待指令执行完毕,否则后面打开文件的时候,报文件不存在异常.
} catch (IOException e) {
e.printStackTrace();
System.out.println("采集源备份错误!");
throw new IOException("采集源备份错误!");
} catch (InterruptedException e) {
System.out.println("采集源备份过程出错!");
throw new IOException("采集源备份过程出错!");
}
return destinationpath + destfile;
}
/**
* 主要把备份的日志文件映射为本地内存缓冲,便于后面解析。
*
* @param fileName
* @return 本地文件映射缓冲MappedByteBuffer
*/
public MappedByteBuffer mappingLogBuffer(String fileName) {
return null;
}
/**
* 负责解析缓冲的内存结构,利用参数返回两个Vector结构对象, 一个存放登录数据,一个存放登出数据。
*
* @param logbuffer
* 要解析的本地内存缓冲。
* @param logins
* 返回解析后的登录数据。
* @param logouts
* 返回解析后的登出数据
*/
public void parseLogBuffer(MappedByteBuffer logbuffer,
ArrayList<LogRecord> logins, ArrayList<LogRecord> logouts) {
}
@SuppressWarnings("unchecked")
public void loginsMatch(){
// 获取上次未匹配的登录数据
ObjectInputStream ois = null;
File f = null;
try {
f = new File("logouts.txt");
ois = new ObjectInputStream(new FileInputStream(f));
logins.addAll((ArrayList<LogRecord>) ois.readObject());
//上面未抛出异常就表示数据已加载完毕,就必须删除此文件,防止下次数据重合
f.delete();
} catch (FileNotFoundException e) {
System.out.println("文件未找到!");
return;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (ois != null) {
try {
ois.close();
} catch (IOException e) {
}
}
}
}
public void collect() {
loginsMatch();
DataCollector data = new DataCollector();
String labip = data.getNativeIP();
RandomAccessFile file = null;
try {
file = new RandomAccessFile("/home/soft01/DMS/bin/history/" + URL,
"r");
while (file.getFilePointer() < file.length()) {
byte[] ut_user = new byte[32];
file.read(ut_user);
String userName = new String(ut_user);
file.read(new byte[4]);
byte[] ut_line = new byte[32];
file.read(ut_line);
String deviceName = new String(ut_line);
int pid = file.readInt();
short type = file.readShort();
file.read(new byte[2]);
file.read(new byte[2]);
file.read(new byte[2]);
int ut_second = file.readInt();
int ut_msecond = file.readInt();
long time = ut_second * 1000L + ut_msecond;
file.read(new byte[4]);
file.read(new byte[20]);
file.read(new byte[2]);
byte[] bip = new byte[257];
file.read(bip);
String userip = new String(bip).trim();
file.seek(file.getFilePointer() + 1);
if ((type != 7 && type != 8) || userName.startsWith(".")
|| deviceName.startsWith("ftp")) {
continue;
} else if (type == 7) {
logins.add(new LogRecord(userName, pid, time, labip, type,
userip));
} else if (type == 8) {
logouts.add(new LogRecord(userName, pid, time, labip, type,
userip));
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (file != null) {
try {
file.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
matchData(logins, logouts);
}
public void matchData(ArrayList<LogRecord> logins,
ArrayList<LogRecord> logouts) {
List<MatchedRecord> matches = new ArrayList<MatchedRecord>();
LogRecord logout = null;
for (int i = 0; i < logouts.size(); i++) {
logout = logouts.get(i);
LogRecord login = null;
for (int j = 0; j < logins.size(); j++) {
login = logins.get(j);
if (login.getPid() == logout.getPid()
&& login.getUserIP().equals(logout.getUserIP())) {
long duration = logout.getTime() - login.getTime();
if (duration < 0) {
logouts.remove(logout);
} else {
MatchedRecord match = new MatchedRecord();
match.setUserIP(login.getUserIP());
match.setLabIp(logout.getLabip());
match.setUserName(logout.getUserName());
match.setLoginTime(login.getTime());
match.setLog