Bläddra i källkod

upload添加日志及springboot启动

xusl 1 år sedan
förälder
incheckning
f40515a819

+ 0 - 52
ipfcst-upload/pom.xml

@@ -53,12 +53,10 @@
     </dependencyManagement>
 
     <dependencies>
-
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-actuator</artifactId>
         </dependency>
-
         <!--配置文件处理器-->
         <dependency>
             <groupId>org.springframework.boot</groupId>
@@ -88,28 +86,6 @@
             <artifactId>hutool-all</artifactId>
             <version>5.3.5</version>
         </dependency>
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-mock</artifactId>
-            <version>2.0.8</version>
-        </dependency>
-        <dependency>
-            <groupId>com.jiayue.ipfcst</groupId>
-            <artifactId>ipfcst-common-data</artifactId>
-            <version>3.0.0</version>
-        </dependency>
-
-        <dependency>
-            <groupId>com.jiayue.ipfcst</groupId>
-            <artifactId>ipfcst-common-security</artifactId>
-            <version>3.0.0</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-dbcp2</artifactId>
-            <version>${commons-dbcp2.version}</version>
-        </dependency>
         <!-- https://mvnrepository.com/artifact/com.googlecode.aviator/aviator -->
         <dependency>
             <groupId>com.googlecode.aviator</groupId>
@@ -139,15 +115,6 @@
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
         </dependency>
-
-        <dependency>
-            <groupId>net.sf.ehcache</groupId>
-            <artifactId>ehcache</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-web</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-websocket</artifactId>
@@ -201,25 +168,6 @@
             <scope>compile</scope>
             <optional>true</optional>
         </dependency>
-
-        <dependency>
-            <groupId>org.apache.commons</groupId>
-            <artifactId>commons-compress</artifactId>
-            <version>1.5</version>
-        </dependency>
-
-        <dependency>
-            <groupId>com.syjy</groupId>
-            <artifactId>calculation-spring-boot-starter</artifactId>
-            <version>0.0.28</version>
-
-            <exclusions>
-                <exclusion>
-                    <groupId>com.alibaba.cloud</groupId>
-                    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
     </dependencies>
 
     <profiles>    <!--考虑到window 和linux环境 npm命令格式的问题,使用maven的profile实现动态指定命令-->

+ 0 - 3
ipfcst-upload/src/main/java/com/jiayue/ipfcst/upload/UploadApplication.java

