ソースを参照

last refactoring before logging method

shjung 5 日 前
コミット
a29cb77a9b
19 ファイル変更149 行追加94 行削除
  1. 1 1
      tsi-comm-server/src/main/java/com/tsi/comm/server/AppNameInitializer.java
  2. 1 1
      tsi-comm-server/src/main/java/com/tsi/comm/server/ApplicationLifecycle.java
  3. 3 3
      tsi-comm-server/src/main/java/com/tsi/comm/server/config/TraceConfig.java
  4. 22 29
      tsi-comm-server/src/main/java/com/tsi/comm/server/controller/TsiCommServerRestController.java
  5. 3 3
      tsi-comm-server/src/main/java/com/tsi/comm/server/kafka/KafkaProducerService.java
  6. 1 1
      tsi-comm-server/src/main/java/com/tsi/comm/server/process/logging/TsiCvimLoggingWorker.java
  7. 8 1
      tsi-comm-server/src/main/java/com/tsi/comm/server/process/packet/TsiChannelSession.java
  8. 1 1
      tsi-comm-server/src/main/java/com/tsi/comm/server/process/packet/TsiCvimPacketProcess.java
  9. 13 10
      tsi-comm-server/src/main/java/com/tsi/comm/server/process/packet/TsiCvimPacketWorker.java
  10. 15 13
      tsi-comm-server/src/main/java/com/tsi/comm/server/protocol/TsiCpuDisconnected.java
  11. 19 17
      tsi-comm-server/src/main/java/com/tsi/comm/server/protocol/TsiCpuPacket.java
  12. 46 0
      tsi-comm-server/src/main/java/com/tsi/comm/server/repository/TsiAlarmManager.java
  13. 3 1
      tsi-comm-server/src/main/java/com/tsi/comm/server/service/TsiCommPacketInitializer.java
  14. 4 1
      tsi-comm-server/src/main/java/com/tsi/comm/server/tcp/codec/CvimServerByteBufMessageDecoder.java
  15. 3 3
      tsi-comm-server/src/main/java/com/tsi/comm/server/tcp/service/ConnectionLifecycleService.java
  16. 3 2
      tsi-comm-server/src/main/java/com/tsi/comm/server/vo/TsiNodeAddVo.java
  17. 0 4
      tsi-comm-server/src/main/java/com/tsi/comm/server/vo/TsiNodeVo.java
  18. 2 2
      tsi-common/src/main/java/com/tsi/common/aspect/LoggingAspect.java
  19. 1 1
      tsi-consumer/src/test/java/com/tsi/comm/consumer/TsiCommConsumerApplicationTests.java

+ 1 - 1
tsi-comm-server/src/main/java/com/tsi/comm/server/AppNameInitializer.java

@@ -23,7 +23,7 @@ public class AppNameInitializer implements ApplicationContextInitializer<Configu
             System.setProperty("spring.application.name", applicationName);
             System.setProperty("spring.datasource.hikari.pool-name", poolName);
         } catch (Exception e) {
-            log.error("Error during context initialization", e);
+            log.error("Error during context initialization: {}", e.getMessage());
         }
     }
 }

+ 1 - 1
tsi-comm-server/src/main/java/com/tsi/comm/server/ApplicationLifecycle.java

@@ -75,7 +75,7 @@ public class ApplicationLifecycle {
             this.tsiCommServerService.insertAlarmOccrHs(alarm);
             this.tsiCommServerService.updateProcessState(0);
         } catch(Exception e) {
-            log.error("Error during startup alarm logging", e);
+            log.error("Error during startup alarm logging: {}", e.getMessage());
         }
 
         this.applicationConfig.setStartSchedule(true);

+ 3 - 3
tsi-comm-server/src/main/java/com/tsi/comm/server/config/TraceConfig.java

@@ -59,7 +59,7 @@ public class TraceConfig {
             // no logging
         }
         catch(Exception e) {
-//            log.error("getProperties: Exception1: {}", e.toString());
+//            log.error("getProperties: Exception1: {}", e.getMessage());
         }
         return props;
     }
@@ -120,7 +120,7 @@ public class TraceConfig {
             this.nodeLogging = props.getProperty("node-logging", "false").trim().equalsIgnoreCase("true");
 
         } catch (Exception e) {
-            log.error("loadTraceInfo: Exception: {}", e.toString(), e);
+            log.error("loadTraceInfo: Exception: {}", e.getMessage());
         }
     }
 
@@ -210,7 +210,7 @@ public class TraceConfig {
             this.nodeLogging = props.getProperty("node-logging",  "false").trim().equalsIgnoreCase("true");
         }
         catch(Exception e) {
-            log.error("loadTraceInfo: Exception: {}", e.toString());
+            log.error("loadTraceInfo: Exception: {}", e.getMessage());
         }
 
     }

+ 22 - 29
tsi-comm-server/src/main/java/com/tsi/comm/server/controller/TsiCommServerRestController.java

