代码拉取完成,页面将自动刷新
生成traceId,将traceId加入到RequestHeader中,带入到下游请求中。
@Component
public class TracePreFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return -1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
String traceIdVal = UUID.randomUUID().toString().replaceAll("-","");
MDC.put(LogCollectionConstants.traceId, traceIdVal);
RequestContext ctx = RequestContext.getCurrentContext();
ctx.addZuulRequestHeader(LogCollectionConstants.traceId, traceIdVal);
return null;
}
}
记录请求的详细信息,请求参数,返回值,时长等信息
@Component
@Slf4j
public class LogFilter extends ZuulFilter {
public static final String START_TIME_KEY = "start_time";
@Override
public String filterType() {
return FilterConstants.POST_TYPE;
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
try {
HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
RequestContext.getCurrentContext().set(START_TIME_KEY, System.currentTimeMillis());
HttpEntity httpEntity = new HttpEntity();
httpEntity.setMethod(request.getMethod());
httpEntity.setUrl(request.getRequestURI());
httpEntity.setIp(request.getRemoteAddr());
HashMap<String, Object> parameter = showParams(request);
httpEntity.setParameter(JSON.toJSONString(parameter));
httpEntity.setUserAgent(request.getHeader("user-agent"));
String body = "";
InputStream stream = RequestContext.getCurrentContext().getResponseDataStream();
byte[] bytes = StreamUtils.copyToByteArray(stream);
body = new String(bytes, StandardCharsets.UTF_8);
httpEntity.setResult(body);
long startTime = (long) RequestContext.getCurrentContext().get(START_TIME_KEY);
httpEntity.setLaunchTime(new Date(startTime));
httpEntity.setDuration(System.currentTimeMillis() - startTime);
httpEntity.setTraceId(RequestContext.getCurrentContext().getZuulRequestHeaders().get(LogCollectionConstants.traceId));
log.info("接口统计 {}",JSON.toJSONString(httpEntity));
RequestContext.getCurrentContext().setResponseBody(body);
} catch (Exception e) {
log.error("日志统计失败", e);
return true;
}
return true;
}
public static HashMap<String, Object> showParams(HttpServletRequest request) {
HashMap<String, Object> map = new HashMap<>();
Enumeration paramNames = request.getParameterNames();
while (paramNames.hasMoreElements()) {
String paramName = (String) paramNames.nextElement();
String[] paramValues = request.getParameterValues(paramName);
if (paramValues.length > 0) {
String paramValue = paramValues[0];
if (paramValue.length() != 0) {
map.put(paramName, paramValue);
}
}
}
return map;
}
}
注册过滤器 ,将上游请求中traceId值取出。使用MDC类将内容记录到日志中
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TraceInterceptor()).addPathPatterns("/**");
super.addInterceptors(registry);
}
}
public class TraceInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String traceIdVal = request.getHeader(LogCollectionConstants.traceId);
if (StringUtils.isNotEmpty(traceIdVal)) {
MDC.put(LogCollectionConstants.traceId, traceIdVal);
}
return true;
}
}
@Configuration
public class HystrixConfig extends LogHystrixConfig {
public HystrixConfig(){
super();
}
}
public class LogHystrixConfig {
public static final Logger log = LoggerFactory.getLogger(LogHystrixConfig.class);
public LogHystrixConfig(){
try {
HystrixConcurrencyStrategy target = new MdcHystrixConcurrencyStrategy();
HystrixConcurrencyStrategy strategy = HystrixPlugins.getInstance().getConcurrencyStrategy();
if (strategy instanceof MdcHystrixConcurrencyStrategy) {
return;
}
HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins
.getInstance().getCommandExecutionHook();
HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance()
.getEventNotifier();
HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance()
.getMetricsPublisher();
HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance()
.getPropertiesStrategy();
HystrixPlugins.reset();
HystrixPlugins.getInstance().registerConcurrencyStrategy(target);
HystrixPlugins.getInstance()
.registerCommandExecutionHook(commandExecutionHook);
HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
}
catch (Exception e) {
log.error("Failed to register Sleuth Hystrix Concurrency Strategy", e);
}
}
}
@Configuration
public class FeignInterceptorConfig extends LogFeignInterceptorConfig implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
requestTemplate.header(LogCollectionConstants.traceId, super.getTraceId());
}
}
public class LogFeignInterceptorConfig {
public String getTraceId() {
return MDC.get(LogCollectionConstants.traceId);
}
}
定时任务在开始执行之前,给MDC类 赋值traceId
@Aspect
@Component
@Slf4j
public class ScheduledAspect {
@Pointcut("@annotation(org.springframework.scheduling.annotation.Scheduled)")
public void proxyAspect() {
}
@Before("proxyAspect()")
public void before(JoinPoint joinPoint) throws Throwable {
String traceId= LogHelper.getTraceId();
MDC.put(LogCollectionConstants.traceId, traceId);
}
}
使用{traceId}写入MDC中的traceId的值
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }) [%X{traceId}] %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } [%X{traceId}] --- [%t] : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
在Service1中写入测试接口
@RestController
@Slf4j
public class UserController {
@GetMapping("/user/getlist")
public List<String> getlist() {
log.info("测试接口user");
List<String> list = asList("user1", "user2", "user3");
log.warn("测测测");
return list;
}
}
通过网关请求接口效果如下
网关中打印日志 通过日志找到traceId为40417dd85d224eda8d67925dce335b6b Service1中的日志
测试代码 Service1中
@RestController
@Slf4j
public class UserController {
@Autowired
private DemoApiClient demoApiClient;
@GetMapping("/user/getlist2")
public List<String> getlist2() {
log.info("测试接口getlist2");
List<String> result = demoApiClient.getlist2();
log.info("请求Service2中接口成功,返回数据");
return result;
}
}
Service2中
@RestController
@Slf4j
public class DemoController {
@GetMapping("/demo/getlist2")
public List<String> getlist2() {
log.info("通过了其他的服务请求过来");
List<String> list = asList("haha", "hehe", "youyou");
log.info("请求完了");
return list;
}
}
通过网关查到traceId为f87e568753004b7e830e76497936fb08 Service1中打印日志 Service2中打印日志
在Service1中加入测试代码
@Component
@Slf4j
public class TestJob {
@Autowired
private DemoApiClient demoApiClient;
@Scheduled(fixedRate = 2000)
public void execute() {
List<String> result = demoApiClient.getlist2();
log.info("定时任务执行 打印获取数据结果 {} ", result);
}
}
在任务中找到一条执行记录中的traceId:56fda9d194e241f9a32e6c1ecf61ee58
在Service2中查看打印日志
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。