@@ -31,9 +31,6 @@ import java.util.TimeZone;
 public class UploadApplication {
 
     private final Environment environment;
-    @Qualifier("dataSource")
-    @Autowired
-    private DataSource dataSource;
 
     @Autowired
     public UploadApplication(Environment environment) {

+ 116 - 0
ipfcst-upload/src/main/java/com/jiayue/ipfcst/upload/config/AppenderFactory.java

@@ -0,0 +1,116 @@
+package com.jiayue.ipfcst.upload.config;
+
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
+import ch.qos.logback.classic.filter.ThresholdFilter;
+import ch.qos.logback.core.rolling.RollingFileAppender;
+import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy;
+import ch.qos.logback.core.util.FileSize;
+import ch.qos.logback.core.util.OptionHelper;
+import com.jiayue.ipfcst.upload.constants.CacheConstant;
+import com.jiayue.ipfcst.upload.util.FileUtil;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * 创建动态日志
+ *
+ * @author xsl
+ * @version 3.0
+ */
+@Component
+public class AppenderFactory {
+  @Value("${fileupload.log.level}")
+  private String logLevel;
+  @Value("${fileupload.log.totalSizeCap}")
+  private String totalSizeCap;
+  @Value("${fileupload.log.maxFileSize}")
+  private String maxFileSize;
+  @Value("${fileupload.log.maxHistory}")
+  private String maxHistory;
+
+  public Logger getLogger(String name, String type, String no) {
+    Logger logger = CacheConstant.uploadLogMap.get(no);
+    if (logger != null) {
+      return logger;
+    } else {
+      if (logger != null) {
+        return logger;
+      }
+      logger = getAppender(name, type, no);
+      CacheConstant.uploadLogMap.put(no, logger);
+    }
+    return logger;
+  }
+
+  /**
+   * 通过传入的名字和级别,动态设置appender
+   *
+   * @param name
+   * @return
+   */
+  public Logger getAppender(String name, String type, String no) {
+//    Level level = Level.toLevel(this.logLevel);
+//    DateFormat format = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.SIMPLIFIED_CHINESE);
+    LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
+    //这里是可以用来设置appender的,在xml配置文件里面,是这种形式:
+    // <appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+    RollingFileAppender appender = new RollingFileAppender();
+    //这里设置级别过滤器
+    ThresholdFilter levelFilter = createLevelFilter(this.logLevel);
+    levelFilter.start();
+    appender.addFilter(levelFilter);
+    // 但可以使用<contextName>设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。
+    appender.setContext(context);
+    //appender的name属性
+    appender.setName("upload-" + type + "-" + name + "-" + no);
+    //设置文件名
+//        appender.setFile(OptionHelper.substVars("d:/eppLog/"+ name+"/" + "fileUploadLogFile-" +name+"-"+ type+".%d{yyyy-MM-dd}.%i.log",context));
+    appender.setAppend(true);
+    appender.setPrudent(false);
+    //设置文件创建时间及大小的类
+    SizeAndTimeBasedRollingPolicy policy = new SizeAndTimeBasedRollingPolicy();
+    //文件名格式
+    String fp = OptionHelper.substVars(FileUtil.getLogsPath() + "/" + "%d{yyyy-MM-dd}" + "/" + "upload-" + type + "-" + name + "-" + no + ".%d{yyyy-MM-dd}.%i.log", context);
+    //最大日志文件大小
+    policy.setMaxFileSize(FileSize.valueOf(this.maxFileSize));
+    //设置文件名模式
+    policy.setFileNamePattern(fp);
+    //设置日志文件保留天数
+    policy.setMaxHistory(Integer.parseInt(this.maxHistory));
+    //总大小限制
+    policy.setTotalSizeCap(FileSize.valueOf(this.totalSizeCap));
+    //设置父节点是appender
+    policy.setParent(appender);
+    // 但可以使用<contextName>设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。
+    policy.setContext(context);
+    policy.setCleanHistoryOnStart(true);
+    policy.start();
+    PatternLayoutEncoder encoder = new PatternLayoutEncoder();
+    //设置上下文,每个logger都关联到logger上下文,默认上下文名称为default。
+    // 但可以使用<contextName>设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。
+    encoder.setContext(context);
+    //设置格式
+//    encoder.setPattern("%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n");
+    encoder.setPattern("%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level - %msg%n");
+    encoder.start();
+    //加入下面两个节点
+    appender.setRollingPolicy(policy);
+    appender.setEncoder(encoder);
+    appender.start();
+    Logger logger = context.getLogger("upload-" + type + "-" + name + "-" + no);
+    //设置不向上级打印信息
+    logger.setAdditive(false);
+    logger.addAppender(appender);
+    return logger;
+  }
+
+  private ThresholdFilter createLevelFilter(String level) {
+    ThresholdFilter levelFilter = new ThresholdFilter();
+    levelFilter.setLevel(level);
+    levelFilter.start();
+    return levelFilter;
+  }
+}

+ 19 - 0
ipfcst-upload/src/main/java/com/jiayue/ipfcst/upload/constants/CacheConstant.java

@@ -0,0 +1,19 @@
+package com.jiayue.ipfcst.upload.constants;
+
+import ch.qos.logback.classic.Logger;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * 上报文件公用变量
+ *
+ * @author xsl
+ * @version 3.0
+ */
+@Slf4j
+public class CacheConstant {
+    public static ConcurrentMap<String, Logger> uploadLogMap = new ConcurrentHashMap<>();
+
+}

+ 349 - 0
ipfcst-upload/src/main/java/com/jiayue/ipfcst/upload/util/FileUtil.java

@@ -0,0 +1,349 @@
+package com.jiayue.ipfcst.upload.util;
+
+import cn.hutool.core.util.CharsetUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.springframework.util.ResourceUtils;
+
+import java.io.*;
+import java.net.URLDecoder;
+import java.nio.charset.Charset;
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributeView;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.PosixFileAttributeView;
+import java.nio.file.attribute.PosixFileAttributes;
+import java.security.MessageDigest;
+import java.util.Date;
+
+/**
+ * 文件工具类
+ *
+ * @author xsl
+ * @version 3.0
+ */
+@Slf4j
+public class FileUtil {
+  /**
+   * 移动本地文件
+   *
+   * @param remoteAbsoluteFile 远程文件名(包括完整路径)
+   * @param localAbsoluteFile  本地文件名(包括完整路径)
+   * @return 成功时,返回true,失败返回false
+   * @throws Exception
+   */
+  public static void move(String localAbsoluteFile, String remoteAbsoluteFile) throws Exception {
+//    File srcFile = new File(localAbsoluteFile);
+//    File destDir = new File(remoteAbsoluteFile);
+//    try {
+//      if (!destDir.exists()) {// 如果目录不存在则创建目录
+//        boolean b = destDir.mkdirs();
+//        if (!b) // 如果创建失败则抛出异常
+//          throw new RuntimeException(destDir + " 目录创建失败");
+//      }
+//      FileUtils.moveFile(srcFile, new File(remoteAbsoluteFile + File.separator + srcFile.getName()));
+//    } catch (IOException e) {
+//      throw new Exception("文件:" + srcFile.getName() + "移动到" + destDir.getPath() + "失败。", e);
+//    }
+    move(localAbsoluteFile, remoteAbsoluteFile, true);
+  }
+
+  public static void move(String localAbsoluteFile, String remoteAbsoluteFile, boolean overwrite) throws Exception {
+    File srcFile = new File(localAbsoluteFile);
+    File destDir = new File(remoteAbsoluteFile);
+    StringBuilder opts = new StringBuilder();
+    try {
+      if (!destDir.exists()) {// 如果目录不存在则创建目录
+        boolean b = destDir.mkdirs();
+        if (!b){ // 如果创建失败则抛出异常
+          throw new RuntimeException(destDir + " 目录创建失败");
+        }
+      }
+      File desFile = new File(remoteAbsoluteFile + File.separator + srcFile.getName());
+      if (overwrite && desFile.exists()) {
+        FileUtils.deleteQuietly(desFile);
+        opts.append(" >> 覆盖 >> ");
+      } else {
+        opts.append(" >> 移动 >> ");
+      }
+      FileUtils.moveFile(srcFile, desFile);
+      log.info("文件:" + srcFile.getName() + opts + destDir.getPath());
+    } catch (IOException e) {
+      throw new Exception("文件:" + srcFile.getName() + opts + destDir.getPath() + "失败。", e);
+    }
+  }
+
+  public static InputStream toInputStream(File file, Charset source, Charset target) {
+    InputStream inputStream = null;
+    try {
+      if (file.exists() && file.canRead()) {
+        String context = FileUtils.readFileToString(file, source);
+        inputStream = null == context ? null : IOUtils.toInputStream(context, target);
+      }
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+    return inputStream;
+  }
+
+  public static File convert(File file, Charset source, Charset target) {
+    if (file.exists() && file.canRead() && file.canWrite()) {
+      return CharsetUtil.convert(file, source, target);
+    }
+    return null;
+  }
+
+  //文件内容md5加密
+  public static String getMD5(byte[] fileByte) {
+    String md5 = new String();
+    try {
+      MessageDigest md = MessageDigest.getInstance("MD5");
+      md.update(fileByte);
+      byte b[] = md.digest();
+
+      int i;
+
+      StringBuffer buf = new StringBuffer("");
+      for (int offset = 0; offset < b.length; offset++) {
+        i = b[offset];
+        if (i < 0) {
+          i += 256;
+        }
+        if (i < 16) {
+          buf.append("0");
+        }
+        buf.append(Integer.toHexString(i));
+      }
+
+      md5 = buf.toString();
+
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+    return md5;
+  }
+
+  /**
+   * 获取文件创建时间
+   *
+   * @param fullFileName
+   * @return
+   */
+  public static Long getFileCreateTime(String fullFileName) {
+    Path path = Paths.get(fullFileName);
+    BasicFileAttributeView basicview = Files.getFileAttributeView(path, BasicFileAttributeView.class, LinkOption.NOFOLLOW_LINKS);
+    BasicFileAttributes attr;
+    try {
+      attr = basicview.readAttributes();
+      Date createDate = new Date(attr.creationTime().toMillis());
+      return createDate.getTime();
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+    return System.currentTimeMillis();
+  }
+
+  /**
+   * 获取项目根路径
+   *
+   * @return
+   */
+  public static String getResourceBasePath() {
+    // 获取跟目录
+    File path = null;
+    try {
+      path = new File(ResourceUtils.getURL("classpath:").getPath());
+
+    } catch (FileNotFoundException e) {
+      // nothing to do
+    }
+    if (path == null || !path.exists()) {
+      path = new File("");
+    }
+
+    String pathStr = path.getAbsolutePath();
+    try {
+      pathStr = URLDecoder.decode(pathStr, "UTF-8");
+    } catch (UnsupportedEncodingException e) {
+      e.printStackTrace();
+    }
+    // 如果是在eclipse中运行,则和target同级目录,如果是jar部署到服务器,则默认和jar包同级
+//    pathStr = pathStr.replace("\\target\\classes", "");
+
+    return pathStr;
+  }
+
+  /**
+   * 获取上报文件目录相对路径
+   *
+   * @return
+   */
+  public static String getFileUploadPath() {
+    return createUploadAllDir("uploadFile");
+  }
+
+  /**
+   * 获取下载文件目录相对路径
+   *
+   * @return
+   */
+  public static String getDownloadFilePath() {
+    return createUploadAllDir("downloadFile");
+  }
+
+  /**
+   * 获取下载文件目录相对路径
+   *
+   * @return
+   */
+  public static String getZxglFilePath() {
+    return createUploadAllDir("zxgl");
+  }
+
+  /**
+   * 获取日志目录相对路径
+   *
+   * @return
+   */
+  public static String getLogsPath() {
+    return createUploadAllDir("logs");
+  }
+
+  /**
+   * 获取系统脚本相对路径
+   *
+   * @return
+   */
+  public static String getBinPath() {
+    return createUploadAllDir("bin");
+  }
+
+  /**
+   * 程序备份相对路径
+   *
+   * @return
+   */
+  public static String getOriginalPath() {
+    return createUploadAllDir("original");
+  }
+
+  /**
+   * 系统资料相对路径
+   *
+   * @return
+   */
+  public static String getSystemFilePath() {
+    return createUploadAllDir("systemFile");
+  }
+
+  /**
+   * 获取被删除文件目录
+   *
+   * @return 路径
+   */
+  public static String getDeleteFilePath() {
+    return createUploadAllDir("deleteFile");
+  }
+
+  /**
+   * 程序运行相对路径
+   *
+   * @return
+   */
+  public static String getProducePath() {
+    return createUploadAllDir("produce");
+  }
+
+  /**
+   * 报表相对路径
+   *
+   * @return
+   */
+  public static String getreportFormPath() {
+    return createUploadAllDir("reportForm");
+  }
+
+  /**
+   * 获取临时文件目录相对路径
+   *
+   * @return
+   */
+  public static String getTempFilePath() {
+    return createUploadAllDir("tempFile");
+  }
+
+  public static String getE46Path() {
+    return createUploadAllDir("HN");
+  }
+
+  private static String createUploadAllDir(String dir) {
+    String path = "";
+    if (System.getProperties().getProperty("file.separator").equals("\\")) {
+      path = new File(getResourceBasePath()).getParentFile().getParentFile().getParentFile().getAbsolutePath() + File.separator + dir;
+      try {
+        path = URLDecoder.decode(path, "UTF-8");
+      } catch (UnsupportedEncodingException e) {
+        e.printStackTrace();
+      }
+      File file = new File(path);
+      if (!file.exists()) {
+        boolean b = file.mkdirs();
+        if (!b) {
+          log.error("目录创建失败" + path);
+        }
+      }
+    } else {
+      path = "/home/syjy/ipfcstV3/" + dir;
+    }
+    return path;
+  }
+
+  /**
+   * 获取环境数据导出文件目录相对路径
+   *
+   * @return
+   */
+  public static String getEnvironmentalDataFile() {
+    return createUploadAllDir("environmentalDataFile");
+  }
+
+
+  /**
+   * 设置用户和用户组
+   *
+   * @param filePath 文件路径
+   * @param owner    用户
+   * @param group    用户组
+   */
+  public static void setFileOwnerAndGroup(String filePath, String owner, String group) {
+    Path path = FileSystems.getDefault().getPath(filePath);
+
+    try {
+      // 创建文件(如果不存在)
+      if (!Files.exists(path)) {
+        Files.createFile(path);
+      }
+
+      // 获取文件属性视图
+      PosixFileAttributeView attributeView = Files.getFileAttributeView(
+        path, PosixFileAttributeView.class);
+
+      // 获取当前的文件属性
+      PosixFileAttributes attributes = attributeView.readAttributes();
+
+      // 设置文件所有者和用户组
+      attributeView.setOwner(FileSystems.getDefault().getUserPrincipalLookupService().lookupPrincipalByName(owner));
+      attributeView.setGroup(FileSystems.getDefault().getUserPrincipalLookupService().lookupPrincipalByGroupName(group));
+
+      log.info("{}文件所有者设置为: {},用户组设置为:{}" + filePath, attributeView.getOwner(), attributes.group());
+
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  // 可以在这里添加其他实用方法
+
+
+}

+ 11 - 0
ipfcst-upload/src/main/resources/application.yml

@@ -0,0 +1,11 @@
+server:
+  port: 9002
+
+logging:
+  config: classpath:logback-upload.xml
+
+mengxi:
+  uploadpath:
+    E1: /WIND_DQ/
+    E2: /WIND_CDQ/
+    E377: /WIND_ZQ/

+ 82 - 0
ipfcst-upload/src/main/resources/logback-upload.xml

@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<configuration scan="false" scanPeriod="60 seconds" debug="false"><!-- 这个是根配置文件,一定要有的
+                            scan:
+                                是当配置文件被修改后会被重新加载
+                            scanPeriod:
+                                设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,
+                                默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
+                            debug:
+                                当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。
+                                默认值为false。
+                             -->
+  <!-- 日志存放路径
+      下面的标签可以自己定义
+      name:相当于Map的key
+      value:就是map的value
+      ${catalina.base}是tomcat的当前路径
+      /logs:就是tomcat下的日志路径,
+      /ehrlog:如果没有目录会默认创建
+  -->
+  <property name="logbase" value="./logs/"/>
+  <!-- 时间戳:这个时间戳可以作为每日日志的名称 -->
+  <timestamp key="bySecond" datePattern="yyyy-MM-dd"/>
+  <!-- appender:
+      name相当于一个名称
+      class:确定要加载哪个类
+      encoder:一定要加 encoder ,
+      默认配置为PatternLayoutEncoder
+      patter:必填
+      ConsoleAppender:也明白是什么意思,就是输出在控制台上-->
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+      <charset>UTF-8</charset>
+    </encoder>
+  </appender>
+  <!-- 把日志存储
+      encoding:日志的编码
+      file:指定当前生成的日志文件名称
+      rollingPolicy:滚动策略
+      FileNamePattern:移动文件最后的名称,跟file标签结合使用,
+      比如file里面的内容是  1.txt
+      那么,FileNamePattern里面写的是2.txt,那么最后文件名就为2.txt
+      如果最后结尾是gz或者zip,那么,就会自动打成压缩包
+      -->
+  <appender name="logFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
+    <!-- 编码 -->
+    <!--<Encoding>UTF-8</Encoding>-->
+    <!-- 按照时间来 -->
+    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+      <!--日志文件输出的文件名-->
+      <FileNamePattern>${logbase}/%d{yyyy-MM-dd}/ipfcst-upload.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
+      <!--日志文件保留天数-->
+      <MaxHistory>180</MaxHistory>
+      <maxFileSize>10MB</maxFileSize>
+      <totalSizeCap>1024MB</totalSizeCap>
+      <cleanHistoryOnStart>true</cleanHistoryOnStart>
+    </rollingPolicy>
+    <!-- 布局 -->
+    <encoder>
+      <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
+      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+      <charset>UTF-8</charset>
+    </encoder>
+    <append>false</append>
+  </appender>
+
+  <logger name="com.jiayue" level="info" additivity="true">
+    <appender-ref ref="logFile"/>
+  </logger>
+  <logger name="com.alibaba.druid.filter.stat.StatFilter" level="info" additivity="true">
+    <appender-ref ref="logFile"/>
+  </logger>
+
+  <logger name="org" level="info" additivity="true">
+    <appender-ref ref="logFile"/>
+  </logger>
+
+  <root level="info">
+    <appender-ref ref="STDOUT"/>
+  </root>
+</configuration>

+ 84 - 0
velocity.log

@@ -127,3 +127,87 @@
 2024-01-25 11:42:33,676 - Null reference [template 'start-console.vm', line 25, column 19] : $app_path cannot be resolved.
 2024-01-25 11:42:33,676 - Null reference [template 'start-console.vm', line 25, column 49] : $start_app_log cannot be resolved.
 2024-01-25 11:42:33,676 - Null reference [template 'start-console.vm', line 28, column 44] : $app_path cannot be resolved.
+2024-03-20 13:29:12,647 - Log4JLogChute initialized using file 'velocity.log'
+2024-03-20 13:29:12,648 - Initializing Velocity, Calling init()...
+2024-03-20 13:29:12,648 - Starting Apache Velocity v1.7 (compiled: 2010-11-19 12:14:37)
+2024-03-20 13:29:12,648 - Default Properties File: org\apache\velocity\runtime\defaults\velocity.properties
+2024-03-20 13:29:12,648 - Trying to use logger class org.apache.velocity.runtime.log.AvalonLogChute
+2024-03-20 13:29:12,648 - Target log system for org.apache.velocity.runtime.log.AvalonLogChute is not available (java.lang.NoClassDefFoundError: org/apache/log/format/Formatter).  Falling back to next log system...
+2024-03-20 13:29:12,648 - Trying to use logger class org.apache.velocity.runtime.log.Log4JLogChute
+2024-03-20 13:29:12,648 - Using logger class org.apache.velocity.runtime.log.Log4JLogChute
+2024-03-20 13:29:12,658 - ResourceLoader instantiated: org.apache.velocity.runtime.resource.loader.FileResourceLoader
+2024-03-20 13:29:12,659 - Do unicode file recognition:  false
+2024-03-20 13:29:12,660 - FileResourceLoader : adding path ''
+2024-03-20 13:29:12,692 - ResourceCache: initialized (class org.apache.velocity.runtime.resource.ResourceCacheImpl) with class java.util.Collections$SynchronizedMap cache map.
+2024-03-20 13:29:12,701 - Loaded System Directive: org.apache.velocity.runtime.directive.Stop
+2024-03-20 13:29:12,704 - Loaded System Directive: org.apache.velocity.runtime.directive.Define
+2024-03-20 13:29:12,705 - Loaded System Directive: org.apache.velocity.runtime.directive.Break
+2024-03-20 13:29:12,706 - Loaded System Directive: org.apache.velocity.runtime.directive.Evaluate
+2024-03-20 13:29:12,707 - Loaded System Directive: org.apache.velocity.runtime.directive.Literal
+2024-03-20 13:29:12,709 - Loaded System Directive: org.apache.velocity.runtime.directive.Macro
+2024-03-20 13:29:12,712 - Loaded System Directive: org.apache.velocity.runtime.directive.Parse
+2024-03-20 13:29:12,714 - Loaded System Directive: org.apache.velocity.runtime.directive.Include
+2024-03-20 13:29:12,716 - Loaded System Directive: org.apache.velocity.runtime.directive.Foreach
+2024-03-20 13:29:12,769 - Created '20' parsers.
+2024-03-20 13:29:12,777 - Velocimacro : "velocimacro.library" is not set.  Trying default library: VM_global_library.vm
+2024-03-20 13:29:12,777 - Velocimacro : Default library not found.
+2024-03-20 13:29:12,777 - Velocimacro : allowInline = true : VMs can be defined inline in templates
+2024-03-20 13:29:12,777 - Velocimacro : allowInlineToOverride = false : VMs defined inline may NOT replace previous VM definitions
+2024-03-20 13:29:12,777 - Velocimacro : allowInlineLocal = false : VMs defined inline will be global in scope if allowed.
+2024-03-20 13:29:12,777 - Velocimacro : autoload off : VM system will not automatically reload global library macros
+2024-03-20 13:32:33,831 - Log4JLogChute initialized using file 'velocity.log'
+2024-03-20 13:32:33,831 - Initializing Velocity, Calling init()...
+2024-03-20 13:32:33,831 - Starting Apache Velocity v1.7 (compiled: 2010-11-19 12:14:37)
+2024-03-20 13:32:33,832 - Default Properties File: org\apache\velocity\runtime\defaults\velocity.properties
+2024-03-20 13:32:33,832 - Trying to use logger class org.apache.velocity.runtime.log.AvalonLogChute
+2024-03-20 13:32:33,832 - Target log system for org.apache.velocity.runtime.log.AvalonLogChute is not available (java.lang.NoClassDefFoundError: org/apache/log/format/Formatter).  Falling back to next log system...
+2024-03-20 13:32:33,832 - Trying to use logger class org.apache.velocity.runtime.log.Log4JLogChute
+2024-03-20 13:32:33,832 - Using logger class org.apache.velocity.runtime.log.Log4JLogChute
+2024-03-20 13:32:33,839 - ResourceLoader instantiated: org.apache.velocity.runtime.resource.loader.FileResourceLoader
+2024-03-20 13:32:33,840 - Do unicode file recognition:  false
+2024-03-20 13:32:33,840 - FileResourceLoader : adding path ''
+2024-03-20 13:32:33,859 - ResourceCache: initialized (class org.apache.velocity.runtime.resource.ResourceCacheImpl) with class java.util.Collections$SynchronizedMap cache map.
+2024-03-20 13:32:33,861 - Loaded System Directive: org.apache.velocity.runtime.directive.Stop
+2024-03-20 13:32:33,862 - Loaded System Directive: org.apache.velocity.runtime.directive.Define
+2024-03-20 13:32:33,863 - Loaded System Directive: org.apache.velocity.runtime.directive.Break
+2024-03-20 13:32:33,864 - Loaded System Directive: org.apache.velocity.runtime.directive.Evaluate
+2024-03-20 13:32:33,865 - Loaded System Directive: org.apache.velocity.runtime.directive.Literal
+2024-03-20 13:32:33,867 - Loaded System Directive: org.apache.velocity.runtime.directive.Macro
+2024-03-20 13:32:33,869 - Loaded System Directive: org.apache.velocity.runtime.directive.Parse
+2024-03-20 13:32:33,871 - Loaded System Directive: org.apache.velocity.runtime.directive.Include
+2024-03-20 13:32:33,873 - Loaded System Directive: org.apache.velocity.runtime.directive.Foreach
+2024-03-20 13:32:33,911 - Created '20' parsers.
+2024-03-20 13:32:33,919 - Velocimacro : "velocimacro.library" is not set.  Trying default library: VM_global_library.vm
+2024-03-20 13:32:33,919 - Velocimacro : Default library not found.
+2024-03-20 13:32:33,919 - Velocimacro : allowInline = true : VMs can be defined inline in templates
+2024-03-20 13:32:33,919 - Velocimacro : allowInlineToOverride = false : VMs defined inline may NOT replace previous VM definitions
+2024-03-20 13:32:33,919 - Velocimacro : allowInlineLocal = false : VMs defined inline will be global in scope if allowed.
+2024-03-20 13:32:33,919 - Velocimacro : autoload off : VM system will not automatically reload global library macros
+2024-03-20 13:42:38,535 - Log4JLogChute initialized using file 'velocity.log'
+2024-03-20 13:42:38,536 - Initializing Velocity, Calling init()...
+2024-03-20 13:42:38,536 - Starting Apache Velocity v1.7 (compiled: 2010-11-19 12:14:37)
+2024-03-20 13:42:38,536 - Default Properties File: org\apache\velocity\runtime\defaults\velocity.properties
+2024-03-20 13:42:38,537 - Trying to use logger class org.apache.velocity.runtime.log.AvalonLogChute
+2024-03-20 13:42:38,537 - Target log system for org.apache.velocity.runtime.log.AvalonLogChute is not available (java.lang.NoClassDefFoundError: org/apache/log/Priority).  Falling back to next log system...
+2024-03-20 13:42:38,537 - Trying to use logger class org.apache.velocity.runtime.log.Log4JLogChute
+2024-03-20 13:42:38,537 - Using logger class org.apache.velocity.runtime.log.Log4JLogChute
+2024-03-20 13:42:38,541 - ResourceLoader instantiated: org.apache.velocity.runtime.resource.loader.FileResourceLoader
+2024-03-20 13:42:38,543 - Do unicode file recognition:  false
+2024-03-20 13:42:38,543 - FileResourceLoader : adding path ''
+2024-03-20 13:42:38,554 - ResourceCache: initialized (class org.apache.velocity.runtime.resource.ResourceCacheImpl) with class java.util.Collections$SynchronizedMap cache map.
+2024-03-20 13:42:38,558 - Loaded System Directive: org.apache.velocity.runtime.directive.Stop
+2024-03-20 13:42:38,559 - Loaded System Directive: org.apache.velocity.runtime.directive.Define
+2024-03-20 13:42:38,560 - Loaded System Directive: org.apache.velocity.runtime.directive.Break
+2024-03-20 13:42:38,561 - Loaded System Directive: org.apache.velocity.runtime.directive.Evaluate
+2024-03-20 13:42:38,561 - Loaded System Directive: org.apache.velocity.runtime.directive.Literal
+2024-03-20 13:42:38,562 - Loaded System Directive: org.apache.velocity.runtime.directive.Macro
+2024-03-20 13:42:38,564 - Loaded System Directive: org.apache.velocity.runtime.directive.Parse
+2024-03-20 13:42:38,564 - Loaded System Directive: org.apache.velocity.runtime.directive.Include
+2024-03-20 13:42:38,565 - Loaded System Directive: org.apache.velocity.runtime.directive.Foreach
+2024-03-20 13:42:38,580 - Created '20' parsers.
+2024-03-20 13:42:38,582 - Velocimacro : "velocimacro.library" is not set.  Trying default library: VM_global_library.vm
+2024-03-20 13:42:38,582 - Velocimacro : Default library not found.
+2024-03-20 13:42:38,582 - Velocimacro : allowInline = true : VMs can be defined inline in templates
+2024-03-20 13:42:38,582 - Velocimacro : allowInlineToOverride = false : VMs defined inline may NOT replace previous VM definitions
+2024-03-20 13:42:38,582 - Velocimacro : allowInlineLocal = false : VMs defined inline will be global in scope if allowed.
+2024-03-20 13:42:38,582 - Velocimacro : autoload off : VM system will not automatically reload global library macros