@@ -43,7 +43,7 @@ public class TsiCommServerRestController {
     private final TsiCvimDbmsProcess dbmsProcess;
 
     private final String sep = System.lineSeparator();
-    private final String heading = "---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------";
+    private final String heading = "--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------";
 
     private StringBuilder getCommonHead() {
         StringBuilder sb = new StringBuilder();
@@ -104,7 +104,7 @@ public class TsiCommServerRestController {
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         sdf.setTimeZone(java.util.TimeZone.getTimeZone("GMT+9"));
 
-        sb.append(String.format("   SEQ[U] %10s %4s %7s %19s %19s %9s %6s %19s  IP Address          CRC/PACKET Signal AvgPrcTm(us)  Dropped/Overlapping Queue(P/L/D)",
+        sb.append(String.format("   SEQ[U] %10s %4s %7s %19s %19s %9s %6s %19s  IP Address       Signal AvgTm(us)  Dropped/Overlapping Queue(P/L/D)",
                 "Node ID", "A-INTC", "Connect", "Connect Time", "Disconnect Time", "Connected", "Closed", "Last-Recv-Time")).append(sep);
         sb.append(heading).append(sep);
 
@@ -112,8 +112,6 @@ public class TsiCommServerRestController {
 //        for (TsiNodeVo node : nodesSnapshot) {
 //        }
 
-        int crcErrorCnt = 0;
-        int packetErrorCnt = 0;
         for (TsiNodeVo node : pagedNodes) {
             String check = (node.isAddNodeEnabled() ? "Y-" : "N-");
             check = check + (node.isInstalled() ? "Y" : "N");
@@ -144,25 +142,14 @@ public class TsiCommServerRestController {
                 avgTime = 0;
             }
 
-            String crcErr = "false";
-            if (node.isCrcError()) {
-                crcErr = "true";
-                crcErrorCnt++;
-            }
-            String packetErr = "false";
-            if (node.isPacketError()) {
-                packetErr = "true";
-                packetErrorCnt++;
-            }
-
             String connectTm = sdf.format(new Date(node.getConnectTm()));
             String disconnectTm = sdf.format(new Date(node.getDisconnectTm()));
             String lastCommTm = sdf.format(new Date(node.getLastCommTm()));
 
-            sb.append(String.format(" %5d%3s %10s %4s %7s %19s %19s %9d %6d %19s  %-15.15s   %5s/%5s  %6d %12d  %-19s %d/%d/%d",
+            sb.append(String.format(" %5d%3s %10s %4s %7s %19s %19s %9d %6d %19s  %-15.15s  %6d %9d  %-19s %d/%d/%d",
                     seqStart++, unknownNode, node.getKey(), check, connect, connectTm, disconnectTm, node.getConnectCount().get(),
                     node.getDisconnectCount().get(), lastCommTm, info, //node.getIpAddr(), //info,
-                    crcErr, packetErr, node.getSigCount(), avgTime,
+                    node.getSigCount(), avgTime,
                     String.format("%d/%d", node.getDroppedPacketCount(), node.getOverlappingPacketCount()),
                     node.getPktQIdx(), node.getLogQIdx(), node.getDbmsQIdx())).append(sep);
         }
@@ -173,9 +160,8 @@ public class TsiCommServerRestController {
                 this.alarmManager.getUnknownIpAddrCount(), this.alarmManager.getDupConnectCount())).append(sep);
 //        sb.append(heading).append(sep);
         sb.append(String.format(" Channel: %d EA, Session: %d EA", this.sessionManager.getChannelCount(), this.sessionManager.getCount())).append(sep);
-        sb.append(String.format(" CRC Error: %d EA, Packet Error: %d EA", crcErrorCnt, packetErrorCnt)).append(sep);
-        sb.append(String.format(" DUMP: %s", this.traceConfig.getCurrentDumpNodeIds().toString())).append(sep);
-        sb.append(String.format(" TCP DUMP: %s", this.traceConfig.getCurrentTcpDumpIps().toString())).append(sep);
+        sb.append(String.format(" TRACE DUMP: %s", this.traceConfig.getCurrentDumpNodeIds().toString())).append(sep);
+        sb.append(String.format(" TRACE TCP DUMP: %s", this.traceConfig.getCurrentTcpDumpIps().toString())).append(sep);
         sb.append(heading).append(sep);
 
         return sb.toString();
@@ -368,17 +354,24 @@ public class TsiCommServerRestController {
         sb.append(heading).append(sep).append(sep);
 
         ii = 1;
-        sb.append("*CRC or Packet Error Node Information.").append(sep);
+        sb.append("*CRC Error Node Information.").append(sep);
         sb.append(heading).append(sep);
-        sb.append("   SEQ Information(CRC/Packet)").append(sep);
+        sb.append("   SEQ Information").append(sep);
         sb.append(heading).append(sep);
-        for (Map.Entry<Long, TsiNodeVo> obj : this.nodeManager.getTsiNodeVoMap().entrySet()) {
-            final TsiNodeVo node = obj.getValue();
-            if (node.isCrcError() || node.isPacketError()) {
-                String crcError = node.isCrcError() ? "true" : "false";
-                String packetError = node.isPacketError() ? "true" : "false";
-                sb.append(String.format(" %5d %d %s/%s", ii++, node.getNodeId(), crcError, packetError)).append(sep);
-            }
+        Set<String> CRC_ERROR_INFO_SET = this.alarmManager.getCRC_ERROR_INFO_SET();
+        for (String info : CRC_ERROR_INFO_SET) {
+            sb.append(String.format(" %5d %s", ii++, info)).append(sep);
+        }
+        sb.append(heading).append(sep).append(sep);
+
+        ii = 1;
+        sb.append("*PACKET Error Node Information.").append(sep);
+        sb.append(heading).append(sep);
+        sb.append("   SEQ Information").append(sep);
+        sb.append(heading).append(sep);
+        Set<String> PACKET_ERROR_INFO_SET = this.alarmManager.getPACKET_ERROR_INFO_SET();
+        for (String info : PACKET_ERROR_INFO_SET) {
+            sb.append(String.format(" %5d %s", ii++, info)).append(sep);
         }
 
         sb.append(heading).append(sep);

+ 3 - 3
tsi-comm-server/src/main/java/com/tsi/comm/server/kafka/KafkaProducerService.java

@@ -190,7 +190,7 @@ public class KafkaProducerService {
                 }
             }
             catch (Exception e) {
-                log.error("sendCvim: {}, {}: {}", TsiKafkaProducerConfig.CVIM_RAW_TOPIC, key, e.toString());
+                log.error("sendCvim: {}, {}: {}", TsiKafkaProducerConfig.CVIM_RAW_TOPIC, key, e.getMessage());
             }
         }
     }
@@ -201,7 +201,7 @@ public class KafkaProducerService {
                 this.nodeProducer.send(key, key, data);
             }
             catch (Exception e) {
-                log.error("sendNode: {}, {}: {}", key, key, e.toString());
+                log.error("sendNode: {}, {}: {}", key, key, e.getMessage());
             }
         }
     }
@@ -213,7 +213,7 @@ public class KafkaProducerService {
                 this.testProducer.sendDefault(Long.toString(key), data);
             }
             catch (Exception e) {
-                log.error("sendTest: {}, {}: {}", TsiKafkaProducerConfig.TEST_TOPIC, key, e.toString());
+                log.error("sendTest: {}, {}: {}", TsiKafkaProducerConfig.TEST_TOPIC, key, e.getMessage());
             }
         }
     }

+ 1 - 1
tsi-comm-server/src/main/java/com/tsi/comm/server/process/logging/TsiCvimLoggingWorker.java

@@ -16,7 +16,7 @@ import java.util.concurrent.LinkedBlockingQueue;
 @Getter
 public class TsiCvimLoggingWorker extends AbstractTsiCvimWorker implements Runnable {
 
-    public static final AbstractTsiPacket SHUTDOWN_PACKET = new TsiCpuPacket(-1L, 0, 0, null);
+    public static final AbstractTsiPacket SHUTDOWN_PACKET = new TsiCpuPacket(-1L, 0, 0, 0, 0);
 
     private final LinkedBlockingQueue<AbstractTsiPacket> DATA_QUEUE;
     private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

+ 8 - 1
tsi-comm-server/src/main/java/com/tsi/comm/server/process/packet/TsiChannelSession.java

@@ -8,6 +8,9 @@ import io.netty.buffer.ByteBufUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
 
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
 @Slf4j
 public class TsiChannelSession {
 
@@ -74,8 +77,12 @@ public class TsiChannelSession {
         try {
             if (nodeVo != null) {
                 final String logKey = nodeVo.getKey();
+                final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                sdf.setTimeZone(java.util.TimeZone.getTimeZone("GMT+9"));
+                final String lastCommTm = sdf.format(new Date(nodeVo.getLastCommTm()));
                 MDC.put("id", logKey);
-                log.info("Node: {},  sessionTimeout, Connects: {}, {}", nodeVo.getNodeId(), nodeVo.getConnectCount().get(), remoteIpAddress);
+                log.info("Node: {},  sessionTimeout, Connects: {}, {}, {}",
+                        nodeVo.getNodeId(), nodeVo.getConnectCount().get(), remoteIpAddress, lastCommTm);
                 MDC.clear();
             }
         }

+ 1 - 1
tsi-comm-server/src/main/java/com/tsi/comm/server/process/packet/TsiCvimPacketProcess.java

@@ -118,7 +118,7 @@ public class TsiCvimPacketProcess extends AbstractTsiCvimProcess {
 //            throw e;
 //        }
 
-        TsiCpuPacket packet = new TsiCpuPacket(nodeId, msec, nsec, null); // channel은 null
+        TsiCpuPacket packet = new TsiCpuPacket(nodeId, msec, nsec, 0, 0); // channel은 null
         packet.setBuf(dummyBytes);
         packet.setObj(dummyNodeVo);
 

+ 13 - 10
tsi-comm-server/src/main/java/com/tsi/comm/server/process/packet/TsiCvimPacketWorker.java

@@ -22,7 +22,7 @@ import java.util.concurrent.TimeUnit;
 @Getter
 public class TsiCvimPacketWorker extends AbstractTsiCvimWorker implements Runnable {
 
-    public static final AbstractTsiPacket SHUTDOWN_PACKET = new TsiCpuPacket(-1L, 0, 0, null);
+    public static final AbstractTsiPacket SHUTDOWN_PACKET = new TsiCpuPacket(-1L, 0, 0, 0, 0);
 
     private final LinkedBlockingQueue<AbstractTsiPacket> DATA_QUEUE;
 
@@ -157,7 +157,6 @@ public class TsiCvimPacketWorker extends AbstractTsiCvimWorker implements Runnab
         if (!parseAndValidate(cpuPacket, nodeVo)) {
             return; // 파싱 실패 시 처리 중단
         }
-        nodeVo.setPacketError(false);
         cpuPacket.setPar(System.nanoTime());
 
         // 2. Kafka로 데이터 전송
@@ -196,9 +195,6 @@ public class TsiCvimPacketWorker extends AbstractTsiCvimWorker implements Runnab
 
     private boolean parseAndValidate(TsiCpuPacket cpuPacket, TsiNodeVo nodeVo) {
         try {
-            nodeVo.setCrcError(false);
-            nodeVo.setPacketError(false);
-
             int result = cpuPacket.parsing(nodeVo, this.serverConfig.isCheckPacket());
             if (result == 0) {
                 return true; // 파싱 성공
@@ -209,8 +205,6 @@ public class TsiCvimPacketWorker extends AbstractTsiCvimWorker implements Runnab
                 return false;   // 네트워크 연결이 끊어진 경우
             }
 
-            nodeVo.setPacketError(true);
-
             if (-4 == result) {
                 return false; // 패킷 버퍼가 null 이거나 너무 짧은 경우
             }
@@ -227,7 +221,7 @@ public class TsiCvimPacketWorker extends AbstractTsiCvimWorker implements Runnab
             return false;
         }
         catch (Exception e) {
-            log.warn("Node: {}, CPU Packet parsing error: {}, connect: {}", nodeVo.getNodeId(), Thread.currentThread().getName(), nodeVo.isConnect(), e);
+            log.warn("Node: {}, CPU Packet parsing error: {}, connect: {}, {}", nodeVo.getNodeId(), Thread.currentThread().getName(), nodeVo.isConnect(), e.getMessage());
             return false;
         }
     }
@@ -238,7 +232,11 @@ public class TsiCvimPacketWorker extends AbstractTsiCvimWorker implements Runnab
     private void handleDisconnectedPacket(TsiCpuPacket packet, TsiNodeVo nodeVo) {
         TsiCpuDisconnected disconnected = (TsiCpuDisconnected) packet;
         try {
-            disconnected.parsing(nodeVo);
+            if (!disconnected.parsing(nodeVo)) {
+                // nodeVo == null
+                return;
+            }
+            packet.setPar(System.nanoTime());
 
             if (nodeVo.isSendCvim() && disconnected.getCvimData() != null) {
                 this.kafkaProducer.sendCvim(disconnected.getNodeId(), disconnected.getCvimData());
@@ -250,11 +248,16 @@ public class TsiCvimPacketWorker extends AbstractTsiCvimWorker implements Runnab
                     this.kafkaProducer.sendCvim(addNodePacket.getNodeId(), addNodePacket.getCvimData());
                 }
             }
+            // 2. Kafka로 데이터 전송
+            packet.setEnd(System.nanoTime());
+
+            // 3. 통계 및 로깅
+            packet.setAvg(calcProcessTime(packet.getRcv()));
 
             logPacketIfNeeded(packet, nodeVo);
         } catch (Exception e) {
             if (nodeVo.isConnect()) {
-                log.warn("Node: {}, Disconnect parsing error: {}, connect: {}", nodeVo.getNodeId(), Thread.currentThread().getName(), nodeVo.isConnect(), e);
+                log.warn("Node: {}, Disconnect parsing error: {}, connect: {}, {}", nodeVo.getNodeId(), Thread.currentThread().getName(), nodeVo.isConnect(), e.getMessage());
             }
         }
     }

+ 15 - 13
tsi-comm-server/src/main/java/com/tsi/comm/server/protocol/TsiCpuDisconnected.java

@@ -4,25 +4,21 @@ import com.tsi.comm.server.protocol.enums.eOpCode;
 import com.tsi.comm.server.vo.TsiNodeAddDetailVo;
 import com.tsi.comm.server.vo.TsiNodeAddVo;
 import com.tsi.comm.server.vo.TsiNodeVo;
-import com.tsi.comm.server.xnet.NettyUtils;
 import com.tsi.common.utils.ByteUtils;
 import com.tsi.common.utils.TimeUtils;
-import io.netty.channel.Channel;
 import lombok.Getter;
 import lombok.Setter;
 
+import java.util.ArrayList;
+
 import static com.tsi.comm.server.protocol.TsiCvibProtocolSpec.*;
 
 @Getter
 @Setter
 public class TsiCpuDisconnected extends TsiCpuPacket {
 
-    public TsiCpuDisconnected(long nodeId, Channel channel) {
-        this(nodeId, TimeUtils.currentTimeSeconds(), System.nanoTime(), channel);
-    }
-
-    public TsiCpuDisconnected(long nodeId, long msec, long nsec, Channel channel) {
-        super(nodeId, msec, nsec, NettyUtils.getRemoteIpAddressToLong(channel), NettyUtils.getRemotePort(channel));
+    public TsiCpuDisconnected(long nodeId, long remoteIpAddress, int remotePort) {
+        super(nodeId, TimeUtils.currentTimeSeconds(), System.nanoTime(), remoteIpAddress, remotePort);
         setOpCode(eOpCode.TSI_CPU_DISCONNECTED.getValue());
     }
 
@@ -37,27 +33,33 @@ public class TsiCpuDisconnected extends TsiCpuPacket {
         ByteUtils.setUnsignedInt(cpuPacket.cvimData, POS_IPC_NODEID, cpuPacket.nodeId);
     }
 
-    public void parsing(TsiNodeVo nodeVo) {
+    public boolean parsing(TsiNodeVo nodeVo) {
 
-        // nodeVo.getNodeId == this.nodeId
         if (nodeVo == null) {
-            return;
+            return false;
         }
 
+        // CVIM DATA 생성
+        makeCvimPacket();
+
         TsiNodeAddVo tsiNodeAddVo = TsiCpuPacket.nodeAddManager.get(this.nodeId);
         if (tsiNodeAddVo == null) {
             // 연등지 정보가 없는 경우
-            makeCvimPacket();
-            return;
+            return true;
         }
 
         // 연등지 노드 카프카 패킷 생성
+        this.addNodes = new ArrayList<>();
+
         for (Integer key : tsiNodeAddVo.getAddNodeMap().keySet()){
             TsiNodeAddDetailVo detailVo = tsiNodeAddVo.getAddNodeMap().get(key);
             TsiCpuAddPacket addPacket = new TsiCpuAddPacket(detailVo.getNodeId(), this.timespec, this.remoteIp, this.remotePort);
             makeAddNodeCvimPaket(addPacket);
+
+            // 연등지 노드에 연결종료 메시지 생성
             this.addNodes.add(addPacket);
         }
+        return true;
     }
 
 }

+ 19 - 17
tsi-comm-server/src/main/java/com/tsi/comm/server/protocol/TsiCpuPacket.java

@@ -3,19 +3,18 @@ package com.tsi.comm.server.protocol;
 import com.tsi.comm.server.dto.TsiCvimAbnormal;
 import com.tsi.comm.server.dto.TsiCvimControl;
 import com.tsi.comm.server.dto.TsiCvimStatus;
+import com.tsi.comm.server.dto.mongodb.TcsNodeStatus;
 import com.tsi.comm.server.protocol.enums.eLightsStatus;
 import com.tsi.comm.server.protocol.enums.eLightsType;
 import com.tsi.comm.server.protocol.enums.eOpCode;
 import com.tsi.comm.server.protocol.enums.eTimeReliability;
-import com.tsi.comm.server.xnet.NettyUtils;
-import com.tsi.comm.server.dto.mongodb.TcsNodeStatus;
+import com.tsi.comm.server.repository.TsiAlarmManager;
 import com.tsi.comm.server.repository.TsiNodeAddManager;
 import com.tsi.comm.server.vo.TsiNodeAddDetailVo;
 import com.tsi.comm.server.vo.TsiNodeAddVo;
 import com.tsi.comm.server.vo.TsiNodeVo;
 import com.tsi.common.utils.ByteUtils;
 import com.tsi.common.utils.CRC16Utils;
-import io.netty.channel.Channel;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.extern.slf4j.Slf4j;
@@ -33,6 +32,7 @@ import static com.tsi.comm.server.protocol.TsiCvibProtocolSpec.*;
 public class TsiCpuPacket extends AbstractTsiPacket {
 
     protected static TsiNodeAddManager nodeAddManager;
+    protected static TsiAlarmManager alarmAddManager;
 
     private Object obj;
     private int  length;
@@ -44,19 +44,16 @@ public class TsiCpuPacket extends AbstractTsiPacket {
 
     protected List<TsiCpuAddPacket> addNodes;
 
-    public static void setNodeAddManager(TsiNodeAddManager nodeAddManager) {
+    public static void setNodeAddManager(TsiNodeAddManager nodeAddManager, TsiAlarmManager alarmAddManager) {
         TsiCpuPacket.nodeAddManager = nodeAddManager;
+        TsiCpuPacket.alarmAddManager = alarmAddManager;
     }
 
-    public TsiCpuPacket(long nodeId, long msec, long nsec, Channel channel) {
-        super(nodeId, msec, nsec, NettyUtils.getRemoteIpAddressToLong(channel), NettyUtils.getRemotePort(channel));
+    public TsiCpuPacket(long nodeId, long msec, long nsec, long remoteIpAddress, int remotePort) {
+        super(nodeId, msec, nsec, remoteIpAddress, remotePort);
         setOpCode(eOpCode.TSI_CPU_SIGNAL_NOTIFY.getValue());
     }
 
-    public TsiCpuPacket(long nodeId, long msec, long nsec, long remoteIpAddressToLong, int remotePort) {
-        super(nodeId, msec, nsec, remoteIpAddressToLong, remotePort);
-    }
-
     // FOR CVIM packet
 //    public TsiCpuPacket(long nodeId, byte[] value) {
 //        super(nodeId, TimeUtils.currentTimeSeconds(), System.nanoTime(), 0, 0);
@@ -102,7 +99,6 @@ public class TsiCpuPacket extends AbstractTsiPacket {
         if (packetLength > 0) {
             System.arraycopy(this.buf, 0, this.cvimData, POS_IPC_PACKET, packetLength);
         }
-        //log.error("CVIM: {}", HexString.fromBytes(this.cvimData));
     }
 
     /*
@@ -136,8 +132,13 @@ public class TsiCpuPacket extends AbstractTsiPacket {
 
     protected int checkPacket(TsiNodeVo obj, boolean checkCrc) {
 
+        if (this.buf == null) {
+            log.error("parsing: errno(-1), NodeId: {}, buf==null", this.nodeId);
+            return -1;
+        }
         // 0 단계. STX1, STX2 체크
         if (this.buf[INDEX_STX1] != STX1 || this.buf[INDEX_STX2] != STX2) {
+            TsiCpuPacket.alarmAddManager.reportPacketError(this.nodeId, this.buf, "STX", (int)(this.buf[INDEX_STX1] & 0xFF), (int)(this.buf[INDEX_STX2] & 0xFF));
             log.error("parsing: errno(-1), NodeId: {}, stx1: {}, stx2: {}", this.nodeId, this.buf[INDEX_STX1], this.buf[INDEX_STX2]);
             return -1;
         }
@@ -153,6 +154,7 @@ public class TsiCpuPacket extends AbstractTsiPacket {
 //        }
         final int reqLength = SIZE_PACKET_DATA + (SIZE_STATUS_DATA * this.count);
         if (this.length < reqLength ) {
+            TsiCpuPacket.alarmAddManager.reportPacketError(this.nodeId, this.buf, "LENGTH", reqLength, this.length);
             log.error("parsing: errno(-2), NodeId: {}, reqLength: {}, recvLength: {}", this.nodeId, reqLength, this.length);
             return -2;
         }
@@ -161,6 +163,7 @@ public class TsiCpuPacket extends AbstractTsiPacket {
         final int receivedCrc = ByteUtils.getUnsignedShort(this.buf, this.buf.length-2);
         final int calculatedCrc = CRC16Utils.CRC16_ccitt_cvim(this.buf, INDEX_LENGTH, this.length-2);  // 시작인덱스가 있으므로 전체길이로 계산
         if (receivedCrc != calculatedCrc) {
+            TsiCpuPacket.alarmAddManager.reportCrcError(this.nodeId, this.buf, receivedCrc, calculatedCrc);
             if (checkCrc || (obj != null && obj.isDump())) {
                 log.error("parsing: errno(-3), NodeId: {}, crc(recv/calc): {}/{}", this.nodeId, receivedCrc, calculatedCrc);
             }
@@ -183,20 +186,17 @@ public class TsiCpuPacket extends AbstractTsiPacket {
 
         obj.setSigCount(this.count);    // 신호현시 갯수 저장
 
-        // CVIM 데이터 및 TEST 데이터가 생성됨
-        makeCvimPacket();
-
         int result = checkPacket(obj, isCheckPacket);
         if (0 != result) {
-            if (-3 == result) {
-                obj.setCrcError(true);
-            }
             if (isCheckPacket) {
                 // 20250425: CRC 체크여부에 따라 바로 리턴(기본값은 체크여부가 true 임)
                 return result;
             }
         }
 
+        // CVIM 데이터 및 TEST 데이터가 생성됨
+        makeCvimPacket();
+
         TsiNodeAddVo tsiNodeAddVo = TsiCpuPacket.nodeAddManager.get(this.nodeId);
         if (tsiNodeAddVo == null) {
             // 연등지 정보가 없는 경우
@@ -249,9 +249,11 @@ public class TsiCpuPacket extends AbstractTsiPacket {
                         // 연등지 방향코드를 배열에 가지고 있기 때문에
                         List<byte[]> list = addStatus.get(detailVo.getNodeId());
                         if (list == null) {
+                            // 최초 데이터가 없을수 있기 때문에 null 을 체크한다.
                             list = new ArrayList<>();
                             addStatus.put(detailVo.getNodeId(), list);
                         }
+
                         if (dirIdx == 0) {
                             status[INDEX_STATUS_DIRECTION] = detailVo.getAddDirCode()[dirIdx];
                             list.add(status);

+ 46 - 0
tsi-comm-server/src/main/java/com/tsi/comm/server/repository/TsiAlarmManager.java

@@ -3,6 +3,7 @@ package com.tsi.comm.server.repository;
 import com.tsi.comm.server.vo.TsiAlarmConfigVo;
 import com.tsi.comm.server.xnet.NettyUtils;
 import com.tsi.common.utils.HexString;
+import io.netty.buffer.ByteBufUtil;
 import io.netty.channel.Channel;
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
@@ -24,6 +25,8 @@ public class TsiAlarmManager {
     private final Set<String> UNKNOWN_NODE_BUF_SET = ConcurrentHashMap.newKeySet();
     private final Set<String> UNKNOWN_IPADDR_SET = ConcurrentHashMap.newKeySet();
     private final Set<String> DUP_CONNECT_INFO_SET = ConcurrentHashMap.newKeySet();
+    private final Set<String> CRC_ERROR_INFO_SET = ConcurrentHashMap.newKeySet();
+    private final Set<String> PACKET_ERROR_INFO_SET = ConcurrentHashMap.newKeySet();
 
     public TsiAlarmConfigVo get(String code) {
         return this.tsiAlarmConfigMap.get(code);
@@ -109,4 +112,47 @@ public class TsiAlarmManager {
         MDC.clear();
     }
 
+    public void reportCrcError(Long nodeId, byte[] buf, int receivedCrc, int calculatedCrc) {
+        if (buf == null) {
+            return;
+        }
+        final String errorInfo = nodeId + "";
+        if (this.CRC_ERROR_INFO_SET.contains(errorInfo)) {
+            return;
+        }
+        this.CRC_ERROR_INFO_SET.add(errorInfo);
+
+        final String fileName = "crc_error";
+        MDC.put("filename", fileName);
+        try {
+            log.info("CRC Error: NodeId: {}, {} Bytes, crc(recv/calc): {}/{}", nodeId, buf.length, receivedCrc, calculatedCrc);
+            log.error("{}", ByteBufUtil.hexDump(buf));
+        }
+        catch(Exception e) {
+            // no logging
+        }
+        MDC.clear();
+    }
+    public void reportPacketError(Long nodeId, byte[] buf, String errType, int value1, int value2) {
+        if (buf == null) {
+            return;
+        }
+        final String errorInfo = nodeId + ":" + errType;
+        if (this.PACKET_ERROR_INFO_SET.contains(errorInfo)) {
+            return;
+        }
+        this.PACKET_ERROR_INFO_SET.add(errorInfo);
+
+        final String fileName = "crc_error";
+        MDC.put("filename", fileName);
+        try {
+            log.info("Packet Error: NodeId: {}, {} Bytes, {}: {}/{}", nodeId, buf.length, errType, value1, value2);
+            log.error("{}", ByteBufUtil.hexDump(buf));
+        }
+        catch(Exception e) {
+            // no logging
+        }
+        MDC.clear();
+    }
+
 }

+ 3 - 1
tsi-comm-server/src/main/java/com/tsi/comm/server/service/TsiCommPacketInitializer.java

@@ -1,6 +1,7 @@
 package com.tsi.comm.server.service;
 
 import com.tsi.comm.server.protocol.TsiCpuPacket;
+import com.tsi.comm.server.repository.TsiAlarmManager;
 import com.tsi.comm.server.repository.TsiNodeAddManager;
 import lombok.RequiredArgsConstructor;
 import org.springframework.stereotype.Component;
@@ -12,10 +13,11 @@ import javax.annotation.PostConstruct;
 public class TsiCommPacketInitializer {
 
     private final TsiNodeAddManager nodeAddManager;
+    private final TsiAlarmManager alarmAddManager;
 
     @PostConstruct
     public void init() {
-        TsiCpuPacket.setNodeAddManager(this.nodeAddManager);
+        TsiCpuPacket.setNodeAddManager(this.nodeAddManager, this.alarmAddManager);
     }
 
 }

+ 4 - 1
tsi-comm-server/src/main/java/com/tsi/comm/server/tcp/codec/CvimServerByteBufMessageDecoder.java

@@ -2,6 +2,7 @@ package com.tsi.comm.server.tcp.codec;
 
 import com.tsi.comm.server.protocol.TsiCpuPacket;
 import com.tsi.comm.server.protocol.TsiCvibProtocolSpec;
+import com.tsi.comm.server.xnet.NettyUtils;
 import com.tsi.common.utils.TimeUtils;
 import io.netty.buffer.ByteBuf;
 import io.netty.channel.ChannelHandler;
@@ -42,9 +43,11 @@ public class CvimServerByteBufMessageDecoder extends MessageToMessageDecoder<Byt
 
         // 노드 ID 추출
         final long nodeId = byteBuf.getUnsignedInt(TsiCvibProtocolSpec.INDEX_NODE_ID);
+        final long remoteIpAddress = NettyUtils.getRemoteIpAddressToLong(ctx.channel());
+        final int remotePort = NettyUtils.getRemotePort(ctx.channel());
 
         // 프로세스 패킷 생성
-        TsiCpuPacket packet = new TsiCpuPacket(nodeId, msec, nsec, ctx.channel());
+        TsiCpuPacket packet = new TsiCpuPacket(nodeId, msec, nsec, remoteIpAddress, remotePort);
         packet.setBuf(new byte[readableBytes]);
         byteBuf.readBytes(packet.getBuf());
         packet.setObj(null);  // TsiNodeVo 객체를 저장

+ 3 - 3
tsi-comm-server/src/main/java/com/tsi/comm/server/tcp/service/ConnectionLifecycleService.java

@@ -78,7 +78,9 @@ public class ConnectionLifecycleService {
             }
 
             // Disconnected 패킷 큐잉
-            TsiCpuDisconnected packet = new TsiCpuDisconnected(nodeVo.getNodeId(), ctx.channel());
+            final long remoteIpAddress = NettyUtils.getRemoteIpAddressToLong(ctx.channel());
+            final int remotePort = NettyUtils.getRemotePort(ctx.channel());
+            TsiCpuDisconnected packet = new TsiCpuDisconnected(nodeVo.getNodeId(), remoteIpAddress, remotePort);
             packet.setBuf(null);
             packet.setObj(nodeVo);
             if (pktQIdx != null) {
@@ -94,8 +96,6 @@ public class ConnectionLifecycleService {
             this.sessionManager.removeChannel(ctx.channel());
             ctx.channel().attr(TsiSessionManager.TSI_NODE_ATTRIBUTE_KEY).set(null);
 
-//            this.queueDistributorService.releaseQueue(nodeVo);  // 작업큐를 할당을 해제
-
             // --- 기존의 synchronized 블록 전체를 아래 코드로 대체 ---
             // TsiNodeVo 객체가 스스로 상태를 확인하고 안전하게 변경하도록 책임을 위임합니다.
             if (nodeVo.disconnectChannel(ctx.channel())) {

+ 3 - 2
tsi-comm-server/src/main/java/com/tsi/comm/server/vo/TsiNodeAddVo.java

@@ -2,8 +2,8 @@ package com.tsi.comm.server.vo;
 
 import lombok.Data;
 
-import java.util.Hashtable;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 @Data
 public class TsiNodeAddVo {
@@ -12,5 +12,6 @@ public class TsiNodeAddVo {
 
     // origin_dir_code 의 add_node_order 에 따라 연등지 교차로를 찾는다.
     // Key = origin_dir_code * 1000 + add_node_order
-    Map<Integer, TsiNodeAddDetailVo> addNodeMap = new Hashtable<>();
+//    Map<Integer, TsiNodeAddDetailVo> addNodeMap = new Hashtable<>();
+    Map<Integer, TsiNodeAddDetailVo> addNodeMap = new ConcurrentHashMap<>();
 }

+ 0 - 4
tsi-comm-server/src/main/java/com/tsi/comm/server/vo/TsiNodeVo.java

@@ -51,8 +51,6 @@ public class TsiNodeVo {
     private int logQIdx;
 
     private int sigCount;
-    private boolean crcError;
-    private boolean packetError;
 
     // 빈번한 패킷 수신 처리를 위한 변수
     private final AtomicLong lastProcessTime = new AtomicLong(0);
@@ -86,8 +84,6 @@ public class TsiNodeVo {
         this.dbmsQIdx = 0;
         this.logQIdx = 0;
         this.sigCount = 0;
-        this.crcError = false;
-        this.packetError = false;
 
         this.tsiNodeAddVo = null;
     }

+ 2 - 2
tsi-common/src/main/java/com/tsi/common/aspect/LoggingAspect.java

@@ -43,7 +43,7 @@ public class LoggingAspect extends AbstractLoggingAspect {
             return proceed;
         }
         catch (InterruptedException e) {
-            log.error("aspectProcessingElapsedTime: Thread interrupted", e);
+            log.error("aspectProcessingElapsedTime: Thread interrupted: {}", e.getMessage());
             throw e;  // 재던지기
         }
     }
@@ -65,7 +65,7 @@ public class LoggingAspect extends AbstractLoggingAspect {
         try {
             joinPoint.proceed();
         } catch (InterruptedException e) {
-            log.error("aspectSchedulingElapsedTime: Thread interrupted", e);
+            log.error("aspectSchedulingElapsedTime: Thread interrupted: {}", e.getMessage());
         }
         long executionTime = System.currentTimeMillis() - start;
 

+ 1 - 1
tsi-consumer/src/test/java/com/tsi/comm/consumer/TsiCommConsumerApplicationTests.java

@@ -152,7 +152,7 @@ public class TsiCommConsumerApplicationTests {
                         Thread.sleep(1000);
                     }
                     catch (Exception e) {
-                        log.error("{}", e.getMessage(), e);
+                        log.error("{}, {}", e.getMessage(), e.getMessage());
                     }
                 }
             });*/