Browse Source

add traceconfigfile

shjung 8 months ago
parent
commit
938cdef241

+ 2 - 0
conf/ggits-comm-server-trace.cfg

@@ -0,0 +1,2 @@
+#DUMP=RegionId,...
+DUMP=

+ 2 - 0
conf/ggits-tsinfo-server-trace.cfg

@@ -0,0 +1,2 @@
+#DUMP=RegionId,...
+DUMP=

+ 2 - 0
ggits-comm-server/conf/ggits-comm-server-trace.cfg

@@ -0,0 +1,2 @@
+#DUMP=RegionId,...
+DUMP=

+ 76 - 0
ggits-comm-server/src/main/java/com/sig/ggits/comm/server/config/TraceConfig.java

@@ -0,0 +1,76 @@
+package com.sig.ggits.comm.server.config;
+
+import com.its.common.utils.StringUtils;
+import com.sig.ggits.comm.server.GgitsCommServerApplication;
+import com.sig.ggits.comm.server.dto.RegionCenter;
+import com.sig.ggits.comm.server.repository.ApplicationRepository;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.List;
+import java.util.Properties;
+
+@Slf4j
+@Getter
+@Setter
+@ToString
+@RequiredArgsConstructor
+@Component
+public class TraceConfig {
+
+    private final ApplicationRepository repo;
+
+    private Properties getProperties() {
+        String traceFileName = System.getProperty("user.dir") + File.separator + "conf" + File.separator + GgitsCommServerApplication.APPLICATION_NAME + "-trace.cfg";
+        Properties props = new Properties();
+        try {
+            FileInputStream in = new FileInputStream(traceFileName);
+            props.load(in);
+            in.close();
+        }
+        catch(Exception e) {
+            log.error("{}.getProperties Exception: {}", this.getClass().getSimpleName(), e.toString());
+        }
+        return props;
+    }
+
+    private Integer getId(String id) {
+        try {
+            return Integer.parseInt(id);
+        }
+        catch(NumberFormatException e) {
+            return 0;
+        }
+    }
+
+    public void loadTraceInfo() {
+        try {
+            this.repo.getCenterMap().forEach((key, center) -> center.setDump(false));
+
+            Properties props = getProperties();
+            String dumps = props.getProperty("DUMP",  "").trim();
+            if (dumps.isEmpty()) {
+                return;
+            }
+
+            List<String> regionCds = StringUtils.split(dumps, ",");
+            regionCds.forEach(id -> {
+                RegionCenter center = this.repo.getCenterMap().get(getId(id.trim()));
+                if (center != null) {
+                    center.setDump(true);
+//                    log.info("TraceConfig.loadTraceInfo: Center Dump: {}", center.getCenterId());
+                }
+            });
+        }
+        catch(Exception e) {
+            log.error("{}.loadTraceInfo Exception: {}", this.getClass().getSimpleName(), e.toString());
+        }
+    }
+
+}

+ 1 - 0
ggits-comm-server/src/main/java/com/sig/ggits/comm/server/dto/RegionCenter.java

@@ -43,6 +43,7 @@ public class RegionCenter implements Serializable {
 
     private int recvSeqNo;
 
+    private boolean isDump;
     private int qSeq;
 
     // 센터 네트워크 상태 정보

+ 1 - 0
ggits-comm-server/src/main/java/com/sig/ggits/comm/server/entity/TbRegionCenter.java

@@ -58,6 +58,7 @@ public class TbRegionCenter {
                 .lastCommMilliSeconds(0)
                 .qSeq(0)
                 .recvSeqNo(0)
+                .isDump(false)
                 .build();
     }
 }

+ 15 - 0
ggits-comm-server/src/main/java/com/sig/ggits/comm/server/process/work/GgitsPacketWorker.java

@@ -1,5 +1,6 @@
 package com.sig.ggits.comm.server.process.work;
 
+import com.its.common.utils.SysUtils;
 import com.its.common.utils.TimeUtils;
 import com.sig.common.protocol.SigProtocolConst;
 import com.sig.ggits.comm.server.dto.IntDto;
