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
package com.yanzuoguang.log;
import com.yanzuoguang.util.cache.MemoryCache;
import com.yanzuoguang.util.helper.StringHelper;
import com.yanzuoguang.util.thread.ThreadNext;
import com.yanzuoguang.util.vo.CloudConfig;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* 当前线程日志编写
*
* @author 颜佐光
*/
@Component
public class LogLocal implements ThreadNext.Next, InitializingBean {
/**
* 一个请求最多保留60分钟
*/
public static final int CLEAR_CACHE = 60 * 60;
/**
* 超时状态
*/
public static final String MAX_TIME = "MAX_TIME";
public static final String MAX_TIME_NAME = "执行超时";
/**
* 日志基础
*/
private final LogBase logBase;
private final CloudConfig cloudConfig;
private final List<LogFilter> logFilters;
private final LogCountTime logCountTime;
/**
* 缓存队列
*/
protected volatile MemoryCache<Timeout<LogInfoVo>> cache = new MemoryCache<>(CLEAR_CACHE);
public LogLocal(LogBase logBase, CloudConfig cloudConfig, List<LogFilter> logFilters, LogCountTime logCountTime) {
this.logBase = logBase;
this.cloudConfig = cloudConfig;
this.logFilters = logFilters;
this.logCountTime = logCountTime;
}
@Override
public void afterPropertiesSet() {
ThreadNext.start(this, "save log error");
}
/**
* 开始记录日志
*
* @param log 日志对象
*/
public void startLog(LogInfoVo log) {
// 声明超时对象
Timeout<LogInfoVo> time = new Timeout<>(log);
cache.put(log.getLogId(), time);
}
/**
* 写入状态
*
* @param log 日志对象
*/
public void result(LogInfoVo log) {
if (log == null || StringHelper.isEmpty(log.getLogId())) {
return;
}
// 日志请求不记录,防止死循环递归
boolean isLog = isLog(log.getTag(), log.getUrl());
// 全路径
String fullUrl = String.format("%s:%s", tag, url);
// 执行时间
long time = System.currentTimeMillis() - log.getStart();
// 记录请求时间
logCountTime.finish(log);
Timeout<LogInfoVo> timeout;
// 判断是否延时结果
boolean isMaxTime = StringHelper.compare(status, MAX_TIME);
if (isMaxTime) {
timeout = cache.get(log.getLogId());
} else {
timeout = cache.remove(log.getLogId());
}
logBase.addLog(log);
}
/**
* 是否属于日志服务
*
* @param keys 是否需要写入
* @return 是否属于日志服务
*/
public boolean isLog(String... keys) {
List<String> list = new ArrayList<>();
list.add(this.cloudConfig.getApplicationName());
list.addAll(Arrays.asList(keys));
for (LogFilter k : logFilters) {
if (k.logExpect(list)) {
return true;
}
}
for (LogFilter k : logFilters) {
if (k.logFilter(list)) {
return false;
}
}
return true;
}
/**
* 执行下一个函数,出现异常会继续执行
*
* @return 是否继续执行
*/
@Override
public boolean next() {
Collection<Timeout<LogInfoVo>> values = cache.getValues();
for (Timeout<LogInfoVo> timeout : values) {
if (timeout == null) {
continue;
}
// 判断是否达到超时时间
if (timeout.isMaxTime(this.cloudConfig.getLogTimeMax(), this.cloudConfig.getLogTimeSplit())) {
this.result(timeout.getData());
}
}
return true;
}
/**
* 沉睡时间
*
* @return 下次执行时间
*/
@Override
public int getNextTime() {
return 1000;
}
}