- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章java读取用户登入退出日志信息上传服务端由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文实例为大家分享了读取用户登入出日志并上传服务端的具体实现代码,供大家参考,具体内容如下 。
该客户端运行在给用户提供unix服务的服务器上。用来读取并收集该服务器上用户的上下线信息,并进行配对整理后发送给服务端汇总.
具体实现代码:
1. DMSServer.java 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
|
package
com.dms;
import
java.io.BufferedReader;
import
java.io.File;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
java.io.InputStreamReader;
import
java.io.OutputStreamWriter;
import
java.io.PrintWriter;
import
java.net.ServerSocket;
import
java.net.Socket;
import
java.util.HashMap;
import
java.util.List;
import
java.util.Map;
import
java.util.concurrent.BlockingQueue;
import
java.util.concurrent.ExecutorService;
import
java.util.concurrent.Executors;
import
java.util.concurrent.LinkedBlockingQueue;
import
org.dom4j.Document;
import
org.dom4j.Element;
import
org.dom4j.io.SAXReader;
/**
* DMS服务端,用来接收每个客户端发送过来的
* 配对日志并保存在本地文件中
* @author Administrator
*
*/
public
class
DMSServer {
//属性定义
//用来接收客户端连接的服务端的ServerSocket
private
ServerSocket server;
//用来管理处理客户端请求的线程的线程池
private
ExecutorService threadPool;
//保存所有客户端发送过来配对日志的文件
private
File serverLogFile;
//消息队列
private
BlockingQueue<String> messageQueue =
new
LinkedBlockingQueue<String>();
public
DMSServer()
throws
Exception{
try
{
System.out.println(
"服务端正在初始化..."
);
//1 解析配置文件server-config.xml
Map<String,String> config = loadConfig();
//2 根据配置文件内容初始化属性
init(config);
System.out.println(
"服务端初始化完毕..."
);
}
catch
(Exception e) {
System.out.println(
"初始化服务端失败!"
);
throw
e;
}
}
/**
* 构造方法初始化第一步,解析配置文件
* @return 返回的Map中保存的是配置文件中的
* 每一条内容,其中key:标签的名字,
* value为标签中间的文本
* @throws Exception
*/
private
Map<String,String> loadConfig()
throws
Exception{
try
{
SAXReader reader =
new
SAXReader();
Document doc
= reader.read(
new
File(
"server-config.xml"
));
Element root = doc.getRootElement();
Map<String,String> config
=
new
HashMap<String,String>();
/*
* 获取<config>标签中的所有子标签
* 并将每一个子标签的名字作为key,中间的
* 文本作为value存入Map集合
*/
List<Element> list = root.elements();
for(Element e : list){
String key = e.getName();
String value = e.getTextTrim();
config.put(key, value);
}
return config;
} catch (Exception e) {
System.out.println("解析配置文件异常!");
e.printStackTrace();
throw e;
}
}
/**
* 构造方法初始化第二步,根据配置项初始化属性
* @param config
* @throws Exception
*/
private void init(Map<String,String> config) throws Exception{
/*
* 用配置文件中的<logrecfile>初始化属性:serverLogFile
* 用配置文件中的<threadsum>初始化属性:threadPool,这里创建固定大小线程池。该值作为线程池线程数量
* 用配置文件中的<serverport>初始化属性:server,这里这个值为ServerSocket的服务端口
*/
this.server = new ServerSocket(
Integer.parseInt(config.get("serverport"))
);
this.serverLogFile = new File(
config.get("logrecfile")
);
this.threadPool = Executors.newFixedThreadPool(
Integer.parseInt(config.get("threadsum"))
);
}
/**
* 服务端开始工作的方法
* @throws Exception
*/
public void start() throws Exception{
/*
* 实现要求:
* 首先单独启动一个线程,用来运行SaveLogHandler
* 这个任务,目的是保存所有配对日志
* 然后开始循环监听服务端端口,一旦一个客户端连接了,
* 就实例化一个ClientHander,然后将该任务交给线程池
* 使其分配线程来处理与该客户端的交互。
*
*/
try {
System.out.println("服务端开始工作...");
SaveLogHandler slh=new SaveLogHandler();
new Thread(slh).start();
while(true){
Socket socket=server.accept();
threadPool.execute(new ClientHandler(socket));
}
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
public static void main(String[] args) {
try {
DMSServer server = new DMSServer();
server.start();
} catch (Exception e) {
System.out.println("启动服务端失败!");
}
}
/**
* 该线程负责从消息队列中取出每一条配对日志,
* 并存入到serverLogFile文件
* @author Administrator
*
*/
private class SaveLogHandler implements Runnable{
public void run(){
PrintWriter pw = null;
try {
pw = new PrintWriter(
new FileOutputStream(
serverLogFile,true
)
);
while(true){
if(messageQueue.size()>0){
pw.println(messageQueue.poll());
}else{
pw.flush();
Thread.sleep(500);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally{
if(pw != null){
pw.close();
}
}
}
}
/**
* 处理一个指定客户端请求
* @author Administrator
*
*/
private class ClientHandler implements Runnable{
private Socket socket;
public ClientHandler(Socket socket){
this.socket = socket;
}
public void run(){
/*
* 思路:
* 首先接收客户端发送过来的所有配对日志,
* 直到读取到"OVER"为止,然后将这些配对
* 日志保存到本地的文件中,并回复客户端
* "OK"
* 执行步骤:
* 1:通过Socket创建输出流,用来给客户端
* 发送响应
* 2:通过Socket创建输入流,读取客户端发送
* 过来的日志
* 3:循环读取客户端发送过来的每一行字符串,并
* 先判断是否为字符串"OVER",若不是,则是
* 一条配对日志,那么保存到本地文件,若是,
* 则停止读取。
* 4:成功读取所有日志后回复客户端"OK"
*/
PrintWriter pw =
null
;
try
{
//1
pw =
new
PrintWriter(
new
OutputStreamWriter(
socket.getOutputStream(),
"UTF-8"
)
);
//2
BufferedReader br =
new
BufferedReader(
new
InputStreamReader(
socket.getInputStream(),
"UTF-8"
)
);
//3
String message =
null
;
while
((message = br.readLine())!=
null
){
if
(
"OVER"
.equals(message)){
break
;
}
//将该日志写入文件保存
messageQueue.offer(message);
}
//4
pw.println(
"OK"
);
pw.flush();
}
catch
(Exception e) {
e.printStackTrace();
pw.println(
"ERROR"
);
pw.flush();
}
finally
{
try
{
//与客户端断开连接释放资源
socket.close();
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
}
}
|
2. DMSClient.java 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
|
package
com.dms;
import
java.io.BufferedReader;
import
java.io.File;
import
java.io.IOException;
import
java.io.InputStreamReader;
import
java.io.OutputStreamWriter;
import
java.io.PrintWriter;
import
java.io.RandomAccessFile;
import
java.net.Socket;
import
java.util.ArrayList;
import
java.util.HashMap;
import
java.util.List;
import
java.util.Map;
import
java.util.Map.Entry;
import
java.util.Set;
import
org.dom4j.Document;
import
org.dom4j.Element;
import
org.dom4j.io.SAXReader;
import
com.dms.bo.LogData;
import
com.dms.bo.LogRec;
/**
* 该客户端运行在给用户提供unix服务的服务器上。
* 用来读取并收集该服务器上用户的上下线信息,并
* 进行配对整理后发送给服务端汇总。
* @author Administrator
*
*/
public
class
DMSClient {
//属性定义
//第一步:解析日志所需属性
//unix系统日志文件
private
File logFile;
//保存解析后日志的文件
private
File textLogFile;
//书签文件
private
File lastPositionFile;
//每次解析日志的条目数
private
int
batch;
//第二步:配对日志所需要属性
//保存配对日志的文件
private
File logRecFile;
//保存未配对日志的文件
private
File loginLogFile;
//第三步:发送日志所需要属性
//服务端地址
private
String serverHost;
//服务端端口
private
int
serverPort;
/**
* 构造方法,用来初始化客户端
* @throws Exception
*/
public
DMSClient()
throws
Exception{
try
{
//1 解析配置文件config.xml
Map<String,String> config = loadConfig();
//打桩
System.out.println(config);
//2 根据配置文件内容初始化属性
init(config);
}
catch
(Exception e) {
System.out.println(
"初始化失败!"
);
throw
e;
}
}
/**
* 构造方法初始化第二步,根据配置项初始化属性
* @param config
* @throws Exception
*/
private
void
init(Map<String,String> config)
throws
Exception{
try
{
logFile =
new
File(
config.get(
"logfile"
)
);
textLogFile =
new
File(
config.get(
"textlogfile"
)
);
lastPositionFile =
new
File(
config.get(
"lastpositionfile"
)
);
batch = Integer.parseInt(
config.get(
"batch"
)
);
logRecFile =
new
File(
config.get(
"logrecfile"
)
);
loginLogFile =
new
File(
config.get(
"loginlogfile"
)
);
serverHost = config.get(
"serverhost"
);
serverPort = Integer.parseInt(
config.get(
"serverport"
)
);
}
catch
(Exception e) {
System.out.println(
"初始化属性失败!"
);
e.printStackTrace();
throw
e;
}
}
/**
* 构造方法初始化第一步,解析配置文件
* @return 返回的Map中保存的是配置文件中的
* 每一条内容,其中key:标签的名字,
* value为标签中间的文本
* @throws Exception
*/
private
Map<String,String> loadConfig()
throws
Exception{
try
{
SAXReader reader =
new
SAXReader();
Document doc
= reader.read(
new
File(
"config.xml"
));
Element root = doc.getRootElement();
Map<String,String> config
=
new
HashMap<String,String>();
/*
* 获取<config>标签中的所有子标签
* 并将每一个子标签的名字作为key,中间的
* 文本作为value存入Map集合
*/
List<Element> list = root.elements();
for(Element e : list){
String key = e.getName();
String value = e.getTextTrim();
config.put(key, value);
}
return config;
} catch (Exception e) {
System.out.println("解析配置文件异常!");
e.printStackTrace();
throw e;
}
}
/**
* 客户端开始工作的方法
* 循环执行三步:
* 1:解析日志
* 2:配对日志
* 3:发送日志
*/
public void start(){
parseLogs();
matchLogs();
sendLogs();
// while(true){
// //解析日志
// if(!parseLogs()){
// continue;
// }
// //配对日志
// if(!matchLogs()){
// continue;
// }
// //发送日志
// sendLogs();
// }
}
/**
* 第三步:发送日志
* @return true:发送成功
* false:发送失败
*/
private boolean sendLogs(){
/*
* 实现思路:
* 将logRecFile文件中的所有配对日志读取
* 出来然后连接上服务端并发送过去,若服务端
* 全部接收,就可以将该文件删除,表示发送
* 完毕了。
* 实现步骤:
* 1:logRecFile文件必须存在
* 2:将所有配对日志读取出来并存入一个集合
* 等待发送
* 3:通过Socket连接服务端
* 4:创建输出流
* 5:顺序将所有配对日志按行发送给服务端
* 6:单独发送一个字符串"OVER"表示所有日志
* 均已发送完毕
* 7:创建输入流
* 8:读取服务端发送回来的响应字符串
* 9:若响应的字符串为"OK",表示服务端正常
* 接收了所有日志,这时就可以将logRecFile
* 文件删除并返回true表示发送完毕。
*
*/
Socket socket = null;
try {
//1
if(!logRecFile.exists()){
System.out.println(logRecFile+"不存在!");
return false;
}
//2
List<String> matches
= IOUtil.loadLogRec(logRecFile);
//3
socket = new Socket(serverHost,serverPort);
//4
PrintWriter pw = new PrintWriter(
new OutputStreamWriter(
socket.getOutputStream(),"UTF-8"
)
);
//5
for(String log : matches){
pw.println(log);
}
//6
pw.println("OVER");
pw.flush();
//7
BufferedReader br = new BufferedReader(
new InputStreamReader(
socket.getInputStream(),"UTF-8"
)
);
//8
String response = br.readLine();
//9
if("OK".equals(response)){
logRecFile.delete();
return true;
}else{
System.out.println("发送日志失败!");
return false;
}
} catch (Exception e) {
System.out.println("发送日志失败!");
e.printStackTrace();
} finally{
if(socket != null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
}
/**
* 第二步:配对日志
* @return true:配对成功
* false:配对失败
*/
private boolean matchLogs(){
/*
* 实现思路:
* 将第一步解析的新日志,与上次为配对成功
* 的登入日志全部读取出来,然后再按照user,
* pid相同,type一个是7,一个是8进行配对。
* 只要能找到类型为8的,一定可以找到一个
* 能与之配对的登入日志。
*
* 实现步骤:
* 1:必要的判断
* 1.1:logRecFile是否存在,存在则不再
* 进行新的配对工作,避免覆盖。
* 1.2:textLogFile文件必须存在。
* 2:读取textLogFile将日志读取出来,并
* 存入到集合中。(若干LogData实例)
* 3:若loginLogFile文件若存在,则说明
* 有上次未配对成功的日志,也将其读取
* 出来存入集合等待一起配对
* 4:配对工作
* 4.1:创建一个集合,用于保存所有配对日志
* 4.2:创建两个Map分别保存登入日志与登出日志
* 4.3:遍历所有待配对的日志,按照登入与登出
* 分别存入两个Map中,
* 其中key:user,pid
* value:LogData实例
* 4.4:遍历登出Map,并根据每条登出日志的key
* 去登入Map中找到对应的登入日志,并
* 以一个LogRec实例保存该配对日志,然后
* 存入配对日志的集合中。并将该配对日志
* 中的登入日志从登入Map中删除。这样一来
* 登入Map中应当只剩下没有配对的了。
* 5:将配对日志写入到logRecFile中
* 6:将所有未配对日志写入到loginLogFile中
* 7:将textLogFile文件删除
* 8:返回true,表示配对完毕
*
*/
try {
//1
//1.1
if(logRecFile.exists()){
return true;
}
//1.2
if(!textLogFile.exists()){
System.out.println(textLogFile+"不存在!");
return false;
}
//2
List<LogData> list
= IOUtil.loadLogData(textLogFile);
//3
if(loginLogFile.exists()){
list.addAll(
IOUtil.loadLogData(loginLogFile)
);
}
//4
//4.1
List<LogRec> matches
= new ArrayList<LogRec>();
//4.2
Map<String,LogData> loginMap
= new HashMap<String,LogData>();
Map<String,LogData> logoutMap
= new HashMap<String,LogData>();
//4.3
for(LogData logData : list){
String key = logData.getUser()+","+
logData.getPid();
if(logData.getType()==LogData.TYPE_LOGIN){
loginMap.put(key, logData);
}else if(logData.getType()==LogData.TYPE_LOGOUT){
logoutMap.put(key, logData);
}
}
//4.4
Set<Entry<String,LogData>> entrySet
= logoutMap.entrySet();
for(Entry<String,LogData> e : entrySet){
LogData logout = e.getValue();
LogData login = loginMap.remove(e.getKey());
LogRec logRec = new LogRec(login,logout);
matches.add(logRec);
}
//5
IOUtil.saveCollection(matches, logRecFile);
//6
IOUtil.saveCollection(
loginMap.values(),loginLogFile
);
//7
textLogFile.delete();
//8
return true;
} catch (Exception e) {
System.out.println("配对日志失败!");
e.printStackTrace();
}
return false;
}
/**
* 第一步:解析日志
* @return true:解析成功
* false:解析失败
*/
private boolean parseLogs(){
/*
* 实现思路:
* 循环读取batch条日志,然后将每条日志中的
* 5个信息解析出来,最终组成一个字符串,以
* 行为单位,写入到textLogFile文件中
*
* 实现步骤:
* 1:必要的判断工作
* 1.1:为了避免解析的日志还没有被使用,而
* 第一步又重复执行导致之前日志被覆盖
* 的问题,这里需要判断,若保存解析后
* 的日志文件存在,则第一步不再执行。
* 该日志文件会在第二步配对完毕后删除。
* 1.2:logFile文件必须存在(wtmpx文件)
* 1.3:是否还有日志可以解析
* 2:创建RandomAccessFile来读取logFile
* 3:将指针移动到上次最后读取的位置,准备
* 开始新的解析工作
* 4:解析工作
* 4.1:创建一个List集合,用于保存解析后
* 的每一条日志(LogData实例)
* 4.2:循环batch次,解析每条日志中的
* 5项内容(user,pid,type,time,host)
* 并用一个LogData实例保存,然后将
* 该LogData实例存入集合
* 5:将集合中的所有的日志以行为单位保存到
* textLogFile中
* 6:保存书签信息
* 7:返回true,表示工作完毕
*
*/
RandomAccessFile raf = null;
try {
//1
//1.1
if(textLogFile.exists()){
return true;
}
//1.2
if(!logFile.exists()){
System.out.println(logFile+"不存在!");
return false;
}
//1.3
long lastPosition = hasLogs();
//打桩
// System.out.println(
// "lastPosition:"+lastPosition
// );
if(lastPosition<0){
System.out.println("没有日志可以解析了!");
return false;
}
//2
raf = new RandomAccessFile(logFile,"r");
//3
raf.seek(lastPosition);
//4
List<LogData> list
= new ArrayList<LogData>();
for(int i=0;i<batch;i++){
//每次解析前都判断是否还有日志可以解析
if(logFile.length()-lastPosition
<LogData.LOG_LENGTH
){
break;
}
//解析user
raf.seek(lastPosition+LogData.USER_OFFSET);
String user
= IOUtil.readString(
raf, LogData.USER_LENGTH
).trim();
//解析PID
raf.seek(lastPosition+LogData.PID_OFFSET);
int pid = raf.readInt();
//解析TYPE
raf.seek(lastPosition+LogData.TYPE_OFFSET);
short type = raf.readShort();
//解析TIME
raf.seek(lastPosition+LogData.TIME_OFFSET);
int time = raf.readInt();
//解析HOST
raf.seek(lastPosition+LogData.HOST_OFFSET);
String host
= IOUtil.readString(
raf, LogData.HOST_LENGTH
).trim();
LogData log = new LogData(user, pid, type, time, host);
list.add(log);
//打桩
// System.out.println(log);
//当解析完一条日志后,更新lastPosition
lastPosition = raf.getFilePointer();
}
//5
IOUtil.saveCollection(list, textLogFile);
//6 保存书签文件
IOUtil.saveLong(
lastPosition, lastPositionFile);
//7
return true;
} catch (Exception e) {
System.out.println("解析日志失败!");
e.printStackTrace();
} finally{
if(raf != null){
try {
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
}
/**
* 第一步解析日志中的一个环节,
* 根据书签文件记录的位置判断是否还有
* 日志可以解析,若有,则将上次最后的位置
* 返回,若没有则返回-1。
* @return
*/
private long hasLogs(){
try {
/*
* 若lastPositionFile不存在,则说明
* 从来没有解析过,那么从头开始解析即可
*/
if
(!lastPositionFile.exists()){
return
0
;
}
long
lastPosition
= IOUtil.readLong(lastPositionFile);
if
(logFile.length()-lastPosition
>=LogData.LOG_LENGTH){
return
lastPosition;
}
}
catch
(Exception e) {
e.printStackTrace();
}
return
-
1
;
}
public
static
void
main(String[] args) {
try
{
DMSClient client =
new
DMSClient();
client.start();
}
catch
(Exception e) {
System.out.println(
"客户端运行失败!"
);
}
}
}
|
3. IOUtil.java 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
package
com.dms;
import
java.io.BufferedReader;
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.InputStreamReader;
import
java.io.PrintWriter;
import
java.io.RandomAccessFile;
import
java.util.ArrayList;
import
java.util.Collection;
import
java.util.List;
import
com.dms.bo.LogData;
/**
* 该类是一个工具类,负责客户端的IO操作
* @author Administrator
*
*/
public
class
IOUtil {
/**
* 从给定的文件中读取每一行字符串(配对日志)
* 并存入一个集合后返回
* @param file
* @return
* @throws Exception
*/
public
static
List<String> loadLogRec(File file)
throws
Exception{
BufferedReader br =
null
;
try
{
br =
new
BufferedReader(
new
InputStreamReader(
new
FileInputStream(
file
)
)
);
List<String> list
=
new
ArrayList<String>();
String line =
null
;
while
((line = br.readLine())!=
null
){
list.add(line);
}
return
list;
}
catch
(Exception e) {
e.printStackTrace();
throw
e;
}
finally
{
if
(br !=
null
){
br.close();
}
}
}
/**
* 从给定的文件中读取每一条配对日志,并存入
* 一个集合中然后返回。
* @param file
* @return
* @throws Exception
*/
public
static
List<LogData> loadLogData(File file)
throws
Exception{
BufferedReader br =
null
;
try
{
br =
new
BufferedReader(
new
InputStreamReader(
new
FileInputStream(
file
)
)
);
List<LogData> list =
new
ArrayList<LogData>();
String line =
null
;
while
((line = br.readLine())!=
null
){
LogData logData =
new
LogData(line);
list.add(logData);
}
return
list;
}
catch
(Exception e) {
e.printStackTrace();
throw
e;
}
finally
{
if
(br!=
null
){
br.close();
}
}
}
/**
* 将指定的long值以字符串的形式写入到
* 给定文件的第一行
* @param l
* @param file
* @throws Exception
*/
public
static
void
saveLong(
long
lon,File file)
throws
Exception{
PrintWriter pw =
null
;
try
{
pw =
new
PrintWriter(file);
pw.println(lon);
}
catch
(Exception e) {
e.printStackTrace();
throw
e;
}
finally
{
if
(pw !=
null
){
pw.close();
}
}
}
/**
* 将集合中每个元素的toString方法返回的字符串
* 以行为单位写入到指定文件中。
* @param c
* @param file
* @throws Exception
*/
public
static
void
saveCollection(
Collection c,File file)
throws
Exception{
PrintWriter pw =
null
;
try
{
pw =
new
PrintWriter(file);
for
(Object o : c){
pw.println(o);
}
}
catch
(Exception e) {
e.printStackTrace();
throw
e;
}
finally
{
if
(pw !=
null
){
pw.close();
}
}
}
/**
* 从给定的RandomAccessFile当前位置开始连续
* 读取length个字节,并转换为字符串后返回
* @param raf
* @param length
* @return
* @throws Exception
*/
public
static
String readString(
RandomAccessFile raf,
int
length)
throws
Exception{
try
{
byte
[] data =
new
byte
[length];
raf.read(data);
return
new
String(data,
"ISO8859-1"
);
}
catch
(Exception e) {
e.printStackTrace();
throw
e;
}
}
/**
* 从给定文件中读取第一行字符串,然后将其
* 转换为一个long值后返回
* @param file
* @return
* @throws Exception
*/
public
static
long
readLong(File file)
throws
Exception{
BufferedReader br =
null
;
try
{
br =
new
BufferedReader(
new
InputStreamReader(
new
FileInputStream(
file
)
)
);
String line = br.readLine();
return
Long.parseLong(line);
}
catch
(Exception e) {
e.printStackTrace();
throw
e;
}
finally
{
if
(br !=
null
){
br.close();
}
}
}
}
|
4. config.xml 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
config
>
<!-- unix系统日志文件名 -->
<
logfile
>wtmpx</
logfile
>
<!-- 保存解析后日志的文件名 -->
<
textlogfile
>log.txt</
textlogfile
>
<!-- 书签文件名 -->
<
lastpositionfile
>last-position.txt</
lastpositionfile
>
<!-- 每次解析日志的条目数 -->
<
batch
>10</
batch
>
<!-- 配对日志文件名 -->
<
logrecfile
>logrec.txt</
logrecfile
>
<!-- 未配对日志文件名 -->
<
loginlogfile
>login.txt</
loginlogfile
>
<!-- 服务端地址 -->
<
serverhost
>localhost</
serverhost
>
<!-- 服务端端口 -->
<
serverport
>8088</
serverport
>
</
config
>
|
5. server-config.xml 。
1
2
3
4
5
6
7
8
9
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
config
>
<!-- 服务端保存配对日志文件的文件名 -->
<
logrecfile
>server-logs.txt</
logrecfile
>
<!-- 线程池线程数量 -->
<
threadsum
>30</
threadsum
>
<!-- 服务端端口 -->
<
serverport
>8088</
serverport
>
</
config
>
|
以上就是本文的全部内容,希望对大家的学习有所帮助.
最后此篇关于java读取用户登入退出日志信息上传服务端的文章就讲到这里了,如果你想了解更多关于java读取用户登入退出日志信息上传服务端的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
这是真的: log(A) + log(B) = log(A * B) [0] 这也是真的吗? O(log(A)) + O(log(B)) = O(log(A * B)) [1] 据我了解 O(f
0 引言 我常以为 配置 INFO 日志级别时, 应用程序代码中日志器(logger) debug 级的日志代码,不会被执行(比如,实验1中的printTestLog函数)。但今天线上的问题,
日志 日志是构建工具的主要界面。如果日志太多,真正的警告和问题容易被隐藏。另一方面,如果出了错,你需要找出相关的信息。Gradle 定义了6个日志级别,如表 18.1,“日志级别”所示。除了那些您通
日志 关键进程日志如下…(将 替换为启动服务的用户,将 替换为计算机名称) NameNode: $ HADOOP_HOME / logs / hadoop- -namenode- .log Da
我正在探索项目的 git 历史 FFMpeg .我在提交之间对每个文件执行了更改 517573a67088b5c7a25c18373434e3448892ee93和 80bb65fafab1d2f5f
我不知道如何在 loggly 中使用正则表达式进行搜索。例如,使用表达式 /24nonstop.+7554/ 记录我想查找的内容. { "level_name": "WARNING", "ex
有没有办法为 API 调用打开日志记录? 我们有一个第三方应用程序在使用我们的商店时遇到问题,希望获得一些调试信息。 ~我已经搜索了 bt 一无所获。 我正在使用 1.7 最佳答案 在一段受控的时间内
我正在尝试获取 SVN 中所有副本/移动/等的固定路径的日志历史记录(如果可能的话,递归地)。实际上,我试图避免 peg revisions ,并将日志应用于路径而不是对象。 svn 手册提出了这个问
如何在命令行中运行 NAnt 脚本并在日志文件中获取每个任务的时间? using nant task or NAnt -buildfile:testscript.build testnanttarg
是否有任何默认方式来记录哪些用户代理访问了您的服务器?我需要编制一份访问我们网站的浏览器列表,以便我们知道我们最能支持什么。 谢谢! 最佳答案 日志CGI.HTTP_USER_AGENT ,也许在 A
我在我的应用程序中使用 Spring 发送电子邮件。 我想在发送电子邮件时记录 imap 服务器操作。 我尝试按如下方式在我的 applicationContext.xml 中实现日志:
我已经运行一个 pod 一个多星期了,从开始到现在没有重启过。但是,我仍然无法查看自它启动以来的日志,它只提供最近两天的日志。容器是否有任何日志轮换策略以及如何根据大小或日期控制轮换? 我尝试了以下命
背景: 我正在设置我的第一个 flex 堆栈,尽管我将开始简单,但是我想确保我从良好的体系结构开始。我最终希望有以下解决方案:托管指标,服务器日志(expressjs APM),单页应用程序监视(AP
常规的 hg log 命令给出每个变更集至少 4 行的输出。例如 changeset: 238:03a214f2a1cf user: My Name date: Th
我在我的项目中使用 Spring iBatis 框架。然后使用 logback 进行记录。然后,在检查日志文件时,我可以看到系统正在使用的数据库...出于安全目的我想隐藏它 这是示例日志.. 12:2
我想使用 hg log 生成一个简短的变更日志,涵盖最新版本的变更。发行版标有“v”前缀,例如“v0.9.1”或“v1.0”。是否可以使用 revsets 选择以“v”开头的最后两个标签之间的范围,不
我是 PHP 的新手,所以如果有一个简单的答案,请原谅我。我在 stackoverflow 中搜索过任何类似的问题,但找不到任何帮助。 我正在开发一个现有的基于 php 的应用程序,我只需要能够将对象
我有一个名为 Radius 的程序可以验证用户登录。运行在CentOS服务器上 日志在/var/log/radius.log 中 它们如下 Mon Jul 24 22:17:08 2017 : Aut
我最近从使用“日志”切换到“日志”。 到目前为止,还不错,但我缺少一项关键功能——在运行时更改最低级别的能力。 在“logging',我可以调用 myLogger.setLevel(logging.I
假设我们有速度关键的系统(例如统计/分析、套接字编程等),我们如何设计跟踪和日志。 更具体地说,日志和跟踪通常会降低性能(即使我们有关闭机制或冗长的扩展机制)。在这种情况下,是否有任何关于如何“放置”
我是一名优秀的程序员,十分优秀!