@@ -77,6 +78,7 @@ public class GgitsPacketWorker extends AbstractAppWorker implements Runnable {
     public void process(Object object) {
         SigGgitsTsinfoDto data = (SigGgitsTsinfoDto)object;
         long popTimestamp = System.currentTimeMillis();
+        String logKey = "L00";
         int idx = 0;
         try {
             RegionCenter center = data.getCenter();//this.repo.getCenterMap().get(data.getLocalPort());
@@ -84,6 +86,9 @@ public class GgitsPacketWorker extends AbstractAppWorker implements Runnable {
                 log.warn("GgitsPacketWorker.process: [{}],Not Found Region Center By RegionId: {}", data.getLocalPort(), data.getLocalPort());
                 return;
             }
+            logKey = center.getLogKey();
+            MDC.put("id", logKey);
+
             List<IntStatusDto> statusLists = new ArrayList<>();
 
             byte stx = data.buffer[idx++];
@@ -101,6 +106,12 @@ public class GgitsPacketWorker extends AbstractAppWorker implements Runnable {
             int dataLength = ((data.buffer[idx++] & 0xFF) << 8) | (data.buffer[idx++] & 0xFF);
             int count      = ((data.buffer[idx++] & 0xFF) << 8) | (data.buffer[idx++] & 0xFF);
 
+            log.info("{}, {}, DataRecv: {} EA. {}.", center.getRegionCd(), center.getGgitsRegionNo(), count, collctDtime);
+
+            if (center.isDump()) {
+                log.info("RECV: [{}]. {} Bytes. {}", center.getLogKey(), data.buffer.length, SysUtils.byteArrayToHex(data.buffer));
+            }
+
 //            log.info("GgitsPacketWorker.process: [{}], Sequence {}, RegionId {}, DataLength {}, Count {}, {} Bytes. {} ms.",
 //                    data.getLocalPort(), sequence, regionId, dataLength, count, data.getBuffer().length, timestamp - data.getTimestamp());
 
@@ -280,6 +291,10 @@ public class GgitsPacketWorker extends AbstractAppWorker implements Runnable {
         catch (Exception e) {
             log.error("GgitsPacketWorker.process: Exception: [{}] {}", data.getLocalPort(), e.toString());
         }
+        finally {
+            MDC.remove(logKey);
+            MDC.clear();
+        }
     }
 
     public void report() {

+ 14 - 0
ggits-comm-server/src/main/java/com/sig/ggits/comm/server/scheduler/SigCommScheduler.java

@@ -1,6 +1,7 @@
 package com.sig.ggits.comm.server.scheduler;
 
 import com.sig.ggits.comm.server.config.KafkaConfig;
+import com.sig.ggits.comm.server.config.TraceConfig;
 import com.sig.ggits.comm.server.repository.ApplicationRepository;
 import com.sig.ggits.comm.server.service.UnitSystService;
 import lombok.RequiredArgsConstructor;
@@ -20,6 +21,19 @@ public class SigCommScheduler {
     private final UnitSystService unitSystService;
     private final ApplicationRepository repository;
 
+    private final TraceConfig traceConfig;
+
+    @Async
+    @Scheduled(cron = "30 * * * * *")  // 1분주기 작업 실행
+    public void loadTraceConfig() {
+        try {
+            this.traceConfig.loadTraceInfo();
+        }
+        catch(Exception e) {
+            log.error("ApplicationScheduler.loadTraceConfig: Exception {}", e.getMessage());
+        }
+    }
+
     @Async
     @Scheduled(cron = "10 * * * * *")  // 1분주기 작업 실행
     public void updateUnitSystStts() {

+ 25 - 15
ggits-comm-server/src/main/java/com/sig/ggits/comm/server/udp/SigGgitsTsinfoUdpServerPacketHandler.java

@@ -12,6 +12,7 @@ import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.SimpleChannelInboundHandler;
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
 import org.springframework.stereotype.Component;
 
 import java.io.IOException;
@@ -40,22 +41,31 @@ public class SigGgitsTsinfoUdpServerPacketHandler extends SimpleChannelInboundHa
 			log.error("SigGgitsTsinfoUdpServerPacketHandler: Local Address {}, Received Data Unknown Center Region Id: {}", NettyUtils.getLocalAddress(ctx.channel()), NettyUtils.getTcpAddress(ctx.channel()));
 			return;
 		}
-		center.setLastCommMilliSeconds(System.currentTimeMillis());
-		if (!center.isCommOnline()) {
-			log.info("Region Center Comm Start: {}", center.getRegionCd());
-			center.setCommOnline(true);
-			// Update Region Center Comm OK...
-			TbRegionCenterComm stts = TbRegionCenterComm.builder()
-					.regionCd(center.getRegionCd())
-					.commState(TbRegionCenterComm.CENTER_COMM_START)
-					.build();
-			// Update Region Center Comm Failed
-			final long currTime = System.currentTimeMillis();
-			this.dbmsDataProcess.add(new DbmsData(center, center.getQSeq(), currTime, currTime, currTime,
-					center.getRegionCd(), center.getRegionId(), DbmsData.DBMS_DATA_CENTER_STTS, stts));
+		try {
+			MDC.put("id", center.getLogKey());
+			//log.info("{}, {}, DataRecv.", center.getRegionCd(), center.getGgitsRegionNo());
+
+			center.setLastCommMilliSeconds(System.currentTimeMillis());
+			if (!center.isCommOnline()) {
+				log.info("Region Center Comm Start: {}", center.getRegionCd());
+				center.setCommOnline(true);
+				// Update Region Center Comm OK...
+				TbRegionCenterComm stts = TbRegionCenterComm.builder()
+						.regionCd(center.getRegionCd())
+						.commState(TbRegionCenterComm.CENTER_COMM_START)
+						.build();
+				// Update Region Center Comm Failed
+				final long currTime = System.currentTimeMillis();
+				this.dbmsDataProcess.add(new DbmsData(center, center.getQSeq(), currTime, currTime, currTime,
+						center.getRegionCd(), center.getRegionId(), DbmsData.DBMS_DATA_CENTER_STTS, stts));
+			}
+			udpData.setCenter(center);
+			this.packetProcess.add(udpData, center.getQSeq());
 		}
-		udpData.setCenter(center);
-		this.packetProcess.add(udpData, center.getQSeq());
+		finally {
+			MDC.remove(center.getLogKey());
+			MDC.clear();
+        }
 	}
 
 //	public void channelReadComplete(ChannelHandlerContext ctx) {

+ 4 - 0
ggits-comm-server/src/main/resources/logback-spring.xml

@@ -66,6 +66,10 @@
             <appender-ref ref="FILE_PACKET"/>
             <appender-ref ref="FILE_ERROR"/>
         </logger>
+        <logger name="${APP_CLASS_PATH}.process.work" level="INFO" additivity="false">
+            <appender-ref ref="FILE_PACKET"/>
+            <appender-ref ref="FILE_ERROR"/>
+        </logger>
 
         <logger name="${APP_CLASS_PATH}.udp" level="INFO" additivity="true">
             <appender-ref ref="FILE_SESSION"/>

+ 2 - 0
ggits-tsinfo-server/conf/ggits-tsinfo-server-trace.cfg

@@ -0,0 +1,2 @@
+#DUMP=RegionId,...
+DUMP=

+ 1 - 1
ggits-tsinfo-server/src/main/java/com/sig/ggits/tsinfo/server/GgitsTsinfoServerApplication.java

@@ -27,7 +27,7 @@ import java.util.Date;
 @ComponentScan(basePackages = {"com.its.common.spring", "com.sig.ggits.tsinfo.server.config", "com.sig.ggits.tsinfo.server"})
 public class GgitsTsinfoServerApplication implements CommandLineRunner, ApplicationListener<ContextClosedEvent>, InitializingBean, DisposableBean {
 
-    private static final String APPLICATION_NAME = "ggits-tsinfo-server";
+    public static final String APPLICATION_NAME = "ggits-tsinfo-server";
 
     public static void main(String[] args) {
         SpringApplication application = new SpringApplicationBuilder()

+ 76 - 0
ggits-tsinfo-server/src/main/java/com/sig/ggits/tsinfo/server/config/TraceConfig.java

@@ -0,0 +1,76 @@
+package com.sig.ggits.tsinfo.server.config;
+
+import com.its.common.utils.StringUtils;
+import com.sig.ggits.tsinfo.server.GgitsTsinfoServerApplication;
+import com.sig.ggits.tsinfo.server.dto.GgitsRegion;
+import com.sig.ggits.tsinfo.server.repository.ApplicationRepository;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import lombok.ToString;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.List;
+import java.util.Properties;
+
+@Slf4j
+@Getter
+@Setter
+@ToString
+@RequiredArgsConstructor
+@Component
+public class TraceConfig {
+
+    private final ApplicationRepository repo;
+
+    private Properties getProperties() {
+        String traceFileName = System.getProperty("user.dir") + File.separator + "conf" + File.separator + GgitsTsinfoServerApplication.APPLICATION_NAME + "-trace.cfg";
+        Properties props = new Properties();
+        try {
+            FileInputStream in = new FileInputStream(traceFileName);
+            props.load(in);
+            in.close();
+        }
+        catch(Exception e) {
+            log.error("{}.getProperties Exception: {}", this.getClass().getSimpleName(), e.toString());
+        }
+        return props;
+    }
+
+    private Integer getId(String id) {
+        try {
+            return Integer.parseInt(id);
+        }
+        catch(NumberFormatException e) {
+            return 0;
+        }
+    }
+
+    public void loadTraceInfo() {
+        try {
+            this.repo.getCenterMap().forEach((key, center) -> center.setDump(false));
+
+            Properties props = getProperties();
+            String dumps = props.getProperty("DUMP",  "").trim();
+            if (dumps.isEmpty()) {
+                return;
+            }
+
+            List<String> regionCds = StringUtils.split(dumps, ",");
+            regionCds.forEach(id -> {
+                GgitsRegion center = this.repo.getCenterMap().get(getId(id.trim()));
+                if (center != null) {
+                    center.setDump(true);
+//                    log.info("TraceConfig.loadTraceInfo: Center Dump: {}", center.getCenterId());
+                }
+            });
+        }
+        catch(Exception e) {
+            log.error("{}.loadTraceInfo Exception: {}", this.getClass().getSimpleName(), e.toString());
+        }
+    }
+
+}

+ 4 - 1
ggits-tsinfo-server/src/main/java/com/sig/ggits/tsinfo/server/dto/GgitsRegion.java

@@ -29,6 +29,7 @@ public class GgitsRegion implements Serializable {
     private boolean isCommOnline;
     private long lastCommMilliSeconds;
 
+    private boolean isDump;
     private String logKey;
     private long sendSeq;
 
@@ -40,9 +41,11 @@ public class GgitsRegion implements Serializable {
         this.serverPort = serverPort;
         this.regionNm = regionNm;
 
-        this.logKey = String.valueOf(this.ggitsRegionNo);
+        //this.logKey = String.valueOf(this.ggitsRegionNo);
+        this.logKey = String.valueOf(this.regionCd);
         this.isCommOnline = false;
         this.lastCommMilliSeconds = 0;
+        this.isDump = false;
 
         initNet();
     }

+ 14 - 22
ggits-tsinfo-server/src/main/java/com/sig/ggits/tsinfo/server/scheduler/ApplicationScheduler.java

@@ -1,8 +1,11 @@
 package com.sig.ggits.tsinfo.server.scheduler;
 
+import com.sig.ggits.tsinfo.server.config.TraceConfig;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
 @Slf4j
@@ -11,28 +14,17 @@ import org.springframework.stereotype.Component;
 @Component
 public class ApplicationScheduler {
 
-//    @Async
-//    @Scheduled(cron = "0/10 * * * * *")  // 10초 주기 작업 실행
-//    public void reportNodeSessionAlive() {
-////        Elapsed elapsed = new Elapsed();
-////        this.appRepositoryService.reportChannelSessions();
-////        log.info("{}", String.format("%25s: %s", "reportNodeSessionAlive", TimeUtils.elapsedTimeStr(elapsed.nanoSeconds())));
-//    }
+    private final TraceConfig traceConfig;
 
-//    @Async
-//    @Scheduled(cron = "0/30 * * * * *")  // 10초 주기 작업 실행
-//    public void updateProcessState() {
-////        Elapsed elapsed = new Elapsed();
-////        this.unitSystService.updateUnitSystStts(true);
-////        log.info("{}", String.format("%25s: %s", "updateProcessState", TimeUtils.elapsedTimeStr(elapsed.nanoSeconds())));
-//    }
-
-//    @Async
-//    @Scheduled(cron = "0 * * * * *")  // 1분 주기 작업 실행
-//    public void staticsForPacketMinute() {
-////        Elapsed elapsed = new Elapsed();
-//        //TsiTpmsManager.getInstance().resetMinute();
-//        //log.info("{}", String.format("%25s: %s", "staticsForPacketMinute", TimeUtils.elapsedTimeStr(elapsed.nanoSeconds())));
-//    }
+    @Async
+    @Scheduled(cron = "30 * * * * *")  // 1분주기 작업 실행
+    public void loadTraceConfig() {
+        try {
+            this.traceConfig.loadTraceInfo();
+        }
+        catch(Exception e) {
+            log.error("ApplicationScheduler.loadTraceConfig: Exception {}", e.getMessage());
+        }
+    }
 
 }

+ 71 - 53
ggits-tsinfo-server/src/main/java/com/sig/ggits/tsinfo/server/service/worker/TsinfoFileWorker.java

@@ -1,10 +1,12 @@
 package com.sig.ggits.tsinfo.server.service.worker;
 
+import com.its.common.utils.SysUtils;
 import com.sig.common.protocol.SigProtocolConst;
 import com.sig.ggits.tsinfo.server.dto.GgitsRegion;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
 import org.springframework.util.StringUtils;
 
 import java.io.File;
@@ -32,6 +34,7 @@ public class TsinfoFileWorker implements Runnable, AutoCloseable {
     private InetAddress serverAddress;
     private DatagramSocket datagramSocket;
     private int packetSeq = 0;
+    private int sendLcNoCnt = 0;
 
     public TsinfoFileWorker(GgitsRegion center, String filePath, String absoluteFilePath) throws IOException {
         this.service = FileSystems.getDefault().newWatchService();
@@ -50,7 +53,8 @@ public class TsinfoFileWorker implements Runnable, AutoCloseable {
             this.datagramSocket = new DatagramSocket();
             try {
                 this.serverAddress = InetAddress.getByName(this.center.getServerIp());
-            } catch (UnknownHostException e) {
+            }
+            catch (UnknownHostException e) {
                 log.error("{}", e.getMessage());
                 return false;
             }
@@ -64,10 +68,10 @@ public class TsinfoFileWorker implements Runnable, AutoCloseable {
     @Override
     public void run() {
         if (!initUdpChannel()) {
-            log.error("TsinfoFileWorker.run: initUdpChannel failed: {}, {}", this.filePath, this.absolutePath);
+            log.error("TsinfoFileWorker.run: initUdpChannel failed: {}, {}, {}", this.center.getRegionCd(), this.filePath, this.absolutePath);
             return;
         }
-        log.info("TsinfoFileWorker.run: Start File Watcher: {}, {}", this.filePath, this.absolutePath);
+        log.info("TsinfoFileWorker.run: Start File Watcher: {}, {}, {}", this.center.getRegionCd(), this.filePath, this.absolutePath);
 
         String oldFileName = "";
         long oldFileSize = 0;
@@ -81,66 +85,75 @@ public class TsinfoFileWorker implements Runnable, AutoCloseable {
                     key = service.take();
                 }
                 catch (InterruptedException e) {
-                    log.error("{}, {}", this.filePath, e.getMessage());
+                    log.error("{}, {}, {}", this.center.getRegionCd(), this.filePath, e.getMessage());
                     Thread.currentThread().interrupt();
                     break;
                 }
 
                 if (key.isValid()) {
                     List<WatchEvent<?>> watchEvents = key.pollEvents();
-                    for (WatchEvent<?> watchEvent : watchEvents) {
-                        WatchEvent<Path> pathEvent = (WatchEvent<Path>) watchEvent;
-                        Path path = pathEvent.context();
-                        WatchEvent.Kind<Path> eventKind = pathEvent.kind();
-
-                        if (eventKind != StandardWatchEventKinds.ENTRY_MODIFY) {
-                            log.warn("{}, Unsupported event, {}", this.filePath, eventKind.name());
-                            continue;
-                        }
+                    try {
+                        MDC.put("id", this.center.getLogKey());
 
-                        // A1-20240723153652.dat
-                        String fileName = path.toString();
-                        if (fileName.length() != 21) {
-                            log.error("{}, FileName Length Error. {}", this.filePath, fileName);
-                            continue;
-                        }
-                        String fileExt = StringUtils.getFilenameExtension(fileName);
-                        if (!"dat".equalsIgnoreCase(fileExt)) {
-                            log.error("{}, FileName Extension Error. {}", this.filePath, fileName);
-                            continue;
-                        }
+                        for (WatchEvent<?> watchEvent : watchEvents) {
+                            WatchEvent<Path> pathEvent = (WatchEvent<Path>) watchEvent;
+                            Path path = pathEvent.context();
+                            WatchEvent.Kind<Path> eventKind = pathEvent.kind();
 
-                        Path absoluteFilePath = FileSystems.getDefault().getPath(this.absolutePath + File.separator + fileName);
-                        long fileSize = absoluteFilePath.toFile().length();
+                            if (eventKind != StandardWatchEventKinds.ENTRY_MODIFY) {
+                                log.warn("{}, {}, Unsupported event, {}", this.center.getRegionCd(), this.filePath, eventKind.name());
+                                continue;
+                            }
 
-                        if (fileSize == 0) {
-                            log.warn("{}, FileSize is zero, {}", this.filePath, fileName);
-                            continue;
-                        }
-                        if (fileName.equals(oldFileName)) {
-                            log.warn("{}, FileName is equals, {}, {}, {}, {}", this.filePath, fileName, oldFileName, oldFileSize, fileSize);
-                            continue;
-                        }
+                            // A1-20240723153652.dat
+                            String fileName = path.toString();
+                            if (fileName.length() != 21) {
+                                log.error("{}, {}, FileName Length Error. {}", this.center.getRegionCd(), this.filePath, fileName);
+                                continue;
+                            }
+                            String fileExt = StringUtils.getFilenameExtension(fileName);
+                            if (!"dat".equalsIgnoreCase(fileExt)) {
+                                log.error("{}, {}, FileName Extension Error. {}", this.center.getRegionCd(), this.filePath, fileName);
+                                continue;
+                            }
+
+                            Path absoluteFilePath = FileSystems.getDefault().getPath(this.absolutePath + File.separator + fileName);
+                            long fileSize = absoluteFilePath.toFile().length();
+
+                            if (fileSize == 0) {
+                                log.warn("{}, {}, FileSize is zero, {}", this.center.getRegionCd(), this.filePath, fileName);
+                                continue;
+                            }
+                            if (fileName.equals(oldFileName)) {
+                                log.warn("{}, {}, FileName is equals, {}, {}, {}, {}", this.center.getRegionCd(), this.filePath, fileName, oldFileName, oldFileSize, fileSize);
+                                continue;
+                            }
 
-                        //remainder = (int)(fileSize % 10);
-                        //dataCount = (int)(fileSize / 10);
-                        createTime = fileName.substring(3, 17);
-                        for (int ii = 0; ii < 2; ii++) {
-                            calDataCount = tsinfoDataSend(absoluteFilePath, fileName, createTime);
-                            log.info("{}, DataSend: {}", this.filePath, calDataCount);
-                            if (calDataCount > 0) {
-                                break;
+                            //remainder = (int)(fileSize % 10);
+                            //dataCount = (int)(fileSize / 10);
+                            createTime = fileName.substring(3, 17);
+                            for (int ii = 0; ii < 2; ii++) {
+                                calDataCount = tsinfoDataSend(absoluteFilePath, fileName, createTime);
+                                log.info("{}, {}, DataSend: {} EA. {}.", this.center.getRegionCd(), this.filePath, this.sendLcNoCnt, fileName);
+                                if (calDataCount > 0) {
+                                    break;
+                                }
                             }
+                            this.center.setLastCommMilliSeconds(System.currentTimeMillis());
+                            this.center.setSendSeq(this.center.getSendSeq() + 1);
+                            oldFileName = fileName;
+                            oldFileSize = fileSize;
+                            //                        if (calDataCount > 0) {
+                            //                            this.center.setClctTime(createTime);
+                            //                            this.center.setClctCount(calDataCount);
+                            //                        }
                         }
-                        this.center.setLastCommMilliSeconds(System.currentTimeMillis());
-                        this.center.setSendSeq(this.center.getSendSeq()+1);
-                        oldFileName = fileName;
-                        oldFileSize = fileSize;
-//                        if (calDataCount > 0) {
-//                            this.center.setClctTime(createTime);
-//                            this.center.setClctCount(calDataCount);
-//                        }
                     }
+                    finally {
+                        MDC.remove(this.center.getLogKey());
+                        MDC.clear();
+                    }
+
                     if (!key.reset()) {
                         log.error("{}, FileWatcher Event Reset Error....", this.filePath);
                         break;
@@ -175,12 +188,14 @@ public class TsinfoFileWorker implements Runnable, AutoCloseable {
         byte min = (byte)now.getMinute();
         byte sec = (byte)now.getSecond();
 
+        this.sendLcNoCnt = 0;
         File file = new File(absoluteFilePath.toString());
         try (FileInputStream fileInputStream = new FileInputStream(file)) {
             while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                 // 데이터 길이 계산 (2바이트)
                 short dataLength = (short) bytesRead;
                 short count = (short)(dataLength / 10);
+                this.sendLcNoCnt += count;
                 this.packetSeq++;
 
                 // Packet Frame Head
@@ -216,16 +231,19 @@ public class TsinfoFileWorker implements Runnable, AutoCloseable {
                 packet.getBytes(packet.readerIndex(), bytes);
                 java.net.DatagramPacket sendPacket = new java.net.DatagramPacket(bytes, bytes.length, this.serverAddress, this.center.getServerPort());
                 this.datagramSocket.send(sendPacket);
-//                log.info("Packet Frame Sent: Data {} EA, Total {} Bytes.", count, length);
+                if (this.center.isDump()) {
+                    //log.info("Packet Frame Sent: Data {} EA, Total {} Bytes.", count, length);
+                    log.info("SEND: [{}]. {} Bytes. {}", center.getLogKey(), bytes.length, SysUtils.byteArrayToHex(bytes));
+                }
                 calDataCount++;
             }
         }
         catch (FileNotFoundException e) {
-            log.warn("{}, {}, File Not Found. {}", this.filePath, absoluteFilePath, e.getMessage());
+            log.warn("{}, {}, {}, File Not Found. {}", this.center.getRegionCd(), this.filePath, absoluteFilePath, e.getMessage());
             return -1;
         }
         catch (IOException e) {
-            log.warn("{}, {}, IOException: {}", this.filePath, absoluteFilePath, e.getMessage());
+            log.warn("{}, {}, {}, IOException: {}", this.center.getRegionCd(), this.filePath, absoluteFilePath, e.getMessage());
             return calDataCount;
         }
         return calDataCount;