Przeglądaj źródła

添加日志模块

hushuyu 4 miesięcy temu
rodzic
commit
bd8586e149
22 zmienionych plików z 291 dodań i 68 usunięć
  1. 1 5
      api/pom.xml
  2. 6 5
      api/src/main/java/cn/seecoder/api/docker/impl/DockerApiImpl.java
  3. 2 1
      api/src/main/java/cn/seecoder/api/k8s/impl/JobApiImpl.java
  4. 7 3
      api/src/main/java/cn/seecoder/api/k8s/impl/WatchApiImpl.java
  5. 3 8
      common/pom.xml
  6. 66 0
      common/src/main/java/cn/seecoder/common/util/LogContext.java
  7. 3 2
      common/src/main/java/cn/seecoder/common/util/LogTrackingUtil.java
  8. 21 4
      common/src/main/java/cn/seecoder/common/util/LoggerUtil.java
  9. 3 3
      common/src/main/java/cn/seecoder/common/util/SpringUtil.java
  10. 24 0
      pom.xml
  11. 1 1
      web/pom.xml
  12. 21 8
      web/src/main/java/cn/seecoder/web/infrastructure/GlobalExceptionHandler.java
  13. 83 0
      web/src/main/java/cn/seecoder/web/infrastructure/RequestLoggingFilter.java
  14. 1 2
      web/src/main/java/cn/seecoder/web/infrastructure/config/AuthTools.java
  15. 5 1
      web/src/main/java/cn/seecoder/web/infrastructure/config/WebSecurityConfig.java
  16. 6 1
      web/src/main/java/cn/seecoder/web/infrastructure/security/JwtAuthenticationTokenFilter.java
  17. 2 4
      web/src/main/java/cn/seecoder/web/service/fork/impl/ForkServiceImpl.java
  18. 14 11
      web/src/main/java/cn/seecoder/web/service/impl/APITest/APITestServiceImpl.java
  19. 5 1
      web/src/main/java/cn/seecoder/web/service/impl/branch/BranchServiceImpl.java
  20. 8 6
      web/src/main/java/cn/seecoder/web/service/impl/commit/CommitServiceImpl.java
  21. 1 2
      web/src/main/java/cn/seecoder/web/service/impl/sql/SqlServiceImpl.java
  22. 8 0
      web/src/main/resources/application.yml

+ 1 - 5
api/pom.xml

@@ -37,7 +37,7 @@
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
-            <version>1.18.4</version>
+            <version>${lombok.version}</version>
         </dependency>
         <dependency>
             <groupId>com.nju.edu</groupId>
@@ -81,10 +81,6 @@
             <artifactId>seecoder-devcloud-common</artifactId>
             <version>0.1.0</version>
         </dependency>
-        <dependency>
-            <groupId>org.projectlombok</groupId>
-            <artifactId>lombok</artifactId>
-        </dependency>
         <!-- https://mvnrepository.com/artifact/io.kubernetes/client-java -->
         <dependency>
             <groupId>io.kubernetes</groupId>

+ 6 - 5
api/src/main/java/cn/seecoder/api/docker/impl/DockerApiImpl.java

@@ -12,9 +12,9 @@ import com.spotify.docker.client.messages.Image;
 import com.spotify.docker.client.messages.ProgressMessage;
 import com.spotify.docker.client.messages.RegistryAuth;
 import com.spotify.docker.client.messages.RegistryConfigs;
-import lombok.extern.apachecommons.CommonsLog;
-import lombok.extern.slf4j.Slf4j;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.system.ApplicationHome;
 import org.springframework.stereotype.Component;
@@ -29,9 +29,10 @@ import java.util.Collections;
 import java.util.List;
 
 @Component
