‘liusuyi’
2024-02-01 b587ba125adcee0631bc816540779cca56f9099b
增加定时监测更新雷达连接状态
已修改8个文件
1118 ■■■■ 文件已修改
src/main/java/com/ard/alarm/radar/domain/ArdEquipRadar.java 151 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/radar/service/IArdEquipRadarService.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/radar/service/impl/ArdEquipRadarServiceImpl.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/utils/netty/tcp/ClientInitialize.java 292 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-dev.yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-prod.yml 150 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/logback-spring.xml 370 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ard/alarm/radar/domain/ArdEquipRadar.java
@@ -1,75 +1,76 @@
package com.ard.alarm.radar.domain;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
/**
 * radar对象 ard_equip_radar
 *
 * @author zj
 * @date 2023-03-11
 */
@Data
public class ArdEquipRadar
{
    private static final long serialVersionUID = 1L;
    /** id */
    private String id;
    /** 名称 */
    private String name;
    /** 端口 */
    private Integer port;
    /** 操作员id */
    private String operate;
    /** 删除标记 */
    private String delFlag;
    /** 用户id */
    private String userId;
    /** 经度 */
    private Double longitude;
    /** 维度 */
    private Double latitude;
    /** 高程 */
    private Double altitude;
    /** 安装时间 */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date radarDate;
    /** 部门id */
    private Long deptId;
    /** 俯仰角 */
    private String pitch;
    /** 塔id */
    private String towerId;
    /** 塔名称 */
    @TableField(exist = false)
    private String towerName;
    /** 图像宽度 */
    private String imageWidth;
    /** 图像高度 */
    private String imageHeight;
    /** 型号 */
    private String type;
    /** ip */
    private String ip;
}
package com.ard.alarm.radar.domain;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
/**
 * radar对象 ard_equip_radar
 *
 * @author zj
 * @date 2023-03-11
 */
@Data
public class ArdEquipRadar
{
    private static final long serialVersionUID = 1L;
    /** id */
    private String id;
    /** 名称 */
    private String name;
    /** 端口 */
    private Integer port;
    /** 操作员id */
    private String operate;
    /** 删除标记 */
    private String delFlag;
    /** 用户id */
    private String userId;
    /** 经度 */
    private Double longitude;
    /** 维度 */
    private Double latitude;
    /** 高程 */
    private Double altitude;
    /** 安装时间 */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date radarDate;
    /** 部门id */
    private Long deptId;
    /** 俯仰角 */
    private String pitch;
    /** 塔id */
    private String towerId;
    /** 塔名称 */
    @TableField(exist = false)
    private String towerName;
    /** 图像宽度 */
    private String imageWidth;
    /** 图像高度 */
    private String imageHeight;
    /** 型号 */
    private String type;
    /** ip */
    private String ip;
    /** 连接状态 */
    private String state;
}
src/main/java/com/ard/alarm/radar/service/IArdEquipRadarService.java
@@ -1,22 +1,29 @@
package com.ard.alarm.radar.service;
import java.util.List;
import com.ard.alarm.radar.domain.ArdEquipRadar;
/**
 * radarService接口
 *
 * @author zj
 * @date 2023-03-11
 */
public interface IArdEquipRadarService {
    /**
     * 查询radar列表
     *
     * @param ardEquipRadar radar
     * @return radar集合
     */
    public List<ArdEquipRadar> selectArdEquipRadarList(ArdEquipRadar ardEquipRadar);
    public ArdEquipRadar selectArdEquipRadarById(String radarId);
}
package com.ard.alarm.radar.service;
import java.util.List;
import com.ard.alarm.radar.domain.ArdEquipRadar;
/**
 * radarService接口
 *
 * @author zj
 * @date 2023-03-11
 */
public interface IArdEquipRadarService {
    /**
     * 查询radar列表
     *
     * @param ardEquipRadar radar
     * @return radar集合
     */
    public List<ArdEquipRadar> selectArdEquipRadarList(ArdEquipRadar ardEquipRadar);
    public ArdEquipRadar selectArdEquipRadarById(String radarId);
    /**
     * 更新雷达
     *
     * @param ardEquipRadar radar
     * @return radar集合
     */
    public int updateArdEquipRadar(ArdEquipRadar ardEquipRadar);
}
src/main/java/com/ard/alarm/radar/service/impl/ArdEquipRadarServiceImpl.java
@@ -1,41 +1,53 @@
package com.ard.alarm.radar.service.impl;
import java.util.List;
import com.ard.alarm.external.domain.ArdEquipExternal;
import com.ard.alarm.radar.domain.ArdEquipRadar;
import com.ard.alarm.radar.mapper.ArdEquipRadarMapper;
import com.ard.alarm.radar.service.IArdEquipRadarService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * radarService业务层处理
 *
 * @author zj
 * @date 2023-03-11
 */
