Optimize log output and support route mapping multi app

This commit is contained in:
hongqiaowei
2021-11-05 18:16:06 +08:00
parent de704233a5
commit 96eecc3899
14 changed files with 91 additions and 90 deletions

View File

@@ -109,7 +109,8 @@ public class ApiPairingController {
}
boolean equals = ApiPairingUtils.checkSign(appId, timestamp, app.secretkey, sign);
if (!equals) {
log.warn("{}request authority: app {}, timestamp {}, sign {} invalid", exchange.getLogPrefix(), appId, timestamp, sign, LogService.BIZ_ID, WebUtils.getTraceId(exchange));
String traceId = WebUtils.getTraceId(exchange);
log.warn("{} request authority: app {}, timestamp {}, sign {} invalid", traceId, appId, timestamp, sign, LogService.BIZ_ID, traceId);
return Result.fail("request sign invalid");
}
return Result.succ();

View File

@@ -142,7 +142,7 @@ public class AggregateFilter implements WebFilter {
final String traceId = WebUtils.getTraceId(exchange);
LogService.setBizId(traceId);
LOGGER.debug("matched api in aggregation: {}", path);
LOGGER.debug("{} matched api in aggregation: {}", traceId, path);
// 客户端提交上来的信息
Map<String, Object> clientInput = new HashMap<>();
@@ -195,7 +195,7 @@ public class AggregateFilter implements WebFilter {
jsonString = JSON.toJSONString(aggResult.getBody());
}
}
LOGGER.debug("response body: {}", jsonString);
LOGGER.debug("{} response body: {}", traceId, jsonString);
if (aggResult.getHeaders() != null && !aggResult.getHeaders().isEmpty()) {
serverHttpResponse.getHeaders().addAll(aggResult.getHeaders());
serverHttpResponse.getHeaders().remove(CommonConstants.HEADER_CONTENT_LENGTH);
@@ -211,7 +211,7 @@ public class AggregateFilter implements WebFilter {
long end = System.currentTimeMillis();
pipeline.getStepContext().addElapsedTime("总耗时", end - start);
LOGGER.info("ElapsedTimes={}", JSON.toJSONString(pipeline.getStepContext().getElapsedTimes()));
LOGGER.info("{} ElapsedTimes={}", traceId, JSON.toJSONString(pipeline.getStepContext().getElapsedTimes()));
return serverHttpResponse
.writeWith(Flux.just(exchange.getResponse().bufferFactory().wrap(jsonString.getBytes())));

View File

@@ -101,7 +101,7 @@ public class FilterExceptionHandlerConfig {
if (t instanceof FizzRuntimeException) {
FizzRuntimeException ex = (FizzRuntimeException) t;
log.error(tMsg, LogService.BIZ_ID, traceId, ex);
log.error(traceId + ' ' + tMsg, LogService.BIZ_ID, traceId, ex);
resp.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
RespEntity rs = null;
if (ex.getStepContext() != null && ex.getStepContext().returnContext()) {

View File

@@ -131,9 +131,9 @@ public class FlowControlFilter extends FizzWebFilter {
if (result != null && !result.isSuccess()) {
String blockedResourceId = result.getBlockedResourceId();
if (BlockType.CONCURRENT_REQUEST == result.getBlockType()) {
log.info("exceed {} flow limit, blocked by maximum concurrent requests", blockedResourceId, LogService.BIZ_ID, traceId);
log.info("{} exceed {} flow limit, blocked by maximum concurrent requests", traceId, blockedResourceId, LogService.BIZ_ID, traceId);
} else {
log.info("exceed {} flow limit, blocked by maximum QPS", blockedResourceId, LogService.BIZ_ID, traceId);
log.info("{} exceed {} flow limit, blocked by maximum QPS", traceId, blockedResourceId, LogService.BIZ_ID, traceId);
}
ResourceRateLimitConfig c = resourceRateLimitConfigService.getResourceRateLimitConfig(ResourceRateLimitConfig.NODE_RESOURCE);

View File

@@ -80,7 +80,7 @@ public class RouteFilter extends FizzWebFilter {
if (resp == null) { // should not reach here
ServerHttpRequest clientReq = exchange.getRequest();
String traceId = WebUtils.getTraceId(exchange);
String msg = pfr.id + " fail";
String msg = traceId + ' ' + pfr.id + " fail";
if (pfr.cause == null) {
log.error(msg, LogService.BIZ_ID, traceId);
} else {

View File

@@ -52,15 +52,15 @@ public abstract class PluginFilter implements FizzPluginFilter {
public Mono<Void> filter(ServerWebExchange exchange, Map<String, Object> config, String fixedConfig) {
FilterResult pfr = WebUtils.getPrevFilterResult(exchange);
String traceId = WebUtils.getTraceId(exchange);
if (log.isDebugEnabled()) {
log.debug(this + ": " + pfr.id + " execute " + (pfr.success ? "success" : "fail"), LogService.BIZ_ID, WebUtils.getTraceId(exchange));
log.debug(traceId + ' ' + this + ": " + pfr.id + " execute " + (pfr.success ? "success" : "fail"), LogService.BIZ_ID, traceId);
}
if (pfr.success) {
return doFilter(exchange, config, fixedConfig);
} else {
if (WebUtils.getDirectResponse(exchange) == null) { // should not reach here
String traceId = WebUtils.getTraceId(exchange);
String msg = pfr.id + " fail";
String msg = traceId + ' ' + pfr.id + " fail";
if (pfr.cause == null) {
log.error(msg, LogService.BIZ_ID, traceId);
} else {

View File

@@ -386,7 +386,6 @@ public class ApiConfigService implements ApplicationListener<ContextRefreshedEve
b.append(service).append(" don't have api config matching ").append(gatewayGroups).append(" group ").append(method).append(" method ").append(path).append(" path");
return Result.fail(b.toString());
}
// List<ApiConfig> appCanAccess = ThreadContext.getArrayList(macs);
List<ApiConfig> appCanAccess = ThreadContext.getArrayList();
for (int i = 0; i < apiConfigs.size(); i++) {
ApiConfig ac = apiConfigs.get(i);
@@ -428,7 +427,6 @@ public class ApiConfigService implements ApplicationListener<ContextRefreshedEve
public Mono<Result<ApiConfig>> auth(ServerWebExchange exchange) {
ServerHttpRequest req = exchange.getRequest();
HttpHeaders hdrs = req.getHeaders();
LogService.setBizId(WebUtils.getTraceId(exchange));
return auth(exchange, WebUtils.getAppId(exchange), WebUtils.getOriginIp(exchange), WebUtils.getTimestamp(exchange), WebUtils.getSign(exchange),
WebUtils.getClientService(exchange), req.getMethod(), WebUtils.getClientReqPath(exchange));

View File

@@ -52,7 +52,8 @@ public class AuthPluginFilter extends PluginFilter {
return apiConfigService.auth(exchange).flatMap(
r -> {
if (log.isDebugEnabled()) {
log.debug("req auth: {}", r, LogService.BIZ_ID, WebUtils.getTraceId(exchange));
String traceId = WebUtils.getTraceId(exchange);
log.debug("{} req auth: {}", traceId, r, LogService.BIZ_ID, traceId);
}
Map<String, Object> data = Collections.singletonMap(RESULT, r);
return WebUtils.transmitSuccessFilterResultAndEmptyMono(exchange, AUTH_PLUGIN_FILTER, data);

View File

@@ -38,7 +38,7 @@ public class ServiceConfig {
public Map<String/*gateway group*/,
Map<Object/*method*/,
Map<String/*path patten*/, ApiConfig>
Map<String/*path patten*/, Set<ApiConfig>>
>
>
apiConfigMap = new HashMap<>();
@@ -49,34 +49,32 @@ public class ServiceConfig {
public void add(ApiConfig ac) {
for (String gatewayGroup : ac.gatewayGroups) {
Map<Object, Map<String, ApiConfig>> method2pathPattenMap = apiConfigMap.get(gatewayGroup);
if (method2pathPattenMap == null) {
method2pathPattenMap = new HashMap<>();
apiConfigMap.put(gatewayGroup, method2pathPattenMap);
}
Map<String, ApiConfig> pathPattern2apiConfigMap = method2pathPattenMap.get(ac.fizzMethod);
if (pathPattern2apiConfigMap == null) {
pathPattern2apiConfigMap = new HashMap<>();
method2pathPattenMap.put(ac.fizzMethod, pathPattern2apiConfigMap);
}
pathPattern2apiConfigMap.put(ac.path, ac);
Map<Object, Map<String, Set<ApiConfig>>> method2pathPattenMap = apiConfigMap.computeIfAbsent(gatewayGroup, k -> new HashMap<>());
Map<String, Set<ApiConfig>> pathPattern2apiConfigsMap = method2pathPattenMap.computeIfAbsent(ac.fizzMethod, k -> new HashMap<>());
Set<ApiConfig> apiConfigs = pathPattern2apiConfigsMap.computeIfAbsent(ac.path, k -> new HashSet<>());
apiConfigs.add(ac);
}
log.info("{} service add api config: {}", id, ac);
}
public void remove(ApiConfig ac) {
for (String gatewayGroup : ac.gatewayGroups) {
Map<Object, Map<String, ApiConfig>> method2pathPattenMap = apiConfigMap.get(gatewayGroup);
Map<Object, Map<String, Set<ApiConfig>>> method2pathPattenMap = apiConfigMap.get(gatewayGroup);
if (method2pathPattenMap != null) {
Map<String, ApiConfig> pathPattern2apiConfigMap = method2pathPattenMap.get(ac.fizzMethod);
if (pathPattern2apiConfigMap != null) {
pathPattern2apiConfigMap.remove(ac.path);
if (pathPattern2apiConfigMap.isEmpty()) {
method2pathPattenMap.remove(ac.fizzMethod);
if (method2pathPattenMap.isEmpty()) {
apiConfigMap.remove(gatewayGroup);
}
Map<String, Set<ApiConfig>> pathPattern2apiConfigsMap = method2pathPattenMap.get(ac.fizzMethod);
if (pathPattern2apiConfigsMap != null) {
Set<ApiConfig> apiConfigs = pathPattern2apiConfigsMap.get(ac.path);
if (apiConfigs != null) {
apiConfigs.remove(ac);
if (apiConfigs.isEmpty()) {
pathPattern2apiConfigsMap.remove(ac.path);
if (pathPattern2apiConfigsMap.isEmpty()) {
method2pathPattenMap.remove(ac.fizzMethod);
if (method2pathPattenMap.isEmpty()) {
apiConfigMap.remove(gatewayGroup);
}
}
}
}
}
}
@@ -85,21 +83,14 @@ public class ServiceConfig {
}
public void update(ApiConfig ac) {
ApiConfig prevApiConfig = null;
for (String gatewayGroup : ac.gatewayGroups) {
Map<Object, Map<String, ApiConfig>> method2pathPattenMap = apiConfigMap.get(gatewayGroup);
if (method2pathPattenMap == null) {
method2pathPattenMap = new HashMap<>();
apiConfigMap.put(gatewayGroup, method2pathPattenMap);
}
Map<String, ApiConfig> pathPattern2apiConfigMap = method2pathPattenMap.get(ac.fizzMethod);
if (pathPattern2apiConfigMap == null) {
pathPattern2apiConfigMap = new HashMap<>();
method2pathPattenMap.put(ac.fizzMethod, pathPattern2apiConfigMap);
}
prevApiConfig = pathPattern2apiConfigMap.put(ac.path, ac);
Map<Object, Map<String, Set<ApiConfig>>> method2pathPattenMap = apiConfigMap.computeIfAbsent(gatewayGroup, k -> new HashMap<>());
Map<String, Set<ApiConfig>> pathPattern2apiConfigsMap = method2pathPattenMap.computeIfAbsent(ac.fizzMethod, k -> new HashMap<>());
Set<ApiConfig> apiConfigs = pathPattern2apiConfigsMap.computeIfAbsent(ac.path, k -> new HashSet<>());
apiConfigs.remove(ac);
apiConfigs.add(ac);
}
log.info("{} service update api config {} with {}", id, prevApiConfig, ac);
log.info("{} service update api config: {}", id, ac);
}
@JsonIgnore
@@ -114,37 +105,46 @@ public class ServiceConfig {
@JsonIgnore
public List<ApiConfig> getApiConfigs(String gatewayGroup, HttpMethod method, String path) {
Map<Object, Map<String, ApiConfig>> method2pathPattenMap = apiConfigMap.get(gatewayGroup);
Map<Object, Map<String, Set<ApiConfig>>> method2pathPattenMap = apiConfigMap.get(gatewayGroup);
if (method2pathPattenMap == null) {
return Collections.emptyList();
} else {
ArrayList<ApiConfig> result = ThreadContext.getArrayList();
Map<String, ApiConfig> pathPattern2apiConfigMap = method2pathPattenMap.get(method);
if (pathPattern2apiConfigMap != null) {
checkPathPattern(pathPattern2apiConfigMap, path, result);
Map<String, Set<ApiConfig>> pathPattern2apiConfigsMap = method2pathPattenMap.get(method);
if (pathPattern2apiConfigsMap != null) {
checkPathPattern(pathPattern2apiConfigsMap, path, result);
}
pathPattern2apiConfigMap = method2pathPattenMap.get(ApiConfig.ALL_METHOD);
if (pathPattern2apiConfigMap != null) {
checkPathPattern(pathPattern2apiConfigMap, path, result);
pathPattern2apiConfigsMap = method2pathPattenMap.get(ApiConfig.ALL_METHOD);
if (pathPattern2apiConfigsMap != null) {
checkPathPattern(pathPattern2apiConfigsMap, path, result);
}
return result;
}
}
private void checkPathPattern(Map<String, ApiConfig> pathPattern2apiConfigMap, String path, ArrayList<ApiConfig> result) {
Set<Map.Entry<String, ApiConfig>> entries = pathPattern2apiConfigMap.entrySet();
for (Map.Entry<String, ApiConfig> entry : entries) {
String pathPattern = entry.getKey();
ApiConfig apiConfig = entry.getValue();
if (apiConfig.access == ApiConfig.ALLOW) {
if (apiConfig.exactMatch) {
if (pathPattern.equals(path)) {
result.add(apiConfig);
return;
private void checkPathPattern(Map<String, Set<ApiConfig>> pathPattern2apiConfigMap, String path, ArrayList<ApiConfig> result) {
Set<Map.Entry<String, Set<ApiConfig>>> entries = pathPattern2apiConfigMap.entrySet();
boolean clear = false;
for (Map.Entry<String, Set<ApiConfig>> entry : entries) {
String pathPattern = entry.getKey();
Set<ApiConfig> apiConfigs = entry.getValue();
if (pathPattern.equals(path)) {
for (ApiConfig ac : apiConfigs) {
if (ac.access == ApiConfig.ALLOW) {
if (!clear && !result.isEmpty()) {
result.clear();
clear = true;
}
result.add(ac);
}
} else {
if (UrlTransformUtils.ANT_PATH_MATCHER.match(pathPattern, path)) {
result.add(apiConfig);
}
if (clear && !result.isEmpty()) {
return;
}
} else if (UrlTransformUtils.ANT_PATH_MATCHER.match(pathPattern, path)) {
for (ApiConfig ac : apiConfigs) {
if (ac.access == ApiConfig.ALLOW) {
result.add(ac);
}
}
}

View File

@@ -78,7 +78,6 @@ public class RequestBodyPlugin implements FizzPluginFilter {
String traceId = WebUtils.getTraceId(exchange);
log.debug("{} request is decorated", traceId, LogService.BIZ_ID, traceId);
}
// return FizzPluginFilterChain.next(newExchange);
return doFilter(newExchange, config);
}
);

View File

@@ -81,10 +81,10 @@ public class CallbackService {
public Mono<Void> requestBackends(ServerWebExchange exchange, HttpHeaders headers, DataBuffer body, CallbackConfig cc, Map<String, ServiceInstance> service2instMap) {
ServerHttpRequest req = exchange.getRequest();
String reqId = WebUtils.getTraceId(exchange);
String traceId = WebUtils.getTraceId(exchange);
HttpMethod method = req.getMethod();
if (log.isDebugEnabled()) {
log.debug("service2instMap: " + JacksonUtils.writeValueAsString(service2instMap), LogService.BIZ_ID, reqId);
log.debug(traceId + " service2instMap: " + JacksonUtils.writeValueAsString(service2instMap), LogService.BIZ_ID, traceId);
}
int rs = cc.receivers.size();
Mono<Object>[] sends = new Mono[rs];
@@ -94,11 +94,11 @@ public class CallbackService {
if (r.type == ApiConfig.Type.SERVICE_DISCOVERY) {
ServiceInstance si = service2instMap.get(r.service);
if (si == null) {
send = fizzWebClient.send2service(reqId, method, r.service, r.path, headers, body)
send = fizzWebClient.send2service(traceId, method, r.service, r.path, headers, body)
.onErrorResume( crError(exchange, r, method, headers, body) );
} else {
String uri = buildUri(req, si, r.path);
send = fizzWebClient.send(reqId, method, uri, headers, body)
send = fizzWebClient.send(traceId, method, uri, headers, body)
.onErrorResume( crError(exchange, r, method, headers, body) );
}
} else {
@@ -154,9 +154,9 @@ public class CallbackService {
StringBuilder b = ThreadContext.getStringBuilder();
WebUtils.request2stringBuilder(exchange, b);
b.append(Consts.S.LINE_SEPARATOR).append(callback).append(Consts.S.LINE_SEPARATOR);
String id = WebUtils.getTraceId(exchange);
WebUtils.request2stringBuilder(id, method, r.service + Consts.S.FORWARD_SLASH + r.path, headers, body, b);
log.error(b.toString(), LogService.BIZ_ID, id, t);
String traceId = WebUtils.getTraceId(exchange);
WebUtils.request2stringBuilder(traceId, method, r.service + Consts.S.FORWARD_SLASH + r.path, headers, body, b);
log.error(b.toString(), LogService.BIZ_ID, traceId, t);
}
private String buildUri(ServerHttpRequest req, ServiceInstance si, String path) {

View File

@@ -422,8 +422,8 @@ public abstract class WebUtils {
request2stringBuilder(WebUtils.getTraceId(exchange), req.getMethod(), req.getURI().toString(), req.getHeaders(), null, b);
}
public static void request2stringBuilder(String reqId, HttpMethod method, String uri, HttpHeaders headers, Object body, StringBuilder b) {
b.append(reqId).append(Consts.S.SPACE).append(method).append(Consts.S.SPACE).append(uri);
public static void request2stringBuilder(String traceId, HttpMethod method, String uri, HttpHeaders headers, Object body, StringBuilder b) {
b.append(traceId).append(Consts.S.SPACE).append(method).append(Consts.S.SPACE).append(uri);
if (headers != null) {
final boolean[] f = {false};
LOG_HEADER_SET.forEach(
@@ -760,12 +760,12 @@ public abstract class WebUtils {
@Deprecated
public static Mono<Void> responseErrorAndBindContext(ServerWebExchange exchange, String filter, HttpStatus httpStatus) {
ServerHttpResponse response = exchange.getResponse();
String rid = getTraceId(exchange);
String traceId = getTraceId(exchange);
StringBuilder b = ThreadContext.getStringBuilder();
request2stringBuilder(exchange, b);
b.append(Consts.S.LINE_SEPARATOR);
b.append(filter).append(Consts.S.SPACE).append(httpStatus);
log.error(b.toString(), LogService.BIZ_ID, rid);
log.error(b.toString(), LogService.BIZ_ID, traceId);
transmitFailFilterResult(exchange, filter);
return buildDirectResponseAndBindContext(exchange, httpStatus, new HttpHeaders(), Consts.S.EMPTY);
}
@@ -774,12 +774,12 @@ public abstract class WebUtils {
public static Mono<Void> responseErrorAndBindContext(ServerWebExchange exchange, String filter, HttpStatus httpStatus,
HttpHeaders headers, String content) {
ServerHttpResponse response = exchange.getResponse();
String rid = getTraceId(exchange);
String traceId = getTraceId(exchange);
StringBuilder b = ThreadContext.getStringBuilder();
request2stringBuilder(exchange, b);
b.append(Consts.S.LINE_SEPARATOR);
b.append(filter).append(Consts.S.SPACE).append(httpStatus);
log.error(b.toString(), LogService.BIZ_ID, rid);
log.error(b.toString(), LogService.BIZ_ID, traceId);
transmitFailFilterResult(exchange, filter);
headers = headers == null ? new HttpHeaders() : headers;
content = StringUtils.isBlank(content) ? Consts.S.EMPTY : content;

View File

@@ -55,6 +55,7 @@ public class ApiDocAuthPluginFilter implements FizzPluginFilter {
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Mono<Void> filter(ServerWebExchange exchange, Map<String, Object> config) {
String traceId = WebUtils.getTraceId(exchange);
try {
String appId = WebUtils.getAppId(exchange);
String service = WebUtils.getClientService(exchange);
@@ -74,13 +75,13 @@ public class ApiDocAuthPluginFilter implements FizzPluginFilter {
response.getHeaders().setCacheControl("no-store");
response.getHeaders().setExpires(0);
String respJson = WebUtils.jsonRespBody(HttpStatus.UNAUTHORIZED.value(),
HttpStatus.UNAUTHORIZED.getReasonPhrase(), WebUtils.getTraceId(exchange));
HttpStatus.UNAUTHORIZED.getReasonPhrase(), traceId);
return WebUtils.response(exchange, HttpStatus.UNAUTHORIZED, null, respJson);
}
} catch (Exception e) {
log.error("{} exception", API_DOC_AUTH_PLUGIN_FILTER, e);
log.error("{} {} exception", traceId, API_DOC_AUTH_PLUGIN_FILTER, e);
String respJson = WebUtils.jsonRespBody(HttpStatus.INTERNAL_SERVER_ERROR.value(),
HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), WebUtils.getTraceId(exchange));
HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), traceId);
return WebUtils.response(exchange, HttpStatus.INTERNAL_SERVER_ERROR, null, respJson);
}
}

View File

@@ -61,8 +61,9 @@ public class ApiPairingPluginFilter implements FizzPluginFilter {
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Mono<Void> filter(ServerWebExchange exchange, Map<String, Object> config) {
String traceId = WebUtils.getTraceId(exchange);
try {
LogService.setBizId(WebUtils.getTraceId(exchange));
LogService.setBizId(traceId);
String appid = WebUtils.getAppId(exchange);
App app = appService.getApp(appid);
String ts = WebUtils.getTimestamp(exchange);
@@ -81,13 +82,13 @@ public class ApiPairingPluginFilter implements FizzPluginFilter {
response.getHeaders().setCacheControl("no-store");
response.getHeaders().setExpires(0);
String respJson = WebUtils.jsonRespBody(HttpStatus.UNAUTHORIZED.value(),
HttpStatus.UNAUTHORIZED.getReasonPhrase(), WebUtils.getTraceId(exchange));
HttpStatus.UNAUTHORIZED.getReasonPhrase(), traceId);
return WebUtils.response(exchange, HttpStatus.UNAUTHORIZED, null, respJson);
}
} catch (Exception e) {
log.error("{} Exception", API_PAIRING_PLUGIN_FILTER, e);
log.error("{} {} Exception", traceId, API_PAIRING_PLUGIN_FILTER, e, LogService.BIZ_ID, traceId);
String respJson = WebUtils.jsonRespBody(HttpStatus.INTERNAL_SERVER_ERROR.value(),
HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), WebUtils.getTraceId(exchange));
HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), traceId);
return WebUtils.response(exchange, HttpStatus.INTERNAL_SERVER_ERROR, null, respJson);
}
}