1
0
Переглянути джерело

微信基础服务完善日志

lhm 4 роки тому
батько
коміт
bccdd906a4

+ 2 - 0
build.gradle

@@ -96,6 +96,7 @@ dependencies {
     implementation 'org.springframework.boot:spring-boot-starter-logging:2.4.5'
     implementation 'org.springframework.boot:spring-boot-starter-aop:2.4.5'
     implementation 'mysql:mysql-connector-java:8.0.11'
+    implementation 'org.springframework.boot:spring-boot-starter-logging:2.4.5'
     testImplementation 'org.springframework.boot:spring-boot-starter-test:2.4.5'
 }
 
@@ -114,4 +115,5 @@ publishing {
 
 tasks.withType(JavaCompile) {
     options.encoding = 'UTF-8'
+    options.compilerArgs << "-Xlint:unchecked"
 }

+ 9 - 2
src/main/java/com/ematou/wxbase/scheduler/RefreshAccessTokenScheduler.java

@@ -9,6 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
 
 import java.text.ParseException;
 import java.util.Date;
@@ -35,6 +36,7 @@ public class RefreshAccessTokenScheduler {
     @Scheduled(cron = "0 0 0/2 * * ?", zone = "Asia/Shanghai")
     public void refreshAccessToken() {
         try {
+            logger.info("定时器开始刷新Token...");
             tokenRecordService.generateToken();
         } catch (Exception e) {
             logger.error("定时刷新Token失败!errorMessage: " + e.getMessage());
@@ -46,13 +48,17 @@ public class RefreshAccessTokenScheduler {
      */
     @Scheduled(cron = "0 3 0/2 * * ?", zone = "Asia/Shanghai")
     public void scanExpiryToken() {
-
+        logger.info("开始扫描库中中失效的token记录......");
         int count = tokenRecordService.queryLatestAndValidRecordCount();
 
         if (count >= 1) {
             // 有生效的token,查询这些token,计算它们的过期时间,并修改已过期的token的状态为已失效
             List<TokenRecord> tokenRecords = tokenRecordService.queryTokenIsValid();
 
+            if (CollectionUtils.isEmpty(tokenRecords)) {
+                return;
+            }
+
             // 需要更新的记录的id数组
             List<Integer> resultList = tokenRecords.stream().filter(tokenRecord -> {
                 // 计算是否需要修改状态,这里对比一下失效时间和当前时间差多少时间即可
@@ -67,11 +73,12 @@ public class RefreshAccessTokenScheduler {
                 Date now = new Date();
                 long diff = now.getTime() - tokenExpiresTime.getTime();
                 // 失效时间后3分钟置为失效token
-                return diff > 0 && diff <= (3 * 60 * 1000);
+                return diff >= (3 * 60 * 1000);
             }).map(TokenRecord::getId).collect(Collectors.toList());
 
             // 批量更新
             tokenRecordService.updateBatchRecord(resultList);
+            logger.info("批量更新token状态成功!");
         }
     }
 

+ 54 - 17
src/main/java/com/ematou/wxbase/service/TokenRecordService.java

@@ -5,12 +5,15 @@ import com.ematou.wxbase.config.WxGeneralConfig;
 import com.ematou.wxbase.entity.OperationRecord;
 import com.ematou.wxbase.entity.TokenRecord;
 import com.ematou.wxbase.mapper.TokenRecordMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.StringUtils;
 import org.springframework.web.client.RestTemplate;
 
+import java.text.ParseException;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
@@ -23,6 +26,8 @@ import java.util.Map;
 @Service
 public class TokenRecordService {
 
+    private static final Logger logger = LoggerFactory.getLogger(TokenRecordService.class);
+
     @Autowired
     OperationRecordService operationRecordService;
 
@@ -40,7 +45,12 @@ public class TokenRecordService {
      * @return 所有未失效的Token记录
      */
     public List<TokenRecord> queryTokenIsValid() {
-        return tokenRecordMapper.queryTokenIsValid();
+        try {
+            return tokenRecordMapper.queryTokenIsValid();
+        } catch (RuntimeException e) {
+            logger.error("查询所有未失效的Token记录失败!errorMessage:" + e.getMessage());
+            return null;
+        }
     }
 
     /**
@@ -48,19 +58,28 @@ public class TokenRecordService {
      * @return token记录总数
      */
     public int queryLatestAndValidRecordCount() {
-        return tokenRecordMapper.queryLatestAndValidRecordCount();
+        try {
+            return tokenRecordMapper.queryLatestAndValidRecordCount();
+        } catch (RuntimeException e) {
+            logger.error("查询最新且有效的Token记录总数失败!errorMessage:" + e.getMessage());
+            return -1;
+        }
     }
 
     /**
      * 新增一条Token记录
      * @param tokenRecord token记录
-     * @return 是否成功
      */
     public void insertRecord(TokenRecord tokenRecord) {
         if (null == tokenRecord) {
+            logger.error("Token记录为空,插入失败!");
             return;
         }
-        tokenRecordMapper.insertRecord(tokenRecord);
+        try {
+            tokenRecordMapper.insertRecord(tokenRecord);
+        } catch (RuntimeException e) {
+            logger.error("插入Token记录失败!errorMessage:" + e.getMessage());
+        }
     }
 
     /**
@@ -68,13 +87,19 @@ public class TokenRecordService {
      *
      * @return token
      */
-    public TokenRecord getLatestToken() {
-
+    public TokenRecord getLatestToken() throws ParseException {
+        // 如果数据库中没有或者是该token已过期,则需要重新生成token
         TokenRecord tokenRecord = tokenRecordMapper.queryLatestAndValidRecord();
         if (null == tokenRecord) {
             // 需要生成Token
             return generateToken();
         }
+        String expiresTime = tokenRecord.getExpiresTime();
+        Date tokenExpiresTime = DateUtils.parseString(expiresTime);
+        Date now = new Date();
+        if (now.getTime() > tokenExpiresTime.getTime()) {
+            return generateToken();
+        }
         return tokenRecord;
     }
 
@@ -83,7 +108,7 @@ public class TokenRecordService {
      *
      * @return token记录
      */
-    public TokenRecord generateToken() {
+    public TokenRecord generateToken() throws RuntimeException {
 
         String url = String.format(wxGeneralConfig.getUrl(), wxGeneralConfig.getGrantType(), wxGeneralConfig.getAppId(), wxGeneralConfig.getAppSecret());
 
@@ -91,16 +116,22 @@ public class TokenRecordService {
         try {
             response = restTemplate.getForEntity(url, Map.class).getBody();
         } catch (Exception e) {
-            throw new RuntimeException("请求微信平台失败!errorMessage:" + e.getMessage());
+            logger.error("请求微信平台失败!errorMessage:" + e.getMessage());
+            throw new RuntimeException("请求微信平台失败!");
+        }
+        if (null == response) {
+            logger.error("请求微信平台失败!errorMessage:response is null");
+            throw new RuntimeException("请求微信平台失败!");
         }
 
         OperationRecord operationRecord = wrapOperationRecord("目前暂无");
         TokenRecord tokenRecord = wrapTokenRecord(operationRecord, response);
 
         if (null == tokenRecord) {
-            Object errcode = response.getOrDefault("errcode", 0);
-            Object errmsg = response.getOrDefault("errmsg", "");
-            throw new RuntimeException("请求微信平台生成AccessToken失败!errorCode:" + errcode + ",errorMessage:" + errmsg);
+            Object errcode = response.get("errcode");
+            Object errmsg = response.get("errmsg");
+            logger.error("请求微信平台生成AccessToken失败!errorCode:" + errcode + ",errorMessage:" + errmsg);
+            throw new RuntimeException("请求微信平台生成AccessToken失败!");
         }
 
         // 保存操作记录
@@ -118,9 +149,15 @@ public class TokenRecordService {
      */
     public void updateBatchRecord(List<Integer> resultList) {
         if (CollectionUtils.isEmpty(resultList)) {
+            logger.warn("需要批量更新的Token记录集合为空,无需更新!");
             return;
         }
-        tokenRecordMapper.updateBatchRecord(resultList);
+        try {
+            tokenRecordMapper.updateBatchRecord(resultList);
+        } catch (RuntimeException e) {
+            logger.error("批量更新Token记录状态失败!errorMessage:" + e.getMessage());
+            throw new RuntimeException("批量更新Token记录状态失败!");
+        }
     }
 
     /**
@@ -144,12 +181,12 @@ public class TokenRecordService {
      */
     private TokenRecord wrapTokenRecord(OperationRecord operationRecord, Map response) {
         TokenRecord tokenRecord = new TokenRecord();
-        String accessToken = (String) response.getOrDefault("access_token", "");
-        Integer expiresIn = (Integer) response.getOrDefault("expires_in", 0);
-        Integer errCode = (Integer) response.getOrDefault("errcode", 0); // 如果没有返回该字段,默认为0,0表示请求成功
-        String errMsg = (String) response.getOrDefault("errmsg", "");
+        String accessToken = (String) response.get("access_token");
+        Integer expiresIn = (Integer) response.get("expires_in");
+        Integer errCode = (Integer) response.get("errcode");
+        String errMsg = (String) response.get("errmsg");
 
-        if (StringUtils.hasLength(accessToken) && expiresIn != 0 && errCode == 0 && !StringUtils.hasLength(errMsg)) {
+        if (StringUtils.hasLength(accessToken) && expiresIn != null && errCode == null && !StringUtils.hasLength(errMsg)) {
             Date now = new Date();
             long expiresTime = now.getTime() + (expiresIn * 1000);
             tokenRecord.setAccessToken(accessToken);

+ 5 - 3
src/main/resources/application.yml

@@ -10,10 +10,12 @@ wx:
 spring:
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    username: root
-    password: root
-    url: jdbc:mysql://localhost:3306/wx_base?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
+    username: tuser
+    password: Qq!123
+    url: jdbc:mysql://120.76.84.45:3306/wx_base?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
 mybatis:
   mapper-locations: classpath:mybatis/*.xml
   configuration:
     map-underscore-to-camel-case: true
+logging:
+  config: classpath:logback.xml

+ 54 - 0
src/main/resources/logback.xml

@@ -0,0 +1,54 @@
+<configuration>
+    <!-- %m输出的信息, %p日志级别, %t线程名, %d日期, %c类的全名, %i索引 -->
+    <!-- appender是configuration的子节点,是负责写日志的组件 -->
+    <!-- ConsoleAppender把日志输出到控制台 -->
+    <!--    <property name="CONSOLE_LOG_PATTERN" -->
+    <!--               value="%date{yyyy-MM-dd HH:mm:ss} | %highlight(%-5level) | %boldYellow(%thread) | %boldGreen(%logger) | %msg%n"/> -->
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <!--<pattern>${CONSOLE_LOG_PATTERN}</pattern> -->
+            <pattern>%date{yyyy-MM-dd HH:mm:ss} %highlight(%-5level) (%file:%line\)- %m%n</pattern>
+            <!-- 控制台也要使用utf-8,不要使用gbk -->
+            <charset>UTF-8</charset>
+        </encoder>
+    </appender>
+
+    <!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
+    <!-- 1.先按日期存日志,日期变了,将前一天的日志文件名重命名为xxx%日期%索引,新的日志仍然是sys.log -->
+    <!-- 2.如果日期没有变化,但是当前日志文件的大小超过1kb时,对当前日志进行分割 重名名 -->
+    <appender name="syslog" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!--<File>${catalina.base}/mylog/sys.log</File>-->
+        <File>/app/project/wx_base/logs/wxbase.log</File>
+        <!-- rollingPolicy:当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名。 -->
+        <!-- TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 活动文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
+            <!--<fileNamePattern>${catalina.base}/mylog/sys.%d.%i.log</fileNamePattern>-->
+            <fileNamePattern>${catalina.base}/%d/sys.%d.%i.log</fileNamePattern>
+            <!-- 每产生一个日志文件,该日志文件的保存期限为30天 -->
+            <maxHistory>30</maxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy  class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <!-- maxFileSize:这是活动文件的大小,默认值是10MB,本篇设置为1KB,只是为了演示 -->
+                <maxFileSize>1KB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder>
+            <!-- pattern节点,用来设置日志的输入格式 -->
+            <pattern>
+                %d %p (%file:%line\)- %m%n
+            </pattern>
+            <!-- 记录日志的编码 -->
+            <charset>UTF-8</charset> <!-- 此处设置字符集 -->
+        </encoder>
+    </appender>
+    <!-- 控制台日志输出级别 -->
+    <root level="info">
+        <appender-ref ref="STDOUT" />
+    </root>
+    <!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->
+    <!-- com.appley为根包,也就是只要是发生在这个根包下面的所有日志操作行为的权限都是DEBUG -->
+    <!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE  -->
+    <logger name="com.yjlc.service.impl.seckill" level="DEBUG">
+        <appender-ref ref="syslog" />
+    </logger>
+</configuration>