@Service
public class ArdEquipRadarServiceImpl implements IArdEquipRadarService {
    @Autowired
    private ArdEquipRadarMapper ardEquipRadarMapper;
    /**
     * 查询radar列表
     *
     * @param ardEquipRadar radar
     * @return radar
     */
    @Override
    public List<ArdEquipRadar> selectArdEquipRadarList(ArdEquipRadar ardEquipRadar) {
        QueryWrapper<ArdEquipRadar> queryWrapper = new QueryWrapper<>(ardEquipRadar);
        return ardEquipRadarMapper.selectList(queryWrapper);
    }
    @Override
    public ArdEquipRadar selectArdEquipRadarById(String radarId) {
        return ardEquipRadarMapper.selectById(radarId);
    }
}
package com.ard.alarm.radar.service.impl;
import java.util.List;
import com.ard.alarm.external.domain.ArdEquipExternal;
import com.ard.alarm.radar.domain.ArdEquipRadar;
import com.ard.alarm.radar.mapper.ArdEquipRadarMapper;
import com.ard.alarm.radar.service.IArdEquipRadarService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
 * radarService业务层处理
 *
 * @author zj
 * @date 2023-03-11
 */
@Service
public class ArdEquipRadarServiceImpl implements IArdEquipRadarService {
    @Resource
    private ArdEquipRadarMapper ardEquipRadarMapper;
    /**
     * 查询radar列表
     *
     * @param ardEquipRadar radar
     * @return radar
     */
    @Override
    public List<ArdEquipRadar> selectArdEquipRadarList(ArdEquipRadar ardEquipRadar) {
        QueryWrapper<ArdEquipRadar> queryWrapper = new QueryWrapper<>(ardEquipRadar);
        return ardEquipRadarMapper.selectList(queryWrapper);
    }
    @Override
    public ArdEquipRadar selectArdEquipRadarById(String radarId) {
        return ardEquipRadarMapper.selectById(radarId);
    }
    /**
     * 更新雷达
     *
     * @param ardEquipRadar radar
     * @return radar
     */
    @Override
    public int updateArdEquipRadar(ArdEquipRadar ardEquipRadar) {
        return ardEquipRadarMapper.updateById(ardEquipRadar);
    }
}
src/main/java/com/ard/utils/netty/tcp/ClientInitialize.java
@@ -1,133 +1,159 @@
package com.ard.utils.netty.tcp;
import com.ard.alarm.radar.domain.ArdEquipRadar;
import com.ard.alarm.radar.service.IArdEquipRadarService;
import com.ard.utils.netty.config.NettyTcpConfiguration;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Consumer;
/**
 * 客户端初始化
 *
 * @author lijiamin
 */