-@Slf4j
 public class DockerApiImpl implements DockerApi {
 
+    private static final Logger log = LoggerFactory.getLogger(DockerApiImpl.class);
+
     private final DockerClient client;
     private final ProgressHandler defaultHandler;
     private final RegistryAuthSupplier registryAuthSupplier;
@@ -84,7 +85,7 @@ public class DockerApiImpl implements DockerApi {
         try {
             images = client.listImages(DockerClient.ListImagesParam.allImages());
         } catch (DockerException | InterruptedException e) {
-            e.printStackTrace();
+            log.error("Failed to list docker images", e);
         }
         return images;
     }
@@ -103,7 +104,7 @@ public class DockerApiImpl implements DockerApi {
     private static class LogActionProgressHandler implements ProgressHandler {
         @Override
         public void progress(ProgressMessage message) {
-            System.out.println(message);
+            DockerApiImpl.log.info("docker build progress: {}", message);
         }
     }
 }

+ 2 - 1
api/src/main/java/cn/seecoder/api/k8s/impl/JobApiImpl.java

@@ -67,7 +67,8 @@ public class JobApiImpl implements JobApi {
             Thread.sleep(60000);
             LoggerUtil.info(logger, "10s has gone");
         } catch (InterruptedException e) {
-            e.printStackTrace();
+            Thread.currentThread().interrupt();
+            LoggerUtil.warn(logger, e, "Job update wait interrupted, namespace={}, name={}", job.getNamespace(), job.getName());
         }
         return create(job);
     }

+ 7 - 3
api/src/main/java/cn/seecoder/api/k8s/impl/WatchApiImpl.java

@@ -6,6 +6,8 @@ import io.kubernetes.client.openapi.ApiException;
 import io.kubernetes.client.openapi.apis.AppsV1Api;
 import io.kubernetes.client.openapi.models.V1Deployment;
 import io.kubernetes.client.util.Watch;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import cn.seecoder.api.k8s.WatchApi;
@@ -22,6 +24,8 @@ import static cn.seecoder.api.k8s.K8sConstants.PRETTY_FORMAT;
 @Service
 public class WatchApiImpl implements WatchApi {
 
+    private static final Logger log = LoggerFactory.getLogger(WatchApiImpl.class);
+
     private ApiClient watchApiClient;
 
     private AppsV1Api watchAppsV1Api;
@@ -53,15 +57,15 @@ public class WatchApiImpl implements WatchApi {
 
             );
             watch.forEach(response -> {
-                System.out.printf("%s pod : %s %s%n", response.type, response.object.getMetadata().getName(), response.object.getStatus());
+                log.info("{} deployment: {} {}", response.type, response.object.getMetadata().getName(), response.object.getStatus());
                 try {
                     watch.close();
                 } catch (IOException e) {
-                    e.printStackTrace();
+                    log.error("Failed to close kubernetes watch", e);
                 }
             });
         } catch (ApiException e) {
-            e.printStackTrace();
+            log.error("Failed to watch deployment", e);
         }
     }
 

+ 3 - 8
common/pom.xml

@@ -10,8 +10,8 @@
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
                 <configuration>
-                    <source>6</source>
-                    <target>6</target>
+                    <source>8</source>
+                    <target>8</target>
                 </configuration>
             </plugin>
         </plugins>
@@ -37,7 +37,7 @@
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
-            <version>1.18.22</version>
+            <version>${lombok.version}</version>
         </dependency>
         <dependency>
             <groupId>io.jsonwebtoken</groupId>
@@ -73,11 +73,6 @@
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
 
-        <dependency>
-            <groupId>org.projectlombok</groupId>
-            <artifactId>lombok</artifactId>
-            <optional>true</optional>
-        </dependency>
         <dependency>
             <groupId>io.jsonwebtoken</groupId>
             <artifactId>jjwt</artifactId>

+ 66 - 0
common/src/main/java/cn/seecoder/common/util/LogContext.java

