package com.vci.ubcs.log.service.impl;
|
|
import com.vci.ubcs.log.enumpack.ServiceNameRoleEnum;
|
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.context.EnvironmentAware;
|
import org.springframework.core.env.Environment;
|
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, EnvironmentAware {
|
|
/**
|
* 各个服务存放的的父路径
|
*/
|
@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;
|
|
/**
|
* 根据当前运行的环境,对配置的日志路径格式进行调整
|
* @param environment
|
*/
|
@Override
|
public void setEnvironment(Environment environment) {
|
String os = environment.getProperty("os.name").toLowerCase();
|
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<LocalLogVO> getSystemLogList(String logParentPath) {
|
List<LocalLogVO> localLogsVO = new ArrayList<>();
|
// 不为空说明是加载当前这个服务路径下的日志文件
|
if(Func.isNotEmpty(logParentPath)){
|
File file = new File(logParentPath);
|
if (file.isDirectory()) {
|
File[] files = file.listFiles();
|
if(Func.isNotEmpty(files) && files.length>0){
|
Arrays.stream(files).forEach(item->{
|
// 组建日志文件对象
|
LocalLogVO localLog = new LocalLogVO();
|
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);
|
localLogsVO.add(localLog);
|
});
|
}
|
}
|
}else {
|
File fileDir = new File(PARENTPATH);
|
File[] childDir = fileDir.listFiles();
|
if(Func.isNotEmpty(childDir) && childDir.length > 0){
|
Arrays.stream(childDir).forEach(dir->{
|
if(dir.getName().contains("ubcs_")){
|
String fullPath = dir.getPath() + LOGPATH;
|
File file = new File(fullPath);
|
if(file.exists()){
|
LocalLogVO localLogVO = new LocalLogVO();
|
localLogVO.setLastModifier(getLastModifiedOrCreatTime(true,fullPath));
|
localLogVO.setCreateTime(getLastModifiedOrCreatTime(false,fullPath));
|
localLogVO.setLogPath(fullPath);
|
String serviceId = getServiceId(file.getPath());
|
localLogVO.setServiceId(serviceId);
|
String serviceName = getServiceName(serviceId);
|
localLogVO.setServiceName(serviceName);
|
localLogVO.setLogType(serviceName+"日志父目录");
|
localLogVO.setLogName(serviceName+"日志父目录");
|
localLogVO.setHasChildren(true);
|
localLogsVO.add(localLogVO);
|
}
|
}
|
});
|
}
|
}
|
return localLogsVO;
|
}
|
|
/**
|
* 获取文件最后修改或者创建时间
|
* @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){
|
// EnumCache.getValue(EnumEnum.SERCIVE_NAME_ROLE, serViceId)
|
return ServiceNameRoleEnum.getTextByValue(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 = this.convertWindows2Linux(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;
|
}
|
|
/**
|
* 下载之前将windows的路径格式转换为linux
|
* @param fullPath
|
* @return
|
*/
|
private String convertWindows2Linux(String fullPath){
|
String os = System.getProperty("os.name").toLowerCase();
|
if (!os.contains("win")) {
|
fullPath = fullPath.replace("\\", "/");
|
}
|
return fullPath;
|
}
|
|
/**
|
* 删除日志文件
|
* @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(","))+"删除失败!");
|
}
|
|
}
|