@Component
@Slf4j(topic = "netty")
@Order(2)
public class ClientInitialize implements ApplicationRunner {
    @Resource
    NettyTcpConfiguration nettyTcpConfig;
    @Resource
    IArdEquipRadarService ardEquipRadarService;
    private Bootstrap bootstrap;
    public static CopyOnWriteArraySet<ArdEquipRadar> falseConnectSet = new CopyOnWriteArraySet();//失败连接的雷达Set
    public static ConcurrentHashMap<String, ArdEquipRadar> trueConnectMap = new ConcurrentHashMap();//成功连接的ip端口对应的雷达
    public static ConcurrentHashMap<String, MessageHandler> SucMessageHandlerMap = new ConcurrentHashMap();//成功连接的ip端口对应的报文解析器
    public static ConcurrentHashMap<String, Channel> SucChannelMap = new ConcurrentHashMap();//成功连接的ip端口对应的netty通道
    /**
     * Netty初始化配置
     */
    public void initNettyTcp() {
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        bootstrap = new Bootstrap();
        bootstrap.group(eventLoopGroup)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.TCP_NODELAY, true)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) {
                        socketChannel.pipeline().addLast(new ClientHandler());
                    }
                });
        //异步持续监听连接失败的地址
        CompletableFuture.runAsync(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        if (falseConnectSet.size() != 0) {
                            // 循环集合内元素
                            falseConnectSet.forEach(new Consumer<ArdEquipRadar>() {
                                @Override
                                public void accept(ArdEquipRadar radar) {
                                    connectServer(radar);
                                }
                            });
                        }
                        Thread.sleep(10000);
                    } catch (Exception e) {
                        log.error("Netty初始化配置监听地址出现异常");
                        e.printStackTrace();
                    }
                }
            }
        });
    }
    /**
     * 服务连接
     *
     * @param ardEquipRadar
     */
    public void connectServer(ArdEquipRadar ardEquipRadar) {
        // 获取地址及端口
        String host = ardEquipRadar.getIp();
        Integer port = ardEquipRadar.getPort();
        String ipPort = host + ":" + port;
        // 异步连接tcp服务端
        bootstrap.remoteAddress(host, port).connect().addListener((ChannelFuture futureListener) -> {
            if (futureListener.isSuccess()) {
                log.debug("雷达【" + ipPort + "】连接成功");
                // 连接成功信息从Set拔除
                falseConnectSet.remove(ardEquipRadar);
                // 连接成功信息写入map
                trueConnectMap.put(ipPort, ardEquipRadar);
                SucMessageHandlerMap.put(ipPort, new MessageHandler());
                SucChannelMap.put(ipPort, futureListener.channel());
            } else {
                log.debug("雷达【" + ipPort + "】连接失败");
                futureListener.channel().close();
                // 连接失败信息插入Set
                falseConnectSet.add(ardEquipRadar);
            }
        });
    }
    /**
     * 初始化方法
     */
    @Override
    public void run(ApplicationArguments args) {
        if (!nettyTcpConfig.getEnabled()) {
            return;
        }
        initNettyTcp();//初始化nettyTcp
        List<ArdEquipRadar> ardEquipRadars = ardEquipRadarService.selectArdEquipRadarList(new ArdEquipRadar());
        for (ArdEquipRadar ardEquipRadar : ardEquipRadars) {
            String host = ardEquipRadar.getIp();
            Integer port = Integer.valueOf(ardEquipRadar.getPort());
            log.debug("TCP client try to connect radar【" + host + ":" + port + "】");
            connectServer(ardEquipRadar);//连接每一个雷达服务
        }
    }
}
package com.ard.utils.netty.tcp;
import com.ard.alarm.radar.domain.ArdEquipRadar;
import com.ard.alarm.radar.service.IArdEquipRadarService;
import com.ard.utils.netty.config.NettyTcpConfiguration;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.function.Consumer;
/**
 * 客户端初始化
 *
 * @author lijiamin
 */