@@ -0,0 +1,66 @@
+package cn.seecoder.common.util;
+
+import org.slf4j.MDC;
+
+import java.util.UUID;
+
+/**
+ * 统一维护日志上下文,便于将请求链路中的关键信息打进 MDC。
+ */
+public final class LogContext {
+
+    public static final String TRACE_ID = "traceId";
+    public static final String USER_ID = "userId";
+    public static final String REQUEST_METHOD = "httpMethod";
+    public static final String REQUEST_URI = "requestUri";
+    public static final String CLIENT_IP = "clientIp";
+
+    private LogContext() {
+    }
+
+    public static String getTraceId() {
+        return MDC.get(TRACE_ID);
+    }
+
+    public static String getOrCreateTraceId() {
+        String traceId = MDC.get(TRACE_ID);
+        if (traceId == null || traceId.trim().length() == 0) {
+            traceId = UUID.randomUUID().toString().replace("-", "");
+            if (traceId.length() > 16) {
+                traceId = traceId.substring(0, 16);
+            }
+            MDC.put(TRACE_ID, traceId);
+        }
+        return traceId;
+    }
+
+    public static void putTraceId(String traceId) {
+        if (traceId == null || traceId.trim().length() == 0) {
+            return;
+        }
+        MDC.put(TRACE_ID, traceId.trim());
+    }
+
+    public static void putUserId(Object userId) {
+        if (userId == null) {
+            return;
+        }
+        MDC.put(USER_ID, String.valueOf(userId));
+    }
+
+    public static void putRequest(String method, String requestUri, String clientIp) {
+        putIfNotBlank(REQUEST_METHOD, method);
+        putIfNotBlank(REQUEST_URI, requestUri);
+        putIfNotBlank(CLIENT_IP, clientIp);
+    }
+
+    public static void clear() {
+        MDC.clear();
+    }
+
+    private static void putIfNotBlank(String key, String value) {
+        if (value != null && value.trim().length() > 0) {
+            MDC.put(key, value.trim());
+        }
+    }
+}

+ 3 - 2
common/src/main/java/cn/seecoder/common/util/LogTrackingUtil.java

@@ -9,7 +9,8 @@ public class LogTrackingUtil {
 
     public static void log(String data, OpType opType) {
         //TODO 旧日志client已经弃用,这里先只打印日志
-        LoggerUtil.info(logger, data, opType);
+        LoggerUtil.info(logger, "opType={} opCode={} traceId={} payload={}",
+                opType.getName(), opType.getNum(), LogContext.getOrCreateTraceId(), data);
     }
 
     public static void main(String[] args) {
@@ -18,4 +19,4 @@ public class LogTrackingUtil {
             LogTrackingUtil.log(data, OpType.CREATE_OR_MODIFY_BUGLIST);
         } catch (Exception ignore) {}
     }
-}
+}

+ 21 - 4
common/src/main/java/cn/seecoder/common/util/LoggerUtil.java

@@ -23,8 +23,7 @@ public class LoggerUtil {
     }
 
     public static void warn(Logger logger, Exception e, String info, Object... parameters) {
-        logger.warn("", e);
-        logger.warn(info, parameters);
+        logger.warn(appendThrowable(parameters, e, info), e);
     }
 
     public static void  error(Logger logger, String info, Object... parameters) {
@@ -32,11 +31,29 @@ public class LoggerUtil {
     }
 
     public static void error(Logger logger, Exception e, String info, Object... parameters) {
-        logger.error("", e);
-        logger.error(info, parameters);
+        logger.error(appendThrowable(parameters, e, info), e);
     }
 
     public static void debug(Logger logger, String info, Object... parameters) {
         logger.debug(info, parameters);
     }
+
+    private static String appendThrowable(Object[] parameters, Exception e, String info) {
+        if (parameters == null || parameters.length == 0) {
+            return info;
+        }
+        return format(info, parameters);
+    }
+
+    private static String format(String template, Object... parameters) {
+        if (template == null || parameters == null || parameters.length == 0) {
+            return template;
+        }
+        String formatted = template;
+        for (Object parameter : parameters) {
+            String replacement = String.valueOf(parameter);
+            formatted = formatted.replaceFirst("\\{}", java.util.regex.Matcher.quoteReplacement(replacement));
+        }
+        return formatted;
+    }
 }

