spring HttpExchangeTracer 源码
springboot HttpExchangeTracer 代码
文件路径:/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/trace/http/HttpExchangeTracer.java
/*
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.trace.http;
import java.net.URI;
import java.security.Principal;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import org.springframework.http.HttpHeaders;
/**
* Traces an HTTP request-response exchange.
*
* @author Andy Wilkinson
* @since 2.0.0
*/
public class HttpExchangeTracer {
private final Set<Include> includes;
/**
* Creates a new {@code HttpExchangeTracer} that will use the given {@code includes}
* to determine the contents of its traces.
* @param includes the includes
*/
public HttpExchangeTracer(Set<Include> includes) {
this.includes = includes;
}
/**
* Begins the tracing of the exchange that was initiated by the given {@code request}
* being received.
* @param request the received request
* @return the HTTP trace for the
*/
public final HttpTrace receivedRequest(TraceableRequest request) {
return new HttpTrace(new FilteredTraceableRequest(request));
}
/**
* Ends the tracing of the exchange that is being concluded by sending the given
* {@code response}.
* @param trace the trace for the exchange
* @param response the response that concludes the exchange
* @param principal a supplier for the exchange's principal
* @param sessionId a supplier for the id of the exchange's session
*/
public final void sendingResponse(HttpTrace trace, TraceableResponse response, Supplier<Principal> principal,
Supplier<String> sessionId) {
setIfIncluded(Include.TIME_TAKEN, () -> calculateTimeTaken(trace), trace::setTimeTaken);
setIfIncluded(Include.SESSION_ID, sessionId, trace::setSessionId);
setIfIncluded(Include.PRINCIPAL, principal, trace::setPrincipal);
trace.setResponse(new HttpTrace.Response(new FilteredTraceableResponse(response)));
}
/**
* Post-process the given mutable map of request {@code headers}.
* @param headers the headers to post-process
*/
protected void postProcessRequestHeaders(Map<String, List<String>> headers) {
}
private <T> T getIfIncluded(Include include, Supplier<T> valueSupplier) {
return this.includes.contains(include) ? valueSupplier.get() : null;
}
private <T> void setIfIncluded(Include include, Supplier<T> supplier, Consumer<T> consumer) {
if (this.includes.contains(include)) {
consumer.accept(supplier.get());
}
}
private Map<String, List<String>> getHeadersIfIncluded(Include include,
Supplier<Map<String, List<String>>> headersSupplier, Predicate<String> headerPredicate) {
if (!this.includes.contains(include)) {
return new LinkedHashMap<>();
}
return headersSupplier.get().entrySet().stream().filter((entry) -> headerPredicate.test(entry.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
private long calculateTimeTaken(HttpTrace trace) {
return TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - trace.getStartNanoTime());
}
private final class FilteredTraceableRequest implements TraceableRequest {
private final TraceableRequest delegate;
private FilteredTraceableRequest(TraceableRequest delegate) {
this.delegate = delegate;
}
@Override
public String getMethod() {
return this.delegate.getMethod();
}
@Override
public URI getUri() {
return this.delegate.getUri();
}
@Override
public Map<String, List<String>> getHeaders() {
Map<String, List<String>> headers = getHeadersIfIncluded(Include.REQUEST_HEADERS, this.delegate::getHeaders,
this::includedHeader);
postProcessRequestHeaders(headers);
return headers;
}
private boolean includedHeader(String name) {
if (name.equalsIgnoreCase(HttpHeaders.COOKIE)) {
return HttpExchangeTracer.this.includes.contains(Include.COOKIE_HEADERS);
}
if (name.equalsIgnoreCase(HttpHeaders.AUTHORIZATION)) {
return HttpExchangeTracer.this.includes.contains(Include.AUTHORIZATION_HEADER);
}
return true;
}
@Override
public String getRemoteAddress() {
return getIfIncluded(Include.REMOTE_ADDRESS, this.delegate::getRemoteAddress);
}
}
private final class FilteredTraceableResponse implements TraceableResponse {
private final TraceableResponse delegate;
private FilteredTraceableResponse(TraceableResponse delegate) {
this.delegate = delegate;
}
@Override
public int getStatus() {
return this.delegate.getStatus();
}
@Override
public Map<String, List<String>> getHeaders() {
return getHeadersIfIncluded(Include.RESPONSE_HEADERS, this.delegate::getHeaders, this::includedHeader);
}
private boolean includedHeader(String name) {
if (name.equalsIgnoreCase(HttpHeaders.SET_COOKIE)) {
return HttpExchangeTracer.this.includes.contains(Include.COOKIE_HEADERS);
}
return true;
}
}
}
相关信息
相关文章
0
赞
- 所属分类: 后端技术
- 本文标签: Spring Boot Java Spring
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