@Component
@Slf4j(topic = "netty")
@Order(2)
public class ClientInitialize implements ApplicationRunner {
    @Resource
    NettyTcpConfiguration nettyTcpConfig;
    @Resource
    IArdEquipRadarService ardEquipRadarService;
    private Bootstrap bootstrap;
    public static CopyOnWriteArraySet<ArdEquipRadar> falseConnectSet = new CopyOnWriteArraySet();//失败连接的雷达Set
    public static ConcurrentHashMap<String, ArdEquipRadar> trueConnectMap = new ConcurrentHashMap();//成功连接的ip端口对应的雷达
    public static ConcurrentHashMap<String, MessageHandler> SucMessageHandlerMap = new ConcurrentHashMap();//成功连接的ip端口对应的报文解析器
    public static ConcurrentHashMap<String, Channel> SucChannelMap = new ConcurrentHashMap();//成功连接的ip端口对应的netty通道
    /**
     * Netty初始化配置
     */
    public void initNettyTcp() {
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        bootstrap = new Bootstrap();
        bootstrap.group(eventLoopGroup)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.TCP_NODELAY, true)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) {
                        socketChannel.pipeline().addLast(new ClientHandler());
                    }
                });
        //异步持续监听连接失败的地址
        CompletableFuture.runAsync(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        if (falseConnectSet.size() != 0) {
                            // 循环集合内元素
                            falseConnectSet.forEach(new Consumer<ArdEquipRadar>() {
                                @Override
                                public void accept(ArdEquipRadar radar) {
                                    connectServer(radar);
                                }
                            });
                        }
                        Thread.sleep(10000);
                    } catch (Exception e) {
                        log.error("Netty初始化配置监听地址出现异常");
                        e.printStackTrace();
                    }
                }
            }
        });
    }
    /**
     * 服务连接
     *
     * @param ardEquipRadar
     */
    public void connectServer(ArdEquipRadar ardEquipRadar) {
        // 获取地址及端口
        String host = ardEquipRadar.getIp();
        Integer port = ardEquipRadar.getPort();
        String ipPort = host + ":" + port;
        // 异步连接tcp服务端
        bootstrap.remoteAddress(host, port).connect().addListener((ChannelFuture futureListener) -> {
            if (futureListener.isSuccess()) {
                log.debug("雷达【" + ipPort + "】连接成功");
                // 连接成功信息从Set拔除
                falseConnectSet.remove(ardEquipRadar);
                // 连接成功信息写入map
                trueConnectMap.put(ipPort, ardEquipRadar);
                SucMessageHandlerMap.put(ipPort, new MessageHandler());
                SucChannelMap.put(ipPort, futureListener.channel());
            } else {
                log.debug("雷达【" + ipPort + "】连接失败");
                futureListener.channel().close();
                // 连接失败信息插入Set
                falseConnectSet.add(ardEquipRadar);
            }
        });
    }
    /**
     * 初始化方法
     */
    @Override
    public void run(ApplicationArguments args) {
        if (!nettyTcpConfig.getEnabled()) {
            return;
        }
        initNettyTcp();//初始化nettyTcp
        List<ArdEquipRadar> ardEquipRadars = ardEquipRadarService.selectArdEquipRadarList(new ArdEquipRadar());
        for (ArdEquipRadar ardEquipRadar : ardEquipRadars) {
            String host = ardEquipRadar.getIp();
            Integer port = Integer.valueOf(ardEquipRadar.getPort());
            log.debug("TCP client try to connect radar【" + host + ":" + port + "】");
            connectServer(ardEquipRadar);//连接每一个雷达服务
        }
    }
    /**
     * 监测雷达连接状态
     */
    @Scheduled(cron = "0/5 * * * * ?")
    public void monitorConnectStatus() {
        log.debug("定时监测雷达连接状态");
        List<ArdEquipRadar> ardEquipRadars = ardEquipRadarService.selectArdEquipRadarList(new ArdEquipRadar());
        ardEquipRadars.stream().forEach(ardEquipRadar ->{
            if(trueConnectMap.contains(ardEquipRadar.getIp()+"_"+ardEquipRadar.getPort()))
            {
                if(!ardEquipRadar.getState().equals("1")) {
                    ardEquipRadar.setState("1");
                    ardEquipRadarService.updateArdEquipRadar(ardEquipRadar);
                }
            }
            else
            {
                if(!ardEquipRadar.getState().equals("0")) {
                    ardEquipRadar.setState("0");
                    ardEquipRadarService.updateArdEquipRadar(ardEquipRadar);
                }
            }
        });
    }
}
src/main/resources/application-dev.yml
@@ -66,10 +66,10 @@
logging:
  level:
    hikSdk: info
    mqtt: debug
    mqtt: info
    netty: debug
    external: info
    camera: info
    tube: info
    digitization3: info
    stealAlarm: info
    stealAlarm: info
src/main/resources/application-prod.yml
@@ -1,75 +1,77 @@
# 开发环境
server:
  port: 8088
# spring配置
spring:
  servlet:
    multipart:
      enabled: true
      max-file-size: 30MB
      max-request-size: 30MB
  datasource:
    druid:
      #开启druid监控web
      stat-view-servlet:
        enabled: true
      driver-class-name: org.postgresql.Driver
      url: jdbc:postgresql://192.168.2.15:5432/ry-vue
      username: postgres
      password: postgres
      #最大连接数
      maxActive: 30
      #最小连接数
      minIdle: 5
      #获取连接的最大等待时间
      maxWait: 10000
      #解决mysql8小时的问题
      validation-query: SELECT 'X'
      #空闲连接的检查时间间隔
      timeBetweenEvictionRunsMillis: 60000
      #空闲连接最小空闲时间
      minEvictableIdleTimeMillis: 300000
# netty配置
netty:
  udp:
    port: 40000
    enabled: true
  tcp:
    enabled: true
# mqtt配置
mqtt:
  host: tcp://192.168.2.15:1883
  clientId: client-2272
  username: admin
  password: admin
  timeout: 100
  keepalive: 60
  enabled: true
# 盗电接口地址
stealelec:
  enabled: false
  url: http://iot.zhdk.net:8090/Warning/GetWarning?userName=cy4oil
  # 三厂数字化地址
# 三场数字化
digitization3:
  enabled: false