+ 3 - 3
common/src/main/java/cn/seecoder/common/util/SpringUtil.java

@@ -1,6 +1,7 @@
 package cn.seecoder.common.util;
 
-import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeansException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
@@ -12,10 +13,9 @@ import javax.annotation.PostConstruct;
  * @date 2021/1/19
  * @description:
  */
-@Slf4j
 public class SpringUtil implements ApplicationContextAware {
 
-
+    private static final Logger log = LoggerFactory.getLogger(SpringUtil.class);
     private static ApplicationContext applicationContext;
 
     public static SpringUtil springUtil ;

+ 24 - 0
pom.xml

@@ -22,6 +22,7 @@
         <spring-boot.version>2.3.4.RELEASE</spring-boot.version>
         <maven.compiler.source>1.8</maven.compiler.source>
         <maven.compiler.target>1.8</maven.compiler.target>
+        <lombok.version>1.18.32</lombok.version>
     </properties>
 
     <dependencies>
@@ -62,4 +63,27 @@
             <url>http://nexus.seecoder.cn/repository/maven-releases</url>
         </repository>
     </distributionManagement>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>3.13.0</version>
+                    <configuration>
+                        <source>${maven.compiler.source}</source>
+                        <target>${maven.compiler.target}</target>
+                        <annotationProcessorPaths>
+                            <path>
+                                <groupId>org.projectlombok</groupId>
+                                <artifactId>lombok</artifactId>
+                                <version>${lombok.version}</version>
+                            </path>
+                        </annotationProcessorPaths>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
 </project>

+ 1 - 1
web/pom.xml

@@ -26,7 +26,7 @@
         <dependency>
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
-            <version>1.18.4</version>
+            <version>${lombok.version}</version>
         </dependency>
         <!-- Swagger -->
         <!-- https://mvnrepository.com/artifact/io.springfox/springfox-boot-starter -->

+ 21 - 8
web/src/main/java/cn/seecoder/web/infrastructure/GlobalExceptionHandler.java

@@ -1,9 +1,12 @@
 package cn.seecoder.web.infrastructure;
 
 import cn.seecoder.web.model.vo.Response;
-import lombok.extern.slf4j.Slf4j;
 import org.apache.http.HttpStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.validation.BindException;
+import org.springframework.web.context.request.ServletWebRequest;
+import org.springframework.web.context.request.WebRequest;
 import org.springframework.web.bind.annotation.ExceptionHandler;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.RestControllerAdvice;
@@ -17,20 +20,23 @@ import javax.validation.ConstraintViolationException;
  * @description: 统一异常返回处理
  */
 @RestControllerAdvice
-@Slf4j
 public class GlobalExceptionHandler {
 
+    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
+
     //***************************validation参数异常的捕获**************
 
     @ExceptionHandler(value = BindException.class)
     @ResponseBody
-    public Response handleResourceBindException(BindException e) {
+    public Response handleResourceBindException(BindException e, WebRequest request) {
+        log.warn("Validation bind failed: path={}, message={}", extractPath(request), e.getMessage());
         return Response.buildFailure(HttpStatus.SC_BAD_REQUEST, e.getMessage());
     }
 
     @ExceptionHandler(value = ConstraintViolationException.class)
     @ResponseBody
-    public Response handleResourceConstraintViolationException(ConstraintViolationException e) {
+    public Response handleResourceConstraintViolationException(ConstraintViolationException e, WebRequest request) {
+        log.warn("Constraint violation: path={}, message={}", extractPath(request), e.getMessage());
         return Response.buildFailure(HttpStatus.SC_BAD_REQUEST, e.getMessage());
     }
 
@@ -38,15 +44,22 @@ public class GlobalExceptionHandler {
 
     @ExceptionHandler(ServiceException.class)
     @ResponseBody
-    public Response serviceExceptionHandler(ServiceException e){
-        log.error("Error: ",e);
+    public Response serviceExceptionHandler(ServiceException e, WebRequest request){
+        log.error("Service exception: path={}, code={}, message={}", extractPath(request), e.getCode(), e.getMessage(), e);
         return Response.buildFailure(e.getCode(),e.getMessage());
     }
 
     @ExceptionHandler(Exception.class)
     @ResponseBody
-    public Response exceptionHandler(Exception e){
-        log.error("Error: ",e);
+    public Response exceptionHandler(Exception e, WebRequest request){
+        log.error("Unhandled exception: path={}, message={}", extractPath(request), e.getMessage(), e);
         return Response.buildFailure(503,e.getMessage());
     }
+
+    private String extractPath(WebRequest request) {
+        if (request instanceof ServletWebRequest) {
+            return ((ServletWebRequest) request).getRequest().getRequestURI();
+        }
+        return "";
+    }
 }

+ 83 - 0
web/src/main/java/cn/seecoder/web/infrastructure/RequestLoggingFilter.java

@@ -0,0 +1,83 @@
+package cn.seecoder.web.infrastructure;
+
+import cn.seecoder.common.util.LogContext;
+import cn.seecoder.web.model.po.user.UserPO;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Component;
+import org.springframework.web.filter.OncePerRequestFilter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+@Component
+public class RequestLoggingFilter extends OncePerRequestFilter {
+
+    public static final String TRACE_ID_HEADER = "X-Trace-Id";
+    private static final String TRACEPARENT_HEADER = "traceparent";
+    private static final Logger log = LoggerFactory.getLogger(RequestLoggingFilter.class);
+
+    @Override
+    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
+            throws ServletException, IOException {
+        long startTime = System.currentTimeMillis();
+        String traceId = resolveTraceId(request);
+        LogContext.putTraceId(traceId);
+        LogContext.putRequest(request.getMethod(), request.getRequestURI(), resolveClientIp(request));
+        response.setHeader(TRACE_ID_HEADER, traceId);
+        try {
+            filterChain.doFilter(request, response);
+        } finally {
+            bindUserId();
+            long duration = System.currentTimeMillis() - startTime;
+            log.info("request completed status={} durationMs={} query={}",
+                    response.getStatus(), duration, safeQueryString(request.getQueryString()));
+            LogContext.clear();
+        }
+    }
+
+    private String resolveTraceId(HttpServletRequest request) {
+        String traceId = request.getHeader(TRACE_ID_HEADER);
+        if (traceId == null || traceId.trim().isEmpty()) {
+            traceId = request.getHeader(TRACEPARENT_HEADER);
+        }
+        if (traceId != null && !traceId.trim().isEmpty()) {
+            return traceId.trim();
+        }
+        return LogContext.getOrCreateTraceId();
+    }
+
+    private String resolveClientIp(HttpServletRequest request) {
+        String forwardedFor = request.getHeader("X-Forwarded-For");
+        if (forwardedFor != null && !forwardedFor.trim().isEmpty()) {
+            return forwardedFor.split(",")[0].trim();
+        }
+        String realIp = request.getHeader("X-Real-IP");
+        if (realIp != null && !realIp.trim().isEmpty()) {
+            return realIp.trim();
+        }
+        return request.getRemoteAddr();
+    }
+
+    private void bindUserId() {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        if (authentication == null) {
+            return;
+        }
+        Object principal = authentication.getPrincipal();
+        if (principal instanceof UserPO) {
+            LogContext.putUserId(((UserPO) principal).getId());
+        } else if (principal != null && !"anonymousUser".equals(principal)) {
+            LogContext.putUserId(principal);
+        }
+    }
+
+    private String safeQueryString(String queryString) {
+        return queryString == null ? "" : queryString;
+    }
+}

+ 1 - 2
web/src/main/java/cn/seecoder/web/infrastructure/config/AuthTools.java

@@ -69,8 +69,7 @@ public class AuthTools {
                 return false;
             }
         } catch (SeecoderGitlabException e) {
-            log.error("checkProjOwnership " + e.getMessage());
-            e.printStackTrace();
+            log.error("checkProjOwnership failed, projectId={}, userId={}", projectId, userPO.getId(), e);
         }
         log.info("Verified ProjectId " + projectId);
         return true;

+ 5 - 1
web/src/main/java/cn/seecoder/web/infrastructure/config/WebSecurityConfig.java

@@ -2,6 +2,7 @@ package cn.seecoder.web.infrastructure.config;
 
 import cn.seecoder.web.infrastructure.security.JwtAuthenticationTokenFilter;
 import cn.seecoder.web.infrastructure.security.WebSecurityConstants;
+import cn.seecoder.web.infrastructure.RequestLoggingFilter;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -31,12 +32,14 @@ import static org.springframework.http.HttpMethod.*;
 public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
 
     private final JwtAuthenticationTokenFilter filter;
+    private final RequestLoggingFilter requestLoggingFilter;
     private final AuthTools authTools;
 
     @Autowired
-    public WebSecurityConfig(JwtAuthenticationTokenFilter filter, AuthTools authTools) {
+    public WebSecurityConfig(JwtAuthenticationTokenFilter filter, RequestLoggingFilter requestLoggingFilter, AuthTools authTools) {
         super();
         this.filter = filter;
+        this.requestLoggingFilter = requestLoggingFilter;
         this.authTools = authTools;
     }
 
@@ -52,6 +55,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
                 .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
 
                 .and()
+                .addFilterBefore(requestLoggingFilter, JwtAuthenticationTokenFilter.class)
                 .addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class)
 
                 .authorizeRequests()

+ 6 - 1
web/src/main/java/cn/seecoder/web/infrastructure/security/JwtAuthenticationTokenFilter.java

@@ -15,6 +15,8 @@ import org.springframework.web.filter.OncePerRequestFilter;
 import cn.seecoder.common.util.JwtTokenUtil;
 import cn.seecoder.web.model.enums.UserIdentity;
 import cn.seecoder.web.model.vo.Response;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
@@ -34,6 +36,8 @@ import java.util.LinkedHashMap;
 @Component
 public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
 
+    private static final Logger log = LoggerFactory.getLogger(JwtAuthenticationTokenFilter.class);
+
     private final UserDetailsService userDetailsService;
 
     private final JwtTokenUtil jwtTokenUtil;
@@ -71,6 +75,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
                 } else {
                     PrintWriter out = null ;
                     try{
+                        log.warn("Jwt token expired, uri={}", httpServletRequest.getRequestURI());
                         httpServletResponse.setCharacterEncoding("UTF-8");
                         httpServletResponse.setStatus(10010);
                         httpServletResponse.setContentType("application/json; charset=utf-8");
@@ -78,7 +83,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
                         out.append(Response.buildFailure(10110,"Jwt token 过期").toString());
                     }
                     catch (Exception e){
-                        e.printStackTrace();
+                        log.error("Failed to write expired token response, uri={}", httpServletRequest.getRequestURI(), e);
                         httpServletResponse.sendError(500);
                     }
                     return;

+ 2 - 4
web/src/main/java/cn/seecoder/web/service/fork/impl/ForkServiceImpl.java

@@ -78,10 +78,8 @@ public class ForkServiceImpl implements ForkService {
                     false);
             return new ForkVO(newProjectId, newName);
         } catch (Exception e) {
-            log.error("Fork API 异常:" + e.getMessage());
-            log.error("Fork API 异常类型:" + e.getClass());
-            log.error("Fork API 异常调用栈:");
-            e.printStackTrace();
+            log.error("Fork API failed, projectId={}, userId={}, exceptionType={}",
+                    forkVO.getProjectId(), userId, e.getClass().getName(), e);
             return null;
         }
     }

+ 14 - 11
web/src/main/java/cn/seecoder/web/service/impl/APITest/APITestServiceImpl.java

@@ -20,6 +20,8 @@ import cn.seecoder.web.service.user.UserService;
 import com.google.gson.Gson;
 import net.sf.json.JSONArray;
 import net.sf.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -40,7 +42,7 @@ import java.util.stream.Collectors;
 @Service
 public class APITestServiceImpl implements APITestService {
 
-
+    private static final Logger log = LoggerFactory.getLogger(APITestServiceImpl.class);
     private final APITestMapper apiTestMapper;
 
     private final PipelineMapper pipelineMapper;
@@ -225,7 +227,7 @@ public class APITestServiceImpl implements APITestService {
                     try {
                         arr = doPost(url, params);
                     } catch (IOException e) {
-                        e.printStackTrace();
+                        log.error("POST api test request failed, url={}, testId={}", url, testId, e);
                     }
                 }
                 timeList.add(arr[1]);
@@ -234,7 +236,8 @@ public class APITestServiceImpl implements APITestService {
                 try{
                     Thread.sleep(100);
                 } catch (InterruptedException e) {
-                    e.printStackTrace();
+                    log.warn("API test thread interrupted, testId={}", testId, e);
+                    Thread.currentThread().interrupt();
                 }
             }
         };
@@ -352,13 +355,13 @@ public class APITestServiceImpl implements APITestService {
                 result.append(line);
             }
         } catch (Exception e) {
-            e.printStackTrace();
+            log.error("GET api test request failed, url={}, params={}", url, params, e);
         } finally {
             try {
                 if (br != null)
                     br.close();
             } catch (IOException ex) {
-                ex.printStackTrace();
+                log.warn("Failed to close GET api test reader, url={}", url, ex);
             }
         }
         long end = System.currentTimeMillis();
@@ -411,8 +414,7 @@ public class APITestServiceImpl implements APITestService {
             // 断开连接
             conn.disconnect();
         } catch (Exception e) {
-            System.out.println("发送 POST 请求出现异常!"+e);
-            e.printStackTrace();
+            log.error("POST api test request failed, url={}, params={}", url, params, e);
         } finally{
             try{
                 if(out!=null){
@@ -423,7 +425,7 @@ public class APITestServiceImpl implements APITestService {
                 }
             }
             catch(IOException ex){
-                ex.printStackTrace();
+                log.warn("Failed to close POST api test resources, url={}", url, ex);
             }
         }
         long end = System.currentTimeMillis();
@@ -446,19 +448,20 @@ public class APITestServiceImpl implements APITestService {
                         endGate.countDown();
                     }
                 } catch (InterruptedException ie) {
-                    ie.printStackTrace();
+                    log.warn("API test worker interrupted", ie);
+                    Thread.currentThread().interrupt();
                 }
             });
             t.start();
         }
         long startTime = System.nanoTime();
