xiejun
2023-11-26 c4d687aacfb4e7b6ee5ce67df93cf2f8d8df80c1
Source/UBCS/ubcs-ops/ubcs-log/src/main/java/com/vci/ubcs/log/service/impl/LogLocalServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,310 @@
package com.vci.ubcs.log.service.impl;
import com.vci.ubcs.log.vo.LocalLogVO;
import com.vci.ubcs.log.service.ILogLocalService;
import com.vci.ubcs.log.entity.LocalLog;
import com.vci.ubcs.resource.utils.FileUtil;
import com.vci.ubcs.resource.utils.ZipUtil;
import com.vci.ubcs.starter.exception.VciBaseException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springblade.core.log.exception.ServiceException;
import com.vci.ubcs.omd.cache.EnumCache;
import com.vci.ubcs.omd.enums.EnumEnum;
import com.vci.ubcs.resource.bo.FileObjectBO;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.*;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.rmi.ServerException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
 * æœ¬åœ°ç³»ç»Ÿæ—¥å¿—
 * @author ludc
 * @date 2023/10/31 15:39
 */
@Service
@Slf4j
public class LogLocalServiceImpl implements ILogLocalService{
   /**
    * å„个服务存放的的父路径
    */
   @Value("${local-log.parent-path:/data1/ubcs/ubcs-server}")
   private String PARENTPATH;
   /**
    * æ—¥å¿—文件的具体位置
    */
   @Value("${local-log.log-path:/target/log}")
   private String LOGPATH;
   /**
    * å½“前操作系统,是否为windows系统
    */
   private Boolean isWindows = true;
   {
      String os = System.getProperty("os.name").toLowerCase();
      //默认就配置为windows的,如果不是当前系统不是windows就需要对其转换为linux的文件路径格式
      if (!os.contains("win")) {
         this.PARENTPATH = this.PARENTPATH.substring(this.PARENTPATH.lastIndexOf(":") + 1).replace("\\", "/");
         this.LOGPATH = this.LOGPATH.replace("\\", "/");
         this.isWindows = false;
      }
   }
   /**
    * åŽ‹ç¼©æ–‡ä»¶çš„å·¥å…·ç±»
    */
   @Resource
   private ZipUtil zipUtil;
   /**
    * èŽ·å–æœ¬åœ°æ—¥å¿—åˆ—è¡¨
    * @param logParentPath
    * @return
    */
   //@Override
   public List<LocalLog> getSystemLogList(String logParentPath) {
      List<LocalLog> localLogs = new ArrayList<>();
      // ä¸ä¸ºç©ºè¯´æ˜Žæ˜¯åŠ è½½å½“å‰è¿™ä¸ªæœåŠ¡è·¯å¾„ä¸‹çš„æ—¥å¿—æ–‡ä»¶
      if(Func.isNotEmpty(logParentPath)){
         File file = new File(logParentPath);
         if (file.isDirectory()) {
            File[] files = file.listFiles();
            Arrays.stream(files).forEach(item->{
               // ç»„建日志文件对象
               LocalLog localLog = new LocalLog();
               localLog.setLogName(item.getName());
               localLog.setLogType(getLogType(item.getName()));
               localLog.setCreateTime(getLastModifiedOrCreatTime(false,logParentPath));
               localLog.setLastModifier(getLastModifiedOrCreatTime(true,logParentPath));
               localLog.setLogPath(logParentPath);
               String serviceId = getServiceId(logParentPath);
               localLog.setServiceId(serviceId);
               localLog.setServiceName(getServiceName(serviceId));
               localLog.setHasChildren(false);
               localLogs.add(localLog);
            });
         }
      }else {
         File fileDir = new File(PARENTPATH);
         File[] childDir = fileDir.listFiles();
         Arrays.stream(childDir).forEach(dir->{
            if(dir.getName().contains("ubcs_")){
               String fullPath = dir.getPath() + LOGPATH;
               File file = new File(fullPath);
               LocalLog localLog = new LocalLog();
               localLog.setLastModifier(getLastModifiedOrCreatTime(true,fullPath));
               localLog.setCreateTime(getLastModifiedOrCreatTime(false,fullPath));
               localLog.setLogPath(fullPath);
               String serviceId = getServiceId(file.getPath());
               localLog.setServiceId(serviceId);
               String serviceName = getServiceName(serviceId);
               localLog.setServiceName(serviceName);
               localLog.setLogType(serviceName+"日志父目录");
               localLog.setLogName(serviceName+"日志父目录");
               localLog.setHasChildren(true);
               localLogs.add(localLog);
            }
         });
      }
      return localLogs;
   }
   /**
    * èŽ·å–æ–‡ä»¶æœ€åŽä¿®æ”¹æˆ–è€…åˆ›å»ºæ—¶é—´
    * @param isModifier
    * @return
    */
   private String getLastModifiedOrCreatTime(boolean isModifier,String pathStr) {
      Path path = FileSystems.getDefault().getPath(pathStr);
      String date = "";
      try {
         BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class);
         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         // æ˜¯èŽ·å–æœ€åŽä¿®æ”¹æ—¶é—´
         if(isModifier){
            date = dateFormat.format(new Date(attr.lastModifiedTime().toMillis()));
         }else {
            date = dateFormat.format(new Date(attr.creationTime().toMillis()));
         }
      } catch (IOException e) {
         throw new ServiceException("Error reading file date attributes: " + e.getMessage());
      }
      return date;
   }
   /**
    * èŽ·å–æ—¥å¿—ç±»åž‹
    * @param fileName
    * @return
    */
   private String getLogType(String fileName){
      //判断日志的的类型
      if (fileName.contains("error")) {
         return "Error";
      } else if (fileName.contains("info")) {
         return "Info";
      } else if (fileName.contains("warning")) {
         return "Warning";
      } else {
         return "Unknown";
      }
   }
   /**
    * èŽ·å–æœåŠ¡ID
    * @param servciePath
    * @return
    */
   private String getServiceId(String servciePath){
      // æ ¹æ®å½“前操作系统来决定是通过什么字符来截取
      String[] parts = servciePath.split(this.isWindows ? "\\\\":"/");
      String extractedString = "";
      if(parts.length > 3){
         extractedString = parts[parts.length - 3];
      }
      return extractedString;
   }
   /**
    * èŽ·å–æœåŠ¡åç§°
    * @param serViceId
    * @return
    */
   private String getServiceName(String serViceId){
      return EnumCache.getValue(EnumEnum.SERCIVE_NAME_ROLE, serViceId);
   }
   /**
    * æˆªå–路径中的日志文件名称
    * @param logFullPath
    * @return
    */
   private String getLogFileName(String logFullPath){
      // æ ¹æ®å½“前操作系统来决定是通过什么字符来截取
      String[] parts = logFullPath.split(this.isWindows ? "\\\\":"/");
      String logFileName = "";
      if(parts.length > 3){
         logFileName = parts[parts.length - 1];
      }
      return logFileName;
   }
   /**
    * ä¸‹è½½æ—¥å¿—文件
    * @param localLogVO ä¸‹è½½æ—¥å¿—对象
    * @return
    * @throws ServerException
    */
   @Override
   public FileObjectBO downloadLogByServiceNameAndFileName(LocalLogVO localLogVO) throws ServerException {
      if(Func.isEmpty(localLogVO) || Func.isEmpty(localLogVO.getLogPath())){
         throw new ServerException("未获取到该日志路径!");
      }
      FileObjectBO fileObjectBO = new FileObjectBO();
      String logFullPaths = localLogVO.getLogFullPaths();
      // åˆ¤æ–­æ˜¯å¦æ˜¯çˆ¶ç›®å½•
      if(!localLogVO.getHasChildren()){
         //只下载一个日志文件
         File file = new File(logFullPaths);
         if(!file.isFile() || !file.exists()){
            throw new ServerException("本地日志文件路径"+ logFullPaths +"中未找到日志");
         }
         try {
            fileObjectBO.setName(file.getName());
            fileObjectBO.setInputStream(new FileInputStream(file));
            fileObjectBO.setFileLocalPath(logFullPaths);
            fileObjectBO.setFileExtension(".log");
         }catch (Throwable e){
            throw new VciBaseException("获取文件的流有问题",new String[]{logFullPaths},e);
         }
      }else{
         // æ˜¯çˆ¶ç›®å½•,所以需要获取到下面的所有子目录
         // æœ‰å¤šä¸ªï¼Œéœ€è¦ä½¿ç”¨zip进行压缩
         String tempFolder = FileUtil.getDefaultTempFolder();
         File[] file1 = new File(logFullPaths).listFiles();
         if(file1.length > 0){
            Arrays.stream(file1).forEach(item->{
               String fileName = tempFolder + File.separator + System.currentTimeMillis() + ".log";
               File file = new File(fileName);
               try {
                  if(!file.exists()) {
                     file.createNewFile();
                  }
               }catch (Throwable e){
                  throw new VciBaseException("创建文件出错,{0}",new String[]{fileName});
               }
               File logFile = new File(item.getPath());
               if(!logFile.exists() || !logFile.isFile()){
                  throw new VciBaseException("本地日志文件路径"+item.getPath()+"中未找到日志");
               }
               try(OutputStream os = new FileOutputStream(file);
                  InputStream ins = new FileInputStream(logFile);
               ){
                  IOUtils.copy(ins,os);
               }catch (Throwable e){
                  throw new VciBaseException("下载文件到临时文件夹里出错,{0}",new String[]{fileName});
               }
            });
            String zipName = new File(tempFolder).getPath() + File.separator + getLogFileName(logFullPaths) + "等"+file1.length + "个文件.zip";
            zipUtil.folderToZipFile(tempFolder,zipName);
            fileObjectBO.setFileLocalPath(zipName);
            fileObjectBO.setFileExtension(".log");
            if(log.isDebugEnabled()){
               log.debug("下载文件的信息,",zipName);
            }
         }
      }
      return fileObjectBO;
   }
   /**
    * åˆ é™¤æ—¥å¿—文件
    * @param localLogVO æ–‡ä»¶å…¨è·¯å¾„集合
    * @throws ServerException
    */
   @Override
   public R deleteLogFile(LocalLogVO localLogVO) throws ServerException {
      List<String> resMsgs = new ArrayList<>();
      // åˆ¤æ–­æ˜¯å¦æ˜¯æ—¥å¿—顶层目录
      if(localLogVO.getHasChildren()){
         // æ˜¯é¡¶å±‚目录,需要循环去删除包含的所有日志文件
         File parentFile = new File(localLogVO.getLogFullPaths());
         if(parentFile.isDirectory()){
            Arrays.stream(parentFile.listFiles()).forEach(logFile->{
               if (logFile.exists()) {
                  //删除失败的直接记录下文件名
                  if (!logFile.delete()) {
                     resMsgs.add(getLogFileName(logFile.getPath()));
                  }
               }
            });
         }
      }else {
         // å•个删除
         File file = new File(localLogVO.getLogFullPaths());
         if (file.exists()) {
            //删除失败的直接记录下文件名
            if (!file.delete()) {
               resMsgs.add(getLogFileName(localLogVO.getLogFullPaths()));
            }
         }
      }
      return resMsgs.size()==0 ? R.success("删除成功!"):R.fail("以下日志文件:"+resMsgs.stream().collect(Collectors.joining(","))+"删除失败!");
   }
}