# minio配置
minio:
  endpoint: http://192.168.2.15:9001
  accessKey: admin
  secretKey: xzx12345
# mybatis-plus配置
mybatis-plus:
  type-aliases-package: com.ard.alarm.**.domain
  mapper-locations: classpath:/mapper/*.xml
# 日志等级配置
logging:
  level:
    hikSdk: info
    mqtt: debug
    netty: info
    external: info
    camera: info
    tube: info
    digitization3: info
# 开发环境
server:
  port: 8088
# spring配置
spring:
  servlet:
    multipart:
      enabled: true
      max-file-size: 30MB
      max-request-size: 30MB
  datasource:
    druid:
      #开启druid监控web
      stat-view-servlet:
        enabled: true
      driver-class-name: org.postgresql.Driver
      url: jdbc:postgresql://192.168.1.14:5432/ry-vue?stringtype=unspecified
      username: postgres
      password: postgres
      #最大连接数
      maxActive: 30
      #最小连接数
      minIdle: 5
      #获取连接的最大等待时间
      maxWait: 10000
      #解决mysql8小时的问题
      validation-query: SELECT 'X'
      #空闲连接的检查时间间隔
      timeBetweenEvictionRunsMillis: 60000
      #空闲连接最小空闲时间
      minEvictableIdleTimeMillis: 300000
# netty配置
netty:
  udp:
    port: 40000
    enabled: true
  tcp:
    enabled: true
# minio配置
minio:
  endpoint: http://127.0.0.1:9001
  accessKey: admin
  secretKey: xzx12345
# mqtt配置
mqtt:
  host: tcp://192.168.1.14:1883
  clientId: alarm14
  username: admin
  password: xzx12345
  topic: tube
  timeout: 100
  keepalive: 60
  enabled: true
# 盗电接口地址
stealelec:
  enabled: false
  url: http://iot.zhdk.net:8090/Warning/GetWarning?userName=cy4oil
  # 三厂数字化地址
# 三场数字化
digitization3:
  enabled: false
# mybatis-plus配置
mybatis-plus:
  type-aliases-package: com.ard.alarm.**.domain
  mapper-locations: classpath:/mapper/*.xml
# 日志等级配置
logging:
  level:
    hikSdk: info
    mqtt: info
    netty: info
    external: info
    camera: info
    tube: info
    digitization3: info
    stealAlarm: info
src/main/resources/application.yml
@@ -1,3 +1,3 @@
spring:
  profiles:
    active: dev
spring:
  profiles:
    active: dev
src/main/resources/logback-spring.xml
@@ -1,185 +1,185 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--日志存放路径-->
    <property name="log.path" value="./logs"/>
    <!-- 日志输出格式 -->
    <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
    <!--控制台输出-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--系统日志输出-->
    <appender name="sys-info" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-info.log</file>
        <!--循环政策:基于时间创建日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件名格式-->
            <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--过滤的级别-->
            <level>INFO</level>
            <!--匹配时的操作:接收(记录)-->
            <onMatch>ACCEPT</onMatch>
            <!--不匹配时的操作:拒绝(不记录)-->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!--管线泄露报警日志输出-->
    <appender name="tube" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/tube.log</file>
        <!--循环政策:基于时间创建日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件名格式-->
            <fileNamePattern>${log.path}/tube.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--通用光电报警日志输出-->
    <appender name="camera" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/camera.log</file>
        <!--循环政策:基于时间创建日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件名格式-->
            <fileNamePattern>${log.path}/camera.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--外联设备报警日志输出-->
    <appender name="external" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/external.log</file>
        <!--循环政策:基于时间创建日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件名格式-->
            <fileNamePattern>${log.path}/external.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--Netty日志输出-->
    <appender name="netty" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/netty.log</file>
        <!--循环政策:基于时间创建日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件名格式-->
            <fileNamePattern>${log.path}/netty.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--mqtt日志输出-->
    <appender name="mqtt" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/mqtt.log</file>
        <!--循环政策:基于时间创建日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件名格式-->
            <fileNamePattern>${log.path}/mqtt.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--hikSdk日志输出-->
    <appender name="hikSdk" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/hikSdk.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/hikSdk.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--stealAlarm日志输出-->
    <appender name="stealAlarm" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/stealAlarm.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/stealAlarm.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--digitization3日志输出-->
    <appender name="digitization3" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/digitization3.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/digitization3.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <root level="DEBUG">
        <appender-ref ref="console"/>
    </root>
    <!--系统操作日志-->
    <root level="INFO">
        <appender-ref ref="sys-info"/>
    </root>
    <!--tube操作日志-->
    <logger name="tube" level="INFO">
        <appender-ref ref="tube"/>
    </logger>
    <!--camera操作日志-->
    <logger name="camera" level="INFO">
        <appender-ref ref="camera"/>
    </logger>
    <!--external操作日志-->
    <logger name="external" level="INFO">
        <appender-ref ref="external"/>
    </logger>
    <!--netty操作日志-->
    <logger name="netty" level="INFO">
        <appender-ref ref="netty"/>
    </logger>
    <!--mqtt操作日志-->
    <logger name="mqtt" level="DEBUG">
        <appender-ref ref="mqtt"/>
    </logger>
    <!--hikSdk操作日志-->
    <logger name="hikSdk" level="INFO">
        <appender-ref ref="hikSdk"/>
    </logger>
    <!--digitization3操作日志-->
    <logger name="digitization3" level="INFO">
        <appender-ref ref="digitization3"/>
    </logger>
    <!--stealAlarm操作日志-->
    <logger name="stealAlarm" level="INFO">
        <appender-ref ref="stealAlarm"/>
    </logger>
</configuration>
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--日志存放路径-->
    <property name="log.path" value="./logs"/>
    <!-- 日志输出格式 -->
    <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
    <!--控制台输出-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--系统日志输出-->
    <appender name="sys-info" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-info.log</file>
        <!--循环政策:基于时间创建日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件名格式-->
            <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!--过滤的级别-->
            <level>INFO</level>
            <!--匹配时的操作:接收(记录)-->
            <onMatch>ACCEPT</onMatch>
            <!--不匹配时的操作:拒绝(不记录)-->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!--管线泄露报警日志输出-->
    <appender name="tube" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/tube.log</file>
        <!--循环政策:基于时间创建日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件名格式-->
            <fileNamePattern>${log.path}/tube.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--通用光电报警日志输出-->
    <appender name="camera" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/camera.log</file>
        <!--循环政策:基于时间创建日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件名格式-->
            <fileNamePattern>${log.path}/camera.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--外联设备报警日志输出-->
    <appender name="external" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/external.log</file>
        <!--循环政策:基于时间创建日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件名格式-->
            <fileNamePattern>${log.path}/external.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--Netty日志输出-->
    <appender name="netty" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/netty.log</file>
        <!--循环政策:基于时间创建日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件名格式-->
            <fileNamePattern>${log.path}/netty.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--mqtt日志输出-->
    <appender name="mqtt" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/mqtt.log</file>
        <!--循环政策:基于时间创建日志文件-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件名格式-->
            <fileNamePattern>${log.path}/mqtt.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--hikSdk日志输出-->
    <appender name="hikSdk" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/hikSdk.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/hikSdk.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--stealAlarm日志输出-->
    <appender name="stealAlarm" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/stealAlarm.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/stealAlarm.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!--digitization3日志输出-->
    <appender name="digitization3" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/digitization3.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--按天回滚daily-->
            <fileNamePattern>${log.path}/digitization3.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!--日志最大的历史60天-->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <root level="DEBUG">
        <appender-ref ref="console"/>
    </root>
    <!--系统操作日志-->
    <root level="INFO">
        <appender-ref ref="sys-info"/>
    </root>
    <!--tube操作日志-->
    <logger name="tube" level="INFO">
        <appender-ref ref="tube"/>
    </logger>
    <!--camera操作日志-->
    <logger name="camera" level="INFO">
        <appender-ref ref="camera"/>
    </logger>
    <!--external操作日志-->
    <logger name="external" level="INFO">
        <appender-ref ref="external"/>
    </logger>
    <!--netty操作日志-->
    <logger name="netty" level="INFO">
        <appender-ref ref="netty"/>
    </logger>
    <!--mqtt操作日志-->
    <logger name="mqtt" level="DEBUG">
        <appender-ref ref="mqtt"/>
    </logger>
    <!--hikSdk操作日志-->
    <logger name="hikSdk" level="INFO">
        <appender-ref ref="hikSdk"/>
    </logger>
    <!--digitization3操作日志-->
    <logger name="digitization3" level="INFO">
        <appender-ref ref="digitization3"/>
    </logger>
    <!--stealAlarm操作日志-->
    <logger name="stealAlarm" level="INFO">
        <appender-ref ref="stealAlarm"/>
    </logger>
</configuration>