-        System.out.println(startTime + " [" + Thread.currentThread() + "] All thread is ready, concurrent going...");
+        log.info("{} [{}] All thread is ready, concurrent going...", startTime, Thread.currentThread());
         // 因开启门只需一个开关,所以立马就开启开始门
         startGate.countDown();
         // 等等结束门开启
         endGate.await();
         long endTime = System.nanoTime();
-        System.out.println(endTime + " [" + Thread.currentThread() + "] All thread is completed.");
+        log.info("{} [{}] All thread is completed.", endTime, Thread.currentThread());
         return endTime - startTime;
     }
 }

+ 5 - 1
web/src/main/java/cn/seecoder/web/service/impl/branch/BranchServiceImpl.java

@@ -4,6 +4,8 @@ import cn.seecoder.web.service.branch.BranchService;
 import com.nju.edu.gitlab.SeecoderGitlabApi;
 import com.nju.edu.gitlab.SeecoderGitlabException;
 import com.nju.edu.gitlab.vo.BranchVO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -12,6 +14,8 @@ import java.util.List;
 @Service
 public class BranchServiceImpl implements BranchService {
 
+    private static final Logger log = LoggerFactory.getLogger(BranchServiceImpl.class);
+
     @Autowired
     SeecoderGitlabApi seecoderGitlabApi;
 
@@ -21,7 +25,7 @@ public class BranchServiceImpl implements BranchService {
         try {
             branches = seecoderGitlabApi.getProjectBranches(projectId);
         } catch (SeecoderGitlabException e) {
-            e.printStackTrace();
+            log.error("Failed to get branches, projectId={}", projectId, e);
             return null;
         }
         return branches;

+ 8 - 6
web/src/main/java/cn/seecoder/web/service/impl/commit/CommitServiceImpl.java

@@ -21,7 +21,8 @@ import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.nju.edu.gitlab.SeecoderGitlabApi;
 import com.nju.edu.gitlab.vo.DiffVO;
-import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import cn.seecoder.web.dao.commit.CommitMapper;
@@ -40,9 +41,10 @@ import java.util.stream.Collectors;
  * @description:
  */
 @Service
-@Slf4j
 public class CommitServiceImpl implements CommitService {
 
+    private static final Logger log = LoggerFactory.getLogger(CommitServiceImpl.class);
+
     private final SeecoderGitlabApi seecoderGitlabApi;
 
     @Autowired
@@ -82,7 +84,7 @@ public class CommitServiceImpl implements CommitService {
             }
 
         } catch (Exception e){
-            e.printStackTrace();
+            log.error("Failed to query commits by branch, projectId={}, branchName={}", projectId, BranchName, e);
             return new ArrayList<>();
         }
 
@@ -96,7 +98,7 @@ public class CommitServiceImpl implements CommitService {
             CommitVO commitVO = new CommitVO(commit);
             CommitPO commitPO = commitLinkService.getLinkedCommit(hash);
             if (commitPO != null){
-                System.out.println(commitPO.getId());
+                log.debug("Commit {} linked to record {}", hash, commitPO.getId());
                 commitVO.setRelatedType(commitPO.getRelatedType());
                 commitVO.setRelatedId(commitPO.getRelatedId());
             } else {
@@ -107,7 +109,7 @@ public class CommitServiceImpl implements CommitService {
 
             return commitVO;
         } catch (Exception e){
-            e.printStackTrace();
+            log.error("Failed to query commit detail, projectId={}, hash={}", projectId, hash, e);
             return null;
         }
     }
@@ -117,7 +119,7 @@ public class CommitServiceImpl implements CommitService {
         try{
             return seecoderGitlabApi.compare(projectId, fromHash, toHash);
         }catch (Exception e){
-            e.printStackTrace();
+            log.error("Failed to compare commits, projectId={}, fromHash={}, toHash={}", projectId, fromHash, toHash, e);
         }
         return new HashSet<>();
     }

+ 1 - 2
web/src/main/java/cn/seecoder/web/service/impl/sql/SqlServiceImpl.java

@@ -83,8 +83,7 @@ public class SqlServiceImpl implements SqlService {
             }
 
         } catch (SQLException e) {
-            e.printStackTrace();
-            log.error("url: {}\nsql: {}\nsql state: {}", dbUrl,sql,e.getMessage());
+            log.error("SQL execution failed, url={}, sql={}, sqlState={}", dbUrl, sql, e.getMessage(), e);
             return "Fail\n"+e.getMessage();
         }
 

+ 8 - 0
web/src/main/resources/application.yml

@@ -0,0 +1,8 @@
+logging:
+  level:
+    root: INFO
+    cn.seecoder: INFO
+    org.springframework.web: INFO
+    org.springframework.security: WARN
+  pattern:
+    console: "%d{yyyy-MM-dd HH:mm:ss.SSS} %5p [%t] [%X{traceId:-no-trace}] [%X{userId:-anonymous}] %logger{36} - %msg%n"