Procházet zdrojové kódy

答题核心逻辑重构

01495251 před 2 měsíci
rodič
revize
b24bae791a

+ 3 - 2
src/main/java/com/sg/answer/core/SgEntity.java

@@ -43,9 +43,9 @@ public class SgEntity {
     /**头像*/
     private  JLabel image;
     /**工号*/
-    private  JTextField userText =new JTextField("34110210",20);
+    private  JTextField userText =new JTextField("34301122",20);
     /**密码*/
-    private JPasswordField passwordText = new JPasswordField("pengyu@0215",20);
+    private JPasswordField passwordText = new JPasswordField("pengyu0215!",20);
     /**工种选择下拉框*/
     private JComboBox comboBox;
     /**难度选择下拉框*/
@@ -56,6 +56,7 @@ public class SgEntity {
     }
     public void apppendLogs(String msg){
         this.getTextArea().append(msg);
+        this.getTextArea().setCaretPosition( this.getTextArea().getText().length());
         this.getTextArea().paintImmediately( this.getTextArea().getBounds());
     }
 

+ 1 - 1
src/main/java/com/sg/answer/panel/PlaceComponents.java

@@ -307,7 +307,7 @@ public class PlaceComponents {
 
             if (!pause.get()){
                 synchronized (lock){
-                    sgEntity.apppendLogs(" 已恢复当前答题 ");
+                    sgEntity.apppendLogs(",已恢复当前答题, ");
                     log.info("以恢复当前等待线程,开始继续答题");
                     lock.notify();
                 }

+ 18 - 13
src/main/java/com/sg/answer/service/AnswerService.java

@@ -2,26 +2,17 @@ package com.sg.answer.service;
 
 import com.alibaba.fastjson.JSONException;
 import com.alibaba.fastjson.JSONObject;
-import com.sg.answer.core.HttpRequestConfig;
-import com.sg.answer.core.HttpRequestResult;
-import com.sg.answer.core.SgEntity;
 import com.sg.answer.sg.ApiEndpoints;
 import com.sg.answer.sg.ErrorCode;
 import com.sg.answer.sg.SgException;
-import com.sg.answer.utils.HttpClientUtils;
 import com.sg.answer.utils.SgUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.http.client.CookieStore;
-import org.apache.http.client.HttpClient;
-import org.apache.http.protocol.HttpContext;
 
-import java.io.IOException;
 import java.util.List;
 import java.util.Random;
 
-import static com.sg.answer.sg.Constant.answerNum;
-
 @Slf4j
 public class AnswerService {
 
@@ -31,8 +22,8 @@ public class AnswerService {
         this.cookieStore = cookieStore;
     }
 
-    private void openAnswerHtml(int num) throws Exception {
-        String openAnswerUrl = ApiEndpoints.START_LEVEL + "?id=" + num + "&matchid=0";
+    public void openAnswerHtml(int gkId) throws Exception {
+        String openAnswerUrl = ApiEndpoints.START_LEVEL + "?id=" + gkId + "&matchid=0";
         log.info("闯关页面请求地址:{}", openAnswerUrl);
         String openResult = SgUtils.executeRemotePostRequest(cookieStore, openAnswerUrl);
         if (StringUtils.isEmpty(openResult)) {
@@ -49,12 +40,12 @@ public class AnswerService {
         }
     }
 
-    public JSONObject autoAnswer(List<String> stemList, String num) throws Exception {
+    public JSONObject autoAnswer(List<String> stemList, int gkId) throws Exception {
         String answerResult;
         int index = new Random().nextInt(50);
         String stem = stemList.get(index);
         log.info("随机选题:序号={},题干={}", index, stem);
-        String dtUrl = ApiEndpoints.SUBMIT_ANSWER + "?passid=" + num + "&" + stem;
+        String dtUrl = ApiEndpoints.SUBMIT_ANSWER + "?passid=" + gkId + "&" + stem;
         try {
             answerResult = SgUtils.executeRemotePostRequest(cookieStore, dtUrl);
         } catch (Exception e) {
@@ -81,4 +72,18 @@ public class AnswerService {
         }
         return jb;
     }
+
+    public void gkSettlement(int gkId) throws Exception {
+        String settlementUrl = ApiEndpoints.LEVEL_RESULT + "&passid=" + gkId + "&matchid=0";
+//        log.info("闯关结算请求地址:{}", settlementUrl);
+        String res = SgUtils.executeRemotePostRequest(cookieStore, settlementUrl);
+        log.info("闯关结算结果:{}", res);
+        if (StringUtils.isEmpty(res)) {
+            log.error("结算异常,再次发起结算请求……");
+            res = SgUtils.executeRemotePostRequest(cookieStore, settlementUrl);
+        }
+        if (res.contains("只差一点点")) {
+            log.error("错误题目过多,闯关失败……");
+        }
+    }
 }

+ 1 - 1
src/main/java/com/sg/answer/service/UserInfoService.java

@@ -26,7 +26,7 @@ import static com.sg.answer.sg.Constant.*;
 public class UserInfoService {
     private static final Logger log = LoggerFactory.getLogger(UserInfoService.class);
 
-    public static void getPersonalInfo(CookieStore cookie, SgEntity sgEntity,
+    public static void refreshUserInfo(CookieStore cookie, SgEntity sgEntity,
                                        UserInfoEntity userInfo) throws Exception {
         try {
             String htmlContent = SgUtils.executeRemotePostRequest(cookie, ApiEndpoints.USER_DATA);

+ 1 - 1
src/main/java/com/sg/answer/sg/Constant.java

@@ -15,7 +15,7 @@ public class Constant {
 //    public final static String MOBILE_API_URL = "http://117.39.28.234:8023/mobile/";
     public final static String SERVER_IP = "http://117.39.28.234:8023/";
     /**所有关数*/
-    public static Map<Integer,Object> gkNum = new HashMap<>(20);
+    public static Map<Integer,String> gkNum = new HashMap<>(20);
     /**1-10关对应的题干数量*/
     public static Map<Integer,Integer> answerNum = new HashMap<>(20);
     /**难度*/

+ 91 - 155
src/main/java/com/sg/answer/sg/FrameManager.java

@@ -1,29 +1,21 @@
 package com.sg.answer.sg;
 
-import com.alibaba.fastjson.JSONException;
 import com.alibaba.fastjson.JSONObject;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import com.sg.answer.core.HttpRequestConfig;
-import com.sg.answer.core.HttpRequestResult;
 import com.sg.answer.core.SgEntity;
 import com.sg.answer.core.UserInfoEntity;
 import com.sg.answer.entity.JobTypeEntity;
 import com.sg.answer.panel.PlaceComponents;
+import com.sg.answer.service.AnswerService;
 import com.sg.answer.service.UserInfoService;
-import com.sg.answer.utils.HttpClientUtils;
 import com.sg.answer.utils.ObjectUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.http.client.CookieStore;
-import org.apache.http.client.protocol.HttpClientContext;
-import org.apache.http.protocol.HttpContext;
 
 import javax.swing.*;
-import java.io.IOException;
 import java.text.DecimalFormat;
-import java.util.HashSet;
 import java.util.Optional;
-import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.*;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -43,7 +35,9 @@ import static com.sg.answer.sg.Constant.answerNum;
 @Slf4j
 public class FrameManager {
 
-    // 线程池配置
+    private static final int MAX_LEVEL = 10;
+    private static final DecimalFormat SCORE_FORMAT = new DecimalFormat("######0.00");
+    private static final Set<String> processedJobs = ConcurrentHashMap.newKeySet();
     private static final ThreadPoolExecutor WORKER_POOL = new ThreadPoolExecutor(
             10, 20, 30L, TimeUnit.SECONDS,
             new LinkedBlockingQueue<>(100),
@@ -52,11 +46,10 @@ public class FrameManager {
 
     public JPanel panel = new JPanel();
     private CookieStore cookie;
-    static Set<String> sets = new HashSet<>();
 
     public void init() {
         // 创建 JFrame 实例
-        JFrame frame = new JFrame("全自动答题系统6.0.2 By 彭宇");
+        JFrame frame = new JFrame("全自动答题系统6.0.3 By 彭宇");
         frame.setBounds(500, 250, 770, 550);
         frame.setSize(770, 550);
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
@@ -81,11 +74,11 @@ public class FrameManager {
      * @date 2019/7/5 15:30
      */
     public void start(JButton loginButton, SgEntity sgEntity, UserInfoEntity userInfoEntity, JLabel statrScore, AtomicBoolean status, AtomicBoolean pause, Object lock) throws Exception {
-        if (!validateCredentials(sgEntity)){
+        if (!validateCredentials(sgEntity)) {
             return;
         }
         initializeSession(sgEntity);
-        updateUIComponents(loginButton, true, "努力答题中……");
+        updateUIComponents(loginButton, false, "努力答题中……");
 
         log.info("当前活动线程数量:{}", Thread.activeCount());
 
@@ -93,9 +86,8 @@ public class FrameManager {
             try {
                 if (status.get()) {
                     cookie = login(sgEntity.getUserText().getText(), String.valueOf(sgEntity.getPasswordText().getPassword()));
-                    UserInfoService.getPersonalInfo(cookie, sgEntity, userInfoEntity);
-                    final String startScore = userInfoEntity.getIntegralDate().getText();
-                    statrScore.setText(startScore);
+                    UserInfoService.refreshUserInfo(cookie, sgEntity, userInfoEntity);
+                    statrScore.setText(userInfoEntity.getIntegralDate().getText());
                     anwser(cookie, sgEntity, userInfoEntity, statrScore, status, pause, lock);
                 } else {
                     log.info("答题已结束");
@@ -105,7 +97,7 @@ public class FrameManager {
                 JOptionPane.showMessageDialog(panel, sg.getMessage(), " stop", JOptionPane.ERROR_MESSAGE);
                 reset(loginButton, sgEntity, sg.getMessage());
             } catch (Exception e) {
-                log.info("未知异常:", e);
+                log.error("未知异常:", e);
             }
         });
     }
@@ -116,172 +108,96 @@ public class FrameManager {
         if (!status.get()) {
             return;
         }
-        HttpClientContext httpContext = new HttpClientContext();
-        httpContext.setCookieStore(cookie);
-        //获取当前答题进度关卡
+        //获取当前用户答题进度关卡
         int gs = UserInfoService.getGKInfo(cookie, sgEntity);
+        AnswerService service = new AnswerService(cookie);
         //外层循环控制1到10关,内存循环控制对应关数多少题数
-        for (int i = 1; i <= 10; i++) {
+        while (status.get()) {
             if (!status.get()) {
                 log.info("结束本次刷题");
                 break;
             }
-            sgEntity.getGkText().setText("第" + gs + "关" + "(" + sgEntity.getDifficulty() + ")");
-            sgEntity.getTextArea().setText("开始第" + gs + "关答题:");
-
-            /**获取用户历史答题关卡id*/
-            int num;
-            if (gs == 11) {
-                num = 8 + sgEntity.getGz();
-            } else if (gs == 12) {
-                num = 9 + sgEntity.getGz();
-            } else if (gs == 13) {
-                num = 10 + sgEntity.getGz();
-            } else {
-                num = gs + sgEntity.getGz();
-            }
-            log.info("当前工种:{},开始第{}关答题,答题页面id:{}", currentJobType.getJobTypeNname(), gs, num);
-            sets.add(currentJobType.getJobTypeNname().trim());
+            updateUIComponents(sgEntity.getGkText(), false, String.format("第%d关(%s)", gs, sgEntity.getDifficulty()));
+            updateUIComponents(sgEntity.getTextArea(), false, "开始第" + gs + "关答题:");
+
+            //获取用户历史答题关卡id
+            int levelId = calculateLevelId(gs, sgEntity.getGz());
+
+            log.info("当前工种:{},开始第{}关答题,答题页面id:{}", currentJobType.getJobTypeNname(), gs, levelId);
+            processedJobs.add(currentJobType.getJobTypeNname().trim());
+
+            //打开当前闯关页面(开始答题计时)*/
+            service.openAnswerHtml(levelId);
 
-            /**打开当前闯关页面(开始答题计时)*/
-            openAnswerHtml(httpContext, num);
             //开始进行本官答题
-            for (int j = 1; j <= answerNum.get(gs) + 10; j++) {
-                if (!status.get()) {
-                    log.info("已结束本次刷题");
-                    break;
-                }
-                while (pause.get()) {
-                    sgEntity.apppendLogs(" 已暂停当前答题 ");
-                    onPause(lock, pause);
-                }
-                sgEntity.getTextArea().append(currentJobType.getJobTypeNname() + ":第" + j + "题,");
-                sgEntity.getTextArea().setCaretPosition(sgEntity.getTextArea().getText().length());
-                sgEntity.getTextArea().paintImmediately(sgEntity.getTextArea().getBounds());
-                log.info("{}====================>第{}题", currentJobType.getJobTypeNname(), j);
-
-                HttpRequestResult answeresult1;
-                int ram = new Random().nextInt(50);
-                String stem = stemList.get(ram);
-                log.info("当前随机选择数字为:{},题干为:【{}】", ram, stem);
-                /**循环答题(每2秒一次 )*/
-                HttpRequestConfig answerConfig = HttpRequestConfig.create().url(API + "cglb/ajaxdt?passid=" + num + "&" + stem).context(httpContext);
-                try {
-                    answeresult1 = HttpClientUtils.post(answerConfig);
-                } catch (IOException e) {
-                    log.error("答题超时{},重新发起请求", e);
-                    Thread.sleep(10000);
-                    answeresult1 = HttpClientUtils.post(answerConfig);
-                    log.info("重新连接成功:{}", cookie);
-                }
-                JSONObject jb;
-                try {
-                    jb = JSONObject.parseObject(answeresult1.getResponseText());
-//                    log.info("当前答题数量:{}",jb.get("isright"));
-                } catch (JSONException exception) {
-                    log.error("json解析异常{}", exception.getMessage());
-                    if (exception.getMessage().contains("重新登录")) {
-                        throw new SgException(ErrorCode.LOGOUT.getCode(), ErrorCode.LOGOUT.getName());
-                    }
-                    Thread.sleep(10000);
-                    answeresult1 = HttpClientUtils.post(answerConfig);
-                    jb = JSONObject.parseObject(answeresult1.getResponseText());
-                }
+            processLevels(sgEntity, status, pause, lock, gs, currentJobType, service, levelId);
 
-                if (Integer.valueOf(jb.get("isright").toString()) == -1) {
-                    sgEntity.getTextArea().append("答题速度过快,直接进行下一题答题");
-                    continue;
-                }
-                if (Integer.valueOf(jb.get("right_num").toString()) >= answerNum.get(gs)) {
-                    log.info("当前关已答题{}道", Integer.valueOf(jb.get("right_num").toString()));
-                    break;
-                }
-                Thread.sleep(2000);
-            }
-            if (!sgEntity.getFlag()) {
-                break;
-            }
-            //进行本本关结算
-            sgEntity.getTextArea().append("开始第" + gkNum.get(gs) + "关结算");
-            sgEntity.getTextArea().paintImmediately(sgEntity.getTextArea().getBounds());
-            log.info("{} 开始第" + gkNum.get(gs) + "关结算," + "当前答题页面id:" + num + "闯关页面id:{}", currentJobType.getJobTypeNname(), sgEntity.getId());
-            log.info("当前答题工种数量:{},当前答题工种为:{}:", sets.size(), StringUtils.join(sets.toArray(), ","));
+            log.info(String.format("%s 开始第%s关结算,当前答题页面id:%d,闯关页面id:%d",currentJobType.getJobTypeNname(), gkNum.get(gs), levelId, sgEntity.getId()));
+            log.info("当前答题工种数量:{},当前答题工种为:{}:", processedJobs.size(), StringUtils.join(processedJobs.toArray(), ","));
             if (!status.get()) {
                 log.info("结束本次刷题,停止当前结算");
                 break;
             }
-            /**对当前关卡进行结算*/
-            HttpRequestConfig answerConfig = HttpRequestConfig.create().url(API + "/cglb/passresult?passid=" + num + "&matchid=0").context(httpContext);
-            HttpRequestResult answeresult1 = HttpClientUtils.post(answerConfig);
+            //更新UI答题进度
+            sgEntity.apppendLogs("开始第" + gkNum.get(gs) + "关结算");
+            //对当前关卡进行结算
+            service.gkSettlement(levelId);
 
-            if (StringUtils.isEmpty(answeresult1.getResponseText())) {
-                log.error("结算异常,再次发起结算请求……");
-                answeresult1 = HttpClientUtils.post(answerConfig);
-            }
-            if (answeresult1.getResponseText().contains("只差一点点")) {
-                log.error("错误题目过多,闯关失败……");
-            }
-            /**结算完成刷新个人信息答题成绩*/
-            UserInfoService.getPersonalInfo(cookie, sgEntity, userInfoEntity);
-
-            DecimalFormat df = new DecimalFormat("######0.00");
-            Double xj = Double.parseDouble(userInfoEntity.getIntegralDate().getText()) - Double.parseDouble(statrScore.getText());
-            log.info("增长分数:{}", xj);
-            sgEntity.getXjText().setText(df.format(xj));
-            sgEntity.getXjText().paintImmediately(sgEntity.getXjText().getBounds());
-//          userInfoEntity.getIntegralDate().setText(Double.parseDouble(userInfoEntity.getIntegralDate().getText())+score+"");
-            if (!ObjectUtils.isEmpty(sgEntity.getCoustomScore()) && xj >= sgEntity.getCoustomScore() && sgEntity.getCoustomScore() != 0.0) {
-                status.set(false);
-                log.info("已完成{}分刷分,如需继续请重新开始", sgEntity.getCoustomScore());
-                throw new SgException(ErrorCode.SORCE_LIMT.getCode(), ErrorCode.SORCE_LIMT.getName());
+            //结算完成刷新个人信息答题成绩
+            UserInfoService.refreshUserInfo(cookie, sgEntity, userInfoEntity);
+
+            // 检查分数限制
+            checkScoreLimit(userInfoEntity, sgEntity, statrScore, status);
+
+            // 更新关卡计数
+            if (gs >= MAX_LEVEL) {
+                gs = 0;
             }
+            gs++;
+        }
+    }
+
+    private static void processLevels(SgEntity sgEntity, AtomicBoolean status, AtomicBoolean pause, Object lock, int gs, JobTypeEntity currentJobType, AnswerService service, int levelId) throws Exception {
+        for (int j = 1; j <= answerNum.get(gs) + 10; j++) {
             if (!status.get()) {
-                log.info("结束本次刷题,停止当前结算");
+                log.info("已结束本次刷题");
                 break;
             }
-            gs++;
-            if (gs > 10) {
-                log.info("一轮答题结束");
+            while (pause.get()) {
+                sgEntity.apppendLogs(" 已暂停当前答题 ");
+                onPause(lock);
+            }
+
+            log.info("{}====================>第{}题", currentJobType.getJobTypeNname(), j);
+            sgEntity.apppendLogs(currentJobType.getJobTypeNname() + ":第" + j + "题,");
+
+            JSONObject resJson = service.autoAnswer(stemList, levelId);
+
+            if (Integer.parseInt(resJson.get("isright").toString()) == -1) {
+                sgEntity.getTextArea().append("答题速度过快,直接进行下一题答题");
+                continue;
+            }
+            if (Integer.parseInt(resJson.get("right_num").toString()) >= answerNum.get(gs)) {
+                log.info("当前关已答题{}道", Integer.valueOf(resJson.get("right_num").toString()));
                 break;
             }
-        }
-        //一轮答题10关结束后,开始从第一关开始
-        if (status.get()) {
-            anwser(cookie, sgEntity, userInfoEntity, statrScore, status, pause, lock);
+            Thread.sleep(2000);
         }
     }
 
-    private static void openAnswerHtml(HttpContext httpContext, int num) throws Exception {
-        String openAnswerUrl = ApiEndpoints.START_LEVEL + "?id=" + num + "&matchid=0";
-        log.info("闯关页面请求地址:{}", openAnswerUrl);
-        HttpRequestConfig openConfig = HttpRequestConfig.create().url(openAnswerUrl).context(httpContext);
-        HttpRequestResult openResult = HttpClientUtils.post(openConfig);
-        if (StringUtils.isEmpty(openResult.getResponseText())) {
-            log.error("请求返回结果集为空");
-            throw new SgException(ErrorCode.RESULT_EMPTY.getCode(), ErrorCode.RESULT_EMPTY.getName());
-        }
-        if (openResult.getResponseText().contains("今天的闯关时间已用尽")) {
-            log.error("今天的闯关时间已用尽");
-            throw new SgException(ErrorCode.TIME_Limit.getCode(), ErrorCode.TIME_Limit.getName());
-        }
-        if (openResult.getResponseText().contains("未解锁")) {
-            log.error("当前关卡未解锁");
-            throw new SgException(ErrorCode.LEVEL_NOT_UNLOCKED.getCode(), ErrorCode.LEVEL_NOT_UNLOCKED.getName());
-        }
-    }
 
-    private static void onPause(Object lock, AtomicBoolean pause) {
+    private static void onPause(Object lock) {
         synchronized (lock) {
             try {
                 log.info("已暂停答题,等待线程唤醒");
                 lock.wait();
             } catch (InterruptedException e) {
-                e.printStackTrace();
+               log.error("暂停答题异常", e);
             }
         }
     }
 
-    // 验证凭证方法
+    // 登录严重
     private boolean validateCredentials(SgEntity sgEntity) throws SgException {
         String uname = Optional.ofNullable(sgEntity.getUserText())
                 .map(JTextField::getText)
@@ -292,7 +208,7 @@ public class FrameManager {
         if (uname.isEmpty() || pwd.isEmpty()) {
             SwingUtilities.invokeLater(() ->
                     JOptionPane.showMessageDialog(panel, "账号密码不能为空", "错误", JOptionPane.ERROR_MESSAGE));
-           return false;
+            return false;
         }
         return true;
     }
@@ -301,6 +217,7 @@ public class FrameManager {
     // 初始化管卡数据
     private void initializeSession(SgEntity sgEntity) {
         sgEntity.setFlag(true);
+        sgEntity.getTextArea().setText("");
         //当前工种选项
         JobTypeEntity currentJobType = (JobTypeEntity) sgEntity.getComboBox().getSelectedItem();
         //获取当前当前选择工种第一关关卡id
@@ -330,7 +247,7 @@ public class FrameManager {
     }
 
     // UI组件更新方法
-    private void updateUIComponents(JComponent component, boolean enabled, String text) {
+    private static void updateUIComponents(JComponent component, boolean enabled, String text) {
         SwingUtilities.invokeLater(() -> {
             if (component instanceof AbstractButton) {
                 component.setEnabled(enabled);
@@ -341,6 +258,25 @@ public class FrameManager {
                 ((JButton) component).setText(text);
             }
         });
-      }
+    }
+
+    private static int calculateLevelId(int baseLevel, int difficulty) {
+        return (baseLevel > 10) ?
+                baseLevel + difficulty - 2 :
+                baseLevel + difficulty;
+    }
+
+
+    // 检查分数限制
+    private static void checkScoreLimit(UserInfoEntity userInfoEntity, SgEntity sgEntity, JLabel statrScore, AtomicBoolean status) throws SgException {
+        Double xj = Double.parseDouble(userInfoEntity.getIntegralDate().getText()) - Double.parseDouble(statrScore.getText());
+        log.info("增长分数:{}", xj);
+        updateUIComponents(sgEntity.getXjText(), true, SCORE_FORMAT.format(xj));
 
-    }
+        if (!ObjectUtils.isEmpty(sgEntity.getCoustomScore()) && xj >= sgEntity.getCoustomScore() && sgEntity.getCoustomScore() != 0.0) {
+            status.set(false);
+            log.info("已完成{}分刷分,如需继续请重新开始", sgEntity.getCoustomScore());
+            throw new SgException(ErrorCode.SORCE_LIMT.getCode(), ErrorCode.SORCE_LIMT.getName());
+        }
+    }
+}

+ 1 - 1
src/main/resource/logback.xml

@@ -13,7 +13,7 @@
     <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
         <encoder>
             <!-- 设置日志输出格式 -->
-            <pattern>[%d{yyyy/MM/dd HH:mm:ss.SSS}][%thread][%p][%logger{0}:%L] %m%n</pattern>
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) %magenta([%thread]) %cyan(%logger{0}.%M):%yellow(%L) %magenta(%X{taskID})- %highlight(%msg) %n</pattern>
         </encoder>
         <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
             <level>INFO</level>