SpringColud网关加日志

GatewayFilter.java

package com.xxxx.gateway.filter;

import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.util.AntPathMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.factory.rewrite.CachedBodyOutputMessage;
import org.springframework.cloud.gateway.support.BodyInserterContext;
import org.springframework.cloud.gateway.support.DefaultServerRequest;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ReactiveHttpOutputMessage;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserter;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.server.ServerWebExchange;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;


import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.JwtException;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;


@Component
@ConfigurationProperties("jwt")
@Setter
@Getter
@Slf4j
public class GatewayFilter implements GlobalFilter,Ordered {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Resource RedisConfigX redisConfigX;

    /**
     * 过滤器
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        String url = request.getURI().getPath();
        AntPathMatcher antPathMatcher = new AntPathMatcher();


          try{

                    .................code


                return authErro(locale,response,Errcode.RoleError,HttpStatus.FORBIDDEN);
            }catch (JwtException e){
                return authErro(locale,response,Errcode.JwtTokenFilterError,HttpStatus.INTERNAL_SERVER_ERROR);
            }catch (Exception e) {

                return authErro(locale,response,Errcode.JwtTokenFilterError,HttpStatus.INTERNAL_SERVER_ERROR);
            }finally {

                if(recordOperationLog && isAuthPass) {
                    String operationUser = null!=user?user.getAccount():"";
                    String ip = this.getRemoteHost(request);
                    MediaType mediaType = request.getHeaders().getContentType();
                    if(mediaType != null && (MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(mediaType) || MediaType.APPLICATION_JSON.isCompatibleWith(mediaType))){

                        //判断过滤器是否执行
                        String contentType = request.getHeaders().getFirst("Content-Type");
                        String method = request.getMethodValue();
                        //判断是否为POST请求
                        if (null != contentType && HttpMethod.POST.name().equalsIgnoreCase(method) ) {

                            ServerRequest serverRequest = new DefaultServerRequest(exchange);
                            List<String> list = new ArrayList<>();
                            // 读取请求体
                            Mono<String> modifiedBody = serverRequest.bodyToMono(String.class)
                                    .flatMap(body -> {
                                        //记录请求体日志
                                        if(null!=body && body.length()>1000) {
                                            setOperationLog(operationUser,ip,url,body.substring(0,1000));
                                        }else {
                                            setOperationLog(operationUser,ip,url,body);
                                        }
                                        return Mono.just(body);
                                    });

                            //BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, String.class);
                            BodyInserter<Mono<String>, ReactiveHttpOutputMessage> bodyInserter = BodyInserters.fromPublisher(modifiedBody, String.class);

                            HttpHeaders headers = new HttpHeaders();
                            headers.putAll(exchange.getRequest().getHeaders());
                            headers.remove(HttpHeaders.CONTENT_LENGTH);

                            CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);
                            return bodyInserter.insert(outputMessage, new BodyInserterContext())
                                    .then(Mono.defer(() -> {
                                        ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(
                                                exchange.getRequest()) {
                                            @Override
                                            public HttpHeaders getHeaders() {
                                                long contentLength = headers.getContentLength();
                                                HttpHeaders httpHeaders = new HttpHeaders();
                                                httpHeaders.putAll(super.getHeaders());
                                                httpHeaders.put("traceId",list);
                                                if (contentLength > 0) {
                                                    httpHeaders.setContentLength(contentLength);
                                                } else {
                                                    httpHeaders.set(HttpHeaders.TRANSFER_ENCODING, "chunked");
                                                }
                                                return httpHeaders;
                                            }

                                            @Override
                                            public Flux<DataBuffer> getBody() {
                                                return outputMessage.getBody();
                                            }
                                        };

                                        return chain.filter(exchange.mutate().request(decorator).build());
                                    }));
                        }
                    }else{
                        setOperationLog(operationUser,ip,url,exchange.getRequest().getQueryParams().toString());
                    }


                }


            }
        }

    }




    private void setOperationLog(String account,String ip,String url,String params) {
        AntPathMatcher antPathMatcher = new AntPathMatcher();

        boolean skipLog = false;
        if(null != skipLogUrls){
            for (String skipLogUrl : skipLogUrls) {
                if(antPathMatcher.match(skipLogUrl, url)) {
                    skipLog=true;
                    break;
                }
            }
        }
        if(!skipLog) {
            String datetime = (new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date());
            String date = (new java.text.SimpleDateFormat("yyyy-MM-dd")).format(new Date());
            OperationLog operationLog = new OperationLog();
            operationLog.setOperationUser(account);
            operationLog.setOperationIp(ip);
            operationLog.setOperationContent(url);
            operationLog.setOperationParams(params);
            operationLog.setCreateTime(datetime);
            //按天记录日志
            //redisTemplate.opsForList().leftPush("logs_"+date, JSONObject.toJSONString(operationLog));
            redisConfigX.getRedisTemplateByDb(logRedisDbNumber).opsForList().leftPush("logs_"+date, JSONObject.toJSONString(operationLog));
        }

    }



    @Override
    public int getOrder() {
        return -100;
    }


}
评论