fix: 码全代码添加

This commit is contained in:
2024-10-11 15:56:51 +08:00
parent 9a853f40c2
commit 7776e95902
907 changed files with 81296 additions and 324 deletions

41
template/cvbp/cvbp-monitor/.gitignore vendored Normal file
View File

@@ -0,0 +1,41 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
logs/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store
script/

View File

@@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2023 codvision.com All Rights Reserved.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.codvision</groupId>
<artifactId>cvbp</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cvbp-monitor</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<description>基础平台-系统监控中心</description>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.codvision</groupId>
<artifactId>cvbp-web-core</artifactId>
</dependency>
<dependency>
<groupId>com.codvision</groupId>
<artifactId>cvbp-auth-core</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-system</artifactId>
</dependency>
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
</dependency>
<dependency>
<groupId>com.codvision</groupId>
<artifactId>cvbp-log-core</artifactId>
</dependency>
</dependencies>
<profiles>
<profile>
<id>dev</id>
<properties>
<profiles.active>dev</profiles.active>
</properties>
<activation>
<!-- 默认环境 -->
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>prd</id>
<properties>
<profiles.active>prd</profiles.active>
</properties>
</profile>
</profiles>
<build>
<finalName>
${project.artifactId}-${project.version}
</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>exec</classifier>
<executable>true</executable>
</configuration>
</plugin>
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<executions>
<execution>
<id>get-the-git-infos</id>
<goals>
<goal>revision</goal>
</goals>
</execution>
</executions>
<configuration>
<dotGitDirectory>${project.basedir}/.git</dotGitDirectory>
<prefix>git</prefix>
<verbose>true</verbose>
<!-- 是否离线解决Authentication is required but no CredentialsProvider has been registered问题 -->
<offline>true</offline>
<dateFormat>yyyy-MM-dd HH:mm:ss</dateFormat>
<!-- 是否生 git.properties 属性文件 -->
<generateGitPropertiesFile>true</generateGitPropertiesFile>
<!-- 生成版本信息文件名 -->
<generateGitPropertiesFilename>${project.build.outputDirectory}/git.json</generateGitPropertiesFilename>
<format>json</format>
<!-- git描述配置,可选;由JGit提供实现 -->
<gitDescribe>
<!-- 是否生成描述属性 -->
<skip>false</skip>
<!-- 提交操作未发现tag时,仅打印提交操作ID -->
<always>false</always>
<!-- 提交操作ID显式字符长度,最大值为:40;默认值:7; 0代表特殊意义;后面有解释; -->
<abbrev>7</abbrev>
<!-- 构建触发时,代码有修改时(即"dirty state"),添加指定后缀;默认值:""; -->
<dirty>-dirty</dirty>
</gitDescribe>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,22 @@
/*
* Copyright (c) 2023 codvision.com All Rights Reserved.
*/
package com.codvision.monitor;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 监控中心启动入口
*
* @author lingee
* @date 2023/11/20
*/
@SpringBootApplication
public class MonitorApplication {
public static void main(String[] args) {
SpringApplication.run(MonitorApplication.class, args);
}
}

View File

@@ -0,0 +1,19 @@
/*
* Copyright (c) 2023 codvision.com All Rights Reserved.
*/
package com.codvision.monitor.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* 监控中心配置
*
* @author lingee
* @date 2023/11/20
*/
@Configuration
@ComponentScan(basePackages = "com.codvision.monitor")
public class MonitorConfig {
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (c) 2023 codvision.com All Rights Reserved.
*/
package com.codvision.monitor.config;
import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* swagger配置
*
* @author lingee
* @date 2023/11/7
*/
@EnableSwagger2
@EnableSwaggerBootstrapUI
@Configuration("monitorSwaggerConfig")
public class SwaggerConfig {
@Bean
public Docket monitorApiConfig() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(webApiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.codvision.monitor"))
.paths(PathSelectors.any())
.build().groupName("监控中心服务");
}
private ApiInfo webApiInfo() {
return new ApiInfoBuilder()
.title("监控中心服务接口管理")
.description("监控中心服务接口文档")
.version("1.0")
.license("Codvision")
.licenseUrl("http://www.codvision.com")
.build();
}
}

View File

@@ -0,0 +1,27 @@
package com.codvision.monitor.controller.manager;
import com.codvision.commoncore.common.ResponseEntity;
import com.codvision.monitor.entity.server.ServerInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 服务器监控数据 管理模块
*
* @author lingee
* @date 2023-11-20
*/
@Api(tags = "平台管理端-服务器监控数据")
@RestController
@RequestMapping("/v1/manager/server")
public class ManagerServerController {
@ApiOperation(value = "获取服务器信息", notes = "获取服务器信息接口")
@GetMapping("/info")
public ResponseEntity<ServerInfo> serverInfo() {
return new ResponseEntity<ServerInfo>().data(new ServerInfo());
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (c) 2023 codvision.com All Rights Reserved.
*/
package com.codvision.monitor.controller.manager;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.codvision.authcore.annotation.RequiresPermissions;
import com.codvision.commoncore.common.ResponseEntity;
import com.codvision.commoncore.utils.DateUtil;
import com.codvision.monitor.entity.SysLog;
import com.codvision.monitor.entity.vo.SysLogVO;
import com.codvision.monitor.service.ISysLogService;
import com.codvision.webcore.bean.QueryPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 系统日志 管理模块
*
* @author lingee
* @date 2023-11-20
*/
@RestController
@RequestMapping("/v1/manager/sysLog")
@Api(tags = "平台管理端-系统日志模块")
public class ManagerSysLogController {
@Autowired
private ISysLogService sysLogService;
@ApiOperation(value = "获取系统日志分页列表", notes = "获取系统日志分页列表接口")
@PostMapping("/all")
@RequiresPermissions("sys_log_list")
public ResponseEntity<IPage<SysLogVO>> getPageList(@ApiParam(value = "类型") @RequestParam(value = "type", required = false, defaultValue = "") String type,
@ApiParam(value = "开始时间") @RequestParam(value = "beginTime", required = false, defaultValue = "") String beginTime,
@ApiParam(value = "结束时间") @RequestParam(value = "endTime", required = false, defaultValue = "") String endTime,
@ApiParam(value = "关键字(内容)") @RequestParam(required = false) String keyword,
@RequestParam(value = "page", required = false, defaultValue = "1") int page,
@RequestParam(value = "size", required = false, defaultValue = "10") int size) {
SysLog queryBean = new SysLog();
queryBean.setType(type);
if (StrUtil.isNotBlank(beginTime)) {
queryBean.setBeginTime(DateUtil.toDate(beginTime));
}
if (StrUtil.isNotBlank(endTime)) {
queryBean.setEndTime(DateUtil.toDate(endTime));
}
queryBean.setContent(keyword);
IPage<SysLogVO> pageResult = sysLogService.getPageResult(new QueryPage<>(queryBean, page, size));
return new ResponseEntity<IPage<SysLogVO>>().ok().data(pageResult);
}
}

View File

@@ -0,0 +1,91 @@
package com.codvision.monitor.controller.manager;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.codvision.commoncore.common.ResponseEntity;
import com.codvision.monitor.entity.GitVersion;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
/**
* @author KX
* @date 2023/6/28 18:09
*/
@Slf4j
@RestController
@Api(tags = "平台管理端-版本信息管理模块")
public class ManagerVersionController {
@ApiOperation(value = "获取前后端版本信息", notes = "获取前后端版本信息接口")
@GetMapping(value = "/version")
public ResponseEntity<GitVersion> versionInformation() {
ResponseEntity<GitVersion> responseEntity = new ResponseEntity<>();
JSONObject jsonObject = JSONUtil.parseObj(readGitProperties());
GitVersion gitVersion = GitVersion.builder().tags(jsonObject.getStr("git.tags")).closestTagName(jsonObject.getStr("git.closest.tag.name"))
.branch(jsonObject.getStr("git.branch")).buildHost(jsonObject.getStr("git.build.host"))
.buildUserName(jsonObject.getStr("git.build.user.name")).buildUserEmail(jsonObject.getStr("git.build.user.email"))
.buildTime(jsonObject.getStr("git.build.time")).buildVersion(jsonObject.getStr("git.build.version"))
.commitIdAbbrev(jsonObject.getStr("git.commit.id.abbrev")).commitId(jsonObject.getStr("git.commit.id"))
.commitUserName(jsonObject.getStr("git.commit.user.name"))
.commitUserEmail(jsonObject.getStr("git.commit.user.email")).commitTime(jsonObject.getStr("git.commit.time"))
.commitMessageFull(jsonObject.getStr("git.commit.message.full")).totalCommitCount(jsonObject.getStr("git.total.commit.count"))
.remoteOriginUrl(jsonObject.getStr("git.remote.origin.url")).build();
log.info(jsonObject.toString());
responseEntity.setData(gitVersion);
return responseEntity;
}
private String readGitProperties() {
ClassLoader classLoader = getClass().getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("git.json");
try {
return readFromInputStream(inputStream);
} catch (IOException e) {
e.printStackTrace();
return "Version information could not be retrieved.";
}
}
private String readFromInputStream(InputStream inputStream)
throws IOException {
StringBuilder result = new StringBuilder();
try (
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8.name()))
) {
String line;
while ((line = br.readLine()) != null) {
result.append(line).append(System.lineSeparator());
}
}
return result.toString();
}
@PostMapping("/appVersion")
@ApiOperation(value = "获取移动端版本信息", notes = "获取移动端版本信息")
public ResponseEntity<String> appVersion(@ApiParam(value = "移动端文件路径", required = true) @RequestParam(value = "path") String path) {
ResponseEntity<String> responseEntity = new ResponseEntity<>();
try {
FileReader fileReader = new FileReader(path);
responseEntity.setData(fileReader.readString());
} catch (IORuntimeException e) {
responseEntity.setMessage("文件路径未找到移动端版本信息!如有需要请联系管理员配置");
}
return responseEntity;
}
}

View File

@@ -0,0 +1,131 @@
package com.codvision.monitor.controller.manager;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.codvision.commoncore.common.ResponseEntity;
import com.codvision.commoncore.exception.BusinessException;
import com.codvision.monitor.entity.Website;
import com.codvision.monitor.entity.WebsiteAccessRecord;
import com.codvision.monitor.entity.vo.WebsiteAccessRecordVO;
import com.codvision.monitor.entity.vo.WebsiteVO;
import com.codvision.monitor.service.IWebsiteAccessRecordService;
import com.codvision.monitor.service.IWebsiteService;
import com.codvision.webcore.annotation.ApiSecret;
import com.codvision.webcore.bean.QueryPage;
import com.google.common.base.Preconditions;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;
import java.util.UUID;
/**
* 站点信息 管理模块
*
* @author lingee
* @date 2023-11-20
*/
@RestController
@RequestMapping("/v1/manager/website")
@Api(tags = "平台管理端-埋点监控管理模块")
public class ManagerWebsiteController {
@Resource
private IWebsiteService websiteService;
@Resource
private IWebsiteAccessRecordService websiteAccessRecordService;
@ApiOperation(value = "获取站点信息分页列表", notes = "获取站点信息分页列表接口")
@PostMapping("/findAll")
public ResponseEntity<IPage<WebsiteVO>> getPageList(@RequestParam(required = false) String websiteName,
@RequestParam(required = false) String websiteKey,
@RequestParam(required = false, defaultValue = "1") int page,
@RequestParam(required = false, defaultValue = "10") int size) {
Website queryBean = new Website();
queryBean.setWebsiteName(websiteName);
queryBean.setKey(websiteKey);
IPage<WebsiteVO> pageResult = websiteService.getPageResult(new QueryPage<>(queryBean, page, size));
return new ResponseEntity<IPage<WebsiteVO>>().ok().data(pageResult);
}
@PostMapping("/getErrorMsgList")
@ApiOperation(value = "错误信息列表", notes = "获取错误信息列表接口")
public ResponseEntity<IPage<WebsiteAccessRecord>> getErrorMsgList(@RequestParam(value = "websiteKey") String websiteKey,
@RequestParam(required = false, defaultValue = "1") int page,
@RequestParam(required = false, defaultValue = "10") int size) {
ResponseEntity<IPage<WebsiteAccessRecord>> responseEntity = new ResponseEntity<>();
LambdaQueryWrapper<WebsiteAccessRecord> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.eq(WebsiteAccessRecord::getWebsiteKey, websiteKey)
.eq(WebsiteAccessRecord::getType, 1)
.orderByDesc(WebsiteAccessRecord::getCreateTime);
IPage<WebsiteAccessRecord> pageResult = websiteAccessRecordService
.page(new QueryPage<WebsiteAccessRecord>(page, size).getPage(), queryWrapper);
return responseEntity.ok().data(pageResult);
}
@ApiOperation(value = "新增站点信息", notes = "新增站点信息接口")
@PostMapping("/add")
public ResponseEntity<String> saveWebsite(@Valid @RequestBody Website website) {
Website isExist = websiteService.getOne(Wrappers.<Website>lambdaQuery().eq(Website::getWebsiteName, website.getWebsiteName()));
website.setKey(UUID.randomUUID().toString());
website.setIsMain(false);
Preconditions.checkArgument(isExist == null || isExist.getId().equals(website.getId()), "网站名称已存在!");
websiteService.save(website);
return new ResponseEntity<String>().ok().message("添加成功");
}
@ApiOperation(value = "删除站点信息", notes = "删除站点信息接口")
@PostMapping("/del")
public ResponseEntity<String> deleteById(@ApiParam(value = "站点信息ID", required = true) @RequestParam Integer id) {
websiteService.removeById(id);
return new ResponseEntity<String>().ok().message("删除成功");
}
@ApiOperation(value = "更新站点信息", notes = "更新站点信息接口")
@PostMapping("/update")
public ResponseEntity<String> updateWebsite(@RequestBody Website website) {
if (ObjectUtil.isEmpty(website.getId())) {
throw new BusinessException(30002);
}
websiteService.updateById(website);
return new ResponseEntity<String>().ok().message("更新成功");
}
@ApiSecret(ignore = true)
@PostMapping("/addRecord")
@ApiOperation(value = "添加访问记录", notes = "添加访问记录")
public ResponseEntity<String> addRecord(@Validated @RequestBody WebsiteAccessRecord accessRecord, HttpServletRequest request) {
websiteAccessRecordService.addRecord(accessRecord, request);
return new ResponseEntity<String>().ok();
}
@PostMapping("/getPvCount")
@ApiOperation(value = "浏览量PV统计", notes = "浏览量PV统计")
public ResponseEntity<List<WebsiteAccessRecordVO>> getPvCount(@RequestParam(value = "websiteKey") String websiteKey,
@RequestParam(value = "startTime") String startTime,
@RequestParam(value = "endTime") String endTime) {
ResponseEntity<List<WebsiteAccessRecordVO>> responseEntity = new ResponseEntity<>();
return responseEntity.data(websiteAccessRecordService.getPvCountList(websiteKey, startTime, endTime));
}
@PostMapping("/getUvCount")
@ApiOperation(value = "访客数UV统计", notes = "访客数UV统计")
public ResponseEntity<List<WebsiteAccessRecordVO>> getUvCount(@RequestParam(value = "websiteKey") String websiteKey,
@RequestParam(value = "startTime") String startTime,
@RequestParam(value = "endTime") String endTime) {
ResponseEntity<List<WebsiteAccessRecordVO>> responseEntity = new ResponseEntity<>();
return responseEntity.data(websiteAccessRecordService.getUvCountList(websiteKey, startTime, endTime));
}
}

View File

@@ -0,0 +1,9 @@
/*
* Copyright (c) 2023 codvision.com All Rights Reserved.
*/
/**
* @author lingee
* @date 2023/11/20
*/
package com.codvision.monitor.controller;

View File

@@ -0,0 +1,67 @@
package com.codvision.monitor.entity;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author KX
* @date 2023/6/29 10:04
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class GitVersion {
@ApiModelProperty(value = "标签(git.tags)")
private String tags;
@ApiModelProperty(value = "最近标签(git.closest.tag.name)")
private String closestTagName;
@ApiModelProperty(value = "分支(git.branch)")
private String branch;
@ApiModelProperty(value = "构建编译主机(git.build.host)")
private String buildHost;
@ApiModelProperty(value = "构建编译用户名(git.build.user.name)")
private String buildUserName;
@ApiModelProperty(value = "构建编译用户邮箱(git.build.user.email)")
private String buildUserEmail;
@ApiModelProperty(value = "构建编译时间(git.build.time)")
private String buildTime;
@ApiModelProperty(value = "构建编译版本(git.build.version)")
private String buildVersion;
@ApiModelProperty(value = "提交id缩写(git.commit.id.abbrev)")
private String commitIdAbbrev;
@ApiModelProperty(value = "提交id(git.commit.id)")
private String commitId;
@ApiModelProperty(value = "提交用户名(git.commit.user.name)")
private String commitUserName;
@ApiModelProperty(value = "提交用户邮箱(git.commit.user.email)")
private String commitUserEmail;
@ApiModelProperty(value = "提交时间(git.commit.time)")
private String commitTime;
@ApiModelProperty(value = "提交信息(git.commit.message.full)")
private String commitMessageFull;
@ApiModelProperty(value = "总提交数(git.total.commit.count)")
private String totalCommitCount;
@ApiModelProperty(value = "远程仓库url(git.remote.origin.url)")
private String remoteOriginUrl;
}

View File

@@ -0,0 +1,69 @@
package com.codvision.monitor.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.codvision.commoncore.enums.SqlOperator;
import com.codvision.webcore.annotation.QueryCondition;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
* 系统日志
* </p>
*
* @author lingee
* @since 2023-11-20
*/
@Data
@TableName("tbl_sys_log")
@ApiModel(value = "SysLog", description = "系统日志")
public class SysLog implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("主键")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty("日志类型")
@QueryCondition(condition = SqlOperator.EQ)
private String type;
@ApiModelProperty("操作人")
private String operator;
@ApiModelProperty("操作人用户id")
private Integer operatorUid;
@ApiModelProperty("日志内容")
@QueryCondition(condition = SqlOperator.LIKE)
private String content;
@ApiModelProperty("操作接口")
private String method;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("ip地址")
private String ip;
@ApiModelProperty("参数")
private String params;
@ApiModelProperty("开始时间")
@TableField(exist = false)
private Date beginTime;
@ApiModelProperty("结束时间")
@TableField(exist = false)
private Date endTime;
}

View File

@@ -0,0 +1,53 @@
package com.codvision.monitor.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* <p>
* 站点信息
* </p>
*
* @author lingee
* @since 2023-11-20
*/
@Data
@TableName("tbl_website")
@ApiModel(value = "Website", description = "站点信息")
public class Website implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("主键")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty("网站key")
private String key;
@ApiModelProperty("网站名称")
private String websiteName;
@ApiModelProperty("网站链接")
private String websiteUrl;
@ApiModelProperty("网站图标")
private String iconUrl;
@ApiModelProperty("当前系统标志")
private Boolean isMain;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("更新时间")
private Date updateTime;
}

View File

@@ -0,0 +1,59 @@
package com.codvision.monitor.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* <p>
* 站点访问记录
* </p>
*
* @author lingee
* @since 2023-11-20
*/
@Data
@TableName("tbl_website_access_record")
@ApiModel(value = "WebsiteAccessRecord", description = "站点访问记录")
public class WebsiteAccessRecord implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("主键")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty("网站key")
private String websiteKey;
@ApiModelProperty("访问界面地址")
private String url;
@ApiModelProperty("访问者ID")
private Integer visitorUid;
@ApiModelProperty("访问者用户名")
private String visitorName;
@ApiModelProperty("IP地址")
private String ip;
@ApiModelProperty("错误信息")
private String errorMsg;
@ApiModelProperty("类型 0-pv/uv、1-错误信息")
private Short type;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("更新时间")
private Date updateTime;
}

View File

@@ -0,0 +1,23 @@
package com.codvision.monitor.entity.server;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
/**
* @author hxl
*/
@Data
@Builder
@ApiModel
public class DirectoryFile {
@ApiModelProperty("所在磁盘总大小")
private String total;
@ApiModelProperty("所在磁盘剩余大小")
private String free;
@ApiModelProperty("当前目录的使用量")
private String used;
@ApiModelProperty("当前目录的使用率")
private double usage;
}

View File

@@ -0,0 +1,116 @@
/*
* Copyright (c) 2023 codvision.com All Rights Reserved.
*/
package com.codvision.monitor.entity.server;
import cn.hutool.core.date.DateUtil;
import com.codvision.monitor.support.Arith;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import java.lang.management.ManagementFactory;
import java.util.Date;
/**
* JVM相关信息
*
* @author hxl
*/
@Builder
@ApiModel
public class Jvm {
@ApiModelProperty("当前JVM占用的内存总数(M)")
private double total;
@ApiModelProperty("JVM最大可用内存总数(M)")
private double max;
@ApiModelProperty("JVM空闲内存(M)")
private double free;
@ApiModelProperty("JDK版本")
private String version;
@ApiModelProperty("JDK路径")
private String home;
public double getTotal() {
return Arith.div(total, (1024 * 1024), 2);
}
public void setTotal(double total) {
this.total = total;
}
public double getMax() {
return Arith.div(max, (1024 * 1024), 2);
}
public void setMax(double max) {
this.max = max;
}
public double getFree() {
return Arith.div(free, (1024 * 1024), 2);
}
public void setFree(double free) {
this.free = free;
}
public double getUsed() {
return Arith.div(total - free, (1024 * 1024), 2);
}
public double getUsage() {
return Arith.mul(Arith.div(total - free, total, 4), 100);
}
/**
* 获取JDK名称
*/
public String getName() {
return ManagementFactory.getRuntimeMXBean().getVmName();
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getHome() {
return home;
}
public void setHome(String home) {
this.home = home;
}
/**
* JDK启动时间
*/
public String getStartTime() {
return DateUtil.format(new Date(ManagementFactory.getRuntimeMXBean().getStartTime()), "yyyy-MM-dd HH:mm:ss");
}
/**
* JDK运行时间
*/
public String getRunTime() {
return getDatePoor(new Date(), new Date(ManagementFactory.getRuntimeMXBean().getStartTime()));
}
private String getDatePoor(Date endDate, Date nowDate) {
long nd = 1000 * 24 * 60 * 60;
long nh = 1000 * 60 * 60;
long nm = 1000 * 60;
long diff = endDate.getTime() - nowDate.getTime();
long day = diff / nd;
long hour = diff % nd / nh;
long min = diff % nd % nh / nm;
return day + "" + hour + "小时" + min + "分钟";
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2023 codvision.com All Rights Reserved.
*/
package com.codvision.monitor.entity.server;
import com.codvision.monitor.support.Arith;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
/**
* 內存相关信息
*
* @author hxl
*/
@Builder
@ApiModel
public class Mem {
@ApiModelProperty("内存总量")
private double total;
@ApiModelProperty("已用内存")
private double used;
@ApiModelProperty("剩余内存")
private double free;
public double getTotal() {
return Arith.div(total, (1024 * 1024 * 1024), 2);
}
public void setTotal(long total) {
this.total = total;
}
public double getUsed() {
return Arith.div(used, (1024 * 1024 * 1024), 2);
}
public void setUsed(long used) {
this.used = used;
}
public double getFree() {
return Arith.div(free, (1024 * 1024 * 1024), 2);
}
public void setFree(long free) {
this.free = free;
}
public double getUsage() {
return Arith.mul(Arith.div(used, total, 4), 100);
}
}

View File

@@ -0,0 +1,144 @@
package com.codvision.monitor.entity.server;
import cn.hutool.core.net.NetUtil;
import cn.hutool.system.oshi.CpuInfo;
import cn.hutool.system.oshi.OshiUtil;
import com.codvision.monitor.support.Arith;
import lombok.Data;
import org.apache.commons.io.FileUtils;
import oshi.SystemInfo;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;
import java.io.File;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import static com.codvision.monitor.support.MonitorConstant.LINUX;
/**
* 服务器相关信息
*
* @author hxl
*/
@Data
public class ServerInfo {
private CpuInfo cpu;
private Mem mem;
private Jvm jvm;
private Sys sys;
private List<SysFile> sysFiles;
private DirectoryFile directoryFile;
private static final OperatingSystem OS;
private static final SystemInfo SYSTEM_INFO;
private static final HardwareAbstractionLayer HARDWARE;
static {
SYSTEM_INFO = new SystemInfo();
HARDWARE = SYSTEM_INFO.getHardware();
OS = SYSTEM_INFO.getOperatingSystem();
}
public ServerInfo() {
init();
}
private void init() {
// 初始化CPU信息
cpu = OshiUtil.getCpuInfo();
// 初始化内存信息
initMemInfo();
// 初始化服务器信息
initSysInfo();
// 初始化JVM信息
initJvmInfo();
// 初始化磁盘信息
initDiskInfo();
// 初始化data目录
initDataDirectory();
}
private void initMemInfo() {
GlobalMemory memory = HARDWARE.getMemory();
mem = Mem.builder().total(memory.getTotal()).free(memory.getAvailable()).used(memory.getTotal() - memory.getAvailable()).build();
}
private void initSysInfo() {
Properties props = System.getProperties();
sys = Sys.builder().computerName(getHostName()).computerIp(NetUtil.getLocalhostStr())
.osName(OS.getFamily() + " " + OS.getVersionInfo().getVersion())
.osArch(props.getProperty("os.arch")).userDir(props.getProperty("user.dir"))
.build();
}
private void initJvmInfo() {
Properties props = System.getProperties();
jvm = Jvm.builder().total(Runtime.getRuntime().totalMemory()).max(Runtime.getRuntime().maxMemory())
.free(Runtime.getRuntime().freeMemory()).version(props.getProperty("java.version")).home(props.getProperty("java.home"))
.build();
}
private void initDiskInfo() {
sysFiles = new LinkedList<>();
FileSystem fileSystem = OS.getFileSystem();
List<OSFileStore> fsArray = fileSystem.getFileStores();
for (OSFileStore fs : fsArray) {
long free = fs.getUsableSpace();
long total = fs.getTotalSpace();
long used = total - free;
SysFile sysFile = SysFile.builder().dirName(fs.getMount()).sysTypeName(fs.getType()).typeName(fs.getName())
.total(convertFileSize(total)).free(convertFileSize(free)).used(convertFileSize(used)).usage(Arith.mul(Arith.div(used, total, 4), 100)).build();
sysFiles.add(sysFile);
}
}
private void initDataDirectory() {
if (LINUX.equalsIgnoreCase(OS.getFamily())) {
File file = new File("/data");
if (file.exists()) {
long total = file.getTotalSpace();
long free = file.getFreeSpace();
long used = FileUtils.sizeOfDirectory(file);
directoryFile = DirectoryFile.builder().total(convertFileSize(total)).free(convertFileSize(free))
.used(convertFileSize(used)).usage(Arith.mul(Arith.div(used, total, 4), 100)).build();
}
}
}
private String convertFileSize(long size) {
long kb = 1024;
long mb = kb * 1024;
long gb = mb * 1024;
if (size >= gb) {
return String.format("%.1f GB", (float) size / gb);
} else if (size >= mb) {
float f = (float) size / mb;
return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
} else if (size >= kb) {
float f = (float) size / kb;
return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
} else {
return String.format("%d B", size);
}
}
private String getHostName() {
try {
return InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException ignored) {
}
return "未知";
}
}

View File

@@ -0,0 +1,27 @@
package com.codvision.monitor.entity.server;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
/**
* 系统相关信息
* @author hxl
*/
@Data
@Builder
@ApiModel
public class Sys {
@ApiModelProperty("服务器名称")
private String computerName;
@ApiModelProperty("服务器Ip")
private String computerIp;
@ApiModelProperty("项目路径")
private String userDir;
@ApiModelProperty("操作系统")
private String osName;
@ApiModelProperty("系统架构")
private String osArch;
}

View File

@@ -0,0 +1,31 @@
package com.codvision.monitor.entity.server;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
/**
* 系统文件相关信息
* @author hxl
*/
@Data
@Builder
@ApiModel
public class SysFile {
@ApiModelProperty("盘符路径")
private String dirName;
@ApiModelProperty("盘符类型")
private String sysTypeName;
@ApiModelProperty("文件类型")
private String typeName;
@ApiModelProperty("总大小")
private String total;
@ApiModelProperty("剩余大小")
private String free;
@ApiModelProperty("已经使用量")
private String used;
@ApiModelProperty("资源的使用率")
private double usage;
}

View File

@@ -0,0 +1,57 @@
package com.codvision.monitor.entity.vo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 系统日志展示信息
* </p>
*
* @author lingee
* @since 2023-11-20
*/
@Getter
@Setter
@ApiModel(value = "SysLogVO", description = "系统日志展示信息")
public class SysLogVO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("主键")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty("日志类型")
private String type;
@ApiModelProperty("操作人")
private String operator;
@ApiModelProperty("操作人用户id")
private Integer operatorUid;
@ApiModelProperty("日志内容")
private String content;
@ApiModelProperty("操作接口")
private String method;
@ApiModelProperty("创建时间")
private Date createTime;
@ApiModelProperty("ip地址")
private String ip;
@ApiModelProperty("参数")
private String params;
}

View File

@@ -0,0 +1,33 @@
package com.codvision.monitor.entity.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
/**
* <p>
* 站点访问记录展示信息
* </p>
*
* @author lingee
* @since 2023-11-20
*/
@Getter
@Setter
@ApiModel(value = "WebsiteAccessRecordVO", description = "站点访问记录展示信息")
public class WebsiteAccessRecordVO implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("日期")
private String day;
@ApiModelProperty("浏览量(PV)")
private Integer pvNum;
@ApiModelProperty("访客数(UV)")
private Integer uvNum;
}

View File

@@ -0,0 +1,41 @@
package com.codvision.monitor.entity.vo;
import com.codvision.monitor.entity.Website;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 站点信息展示信息
* </p>
*
* @author lingee
* @since 2023-11-20
*/
@Getter
@Setter
@ApiModel(value = "WebsiteVO", description = "站点信息展示信息")
public class WebsiteVO extends Website {
private static final long serialVersionUID = 1L;
@ApiModelProperty("今日浏览量(PV)")
private Integer todayPvNum;
@ApiModelProperty("昨日浏览量(PV)")
private Integer yesterdayPvNum;
@ApiModelProperty("今日访客数(UV)")
private Integer todayUvNum;
@ApiModelProperty("昨日访客数(UV)")
private Integer yesterdayUvNum;
@ApiModelProperty("今日IP数")
private Integer todayIpNum;
@ApiModelProperty("昨日IP数")
private Integer yesterdayIpNum;
}

View File

@@ -0,0 +1,16 @@
package com.codvision.monitor.mapper;
import com.codvision.monitor.entity.SysLog;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* 系统日志 Mapper 接口
* </p>
*
* @author lingee
* @since 2023-11-20
*/
public interface SysLogMapper extends BaseMapper<SysLog> {
}

View File

@@ -0,0 +1,39 @@
package com.codvision.monitor.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.codvision.monitor.entity.WebsiteAccessRecord;
import com.codvision.monitor.entity.vo.WebsiteAccessRecordVO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 站点访问记录 Mapper 接口
* </p>
*
* @author lingee
* @since 2023-11-20
*/
public interface WebsiteAccessRecordMapper extends BaseMapper<WebsiteAccessRecord> {
/**
* 获取Pv数
*
* @param websiteKey 网站key
* @param startTime 日期起始时间
* @param endTime 日期结束时间
* @return pv数
*/
List<WebsiteAccessRecordVO> getPvCountList(@Param("websiteKey") String websiteKey, @Param("startTime") String startTime, @Param("endTime") String endTime);
/**
* 获取Uv数
*
* @param websiteKey 网站key
* @param startTime 日期起始时间
* @param endTime 日期结束时间
* @return Uv数
*/
List<WebsiteAccessRecordVO> getUvCountList(@Param("websiteKey") String websiteKey, @Param("startTime") String startTime, @Param("endTime") String endTime);
}

View File

@@ -0,0 +1,29 @@
package com.codvision.monitor.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.codvision.monitor.entity.Website;
import com.codvision.monitor.entity.vo.WebsiteVO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 站点信息 Mapper 接口
* </p>
*
* @author lingee
* @since 2023-11-20
*/
public interface WebsiteMapper extends BaseMapper<Website> {
/**
* 分页查询站点信息列表
*
* @param websiteName 站点名称
* @param websiteKey 站点key
* @return 站点列表
*/
List<WebsiteVO> findAll(IPage page, @Param("websiteName") String websiteName, @Param("websiteKey") String websiteKey);
}

View File

@@ -0,0 +1,11 @@
/*
* Copyright (c) 2023 codvision.com All Rights Reserved.
*/
/**
* 系统监控中心
*
* @author lingee
* @date 2023/11/20
*/
package com.codvision.monitor;

View File

@@ -0,0 +1,44 @@
package com.codvision.monitor.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.codvision.monitor.entity.SysLog;
import com.codvision.monitor.entity.vo.SysLogVO;
import com.codvision.webcore.service.IBaseService;
import com.codvision.webcore.bean.QueryPage;
import java.util.List;
/**
* <p>
* 系统日志 服务类
* </p>
*
* @author lingee
* @since 2023-11-20
*/
public interface ISysLogService extends IBaseService<SysLog, SysLogVO> {
/**
* 获取系统日志详情
*
* @param id
* @return 系统日志
*/
SysLogVO getDetail(Long id);
/**
* 分页查询系统日志
*
* @param queryPage 分页参数
* @return 分页结果
*/
IPage<SysLogVO> getPageResult(QueryPage<SysLog> queryPage);
/**
* 根据条件查询系统日志
*
* @param queryBean 查询条件
* @return 系统日志列表
*/
List<SysLogVO> listAll(SysLog queryBean);
}

View File

@@ -0,0 +1,47 @@
package com.codvision.monitor.service;
import com.codvision.monitor.entity.WebsiteAccessRecord;
import com.codvision.monitor.entity.vo.WebsiteAccessRecordVO;
import com.codvision.webcore.service.IBaseService;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
* <p>
* 站点访问记录 服务类
* </p>
*
* @author lingee
* @since 2023-11-20
*/
public interface IWebsiteAccessRecordService extends IBaseService<WebsiteAccessRecord, WebsiteAccessRecordVO> {
/**
* 添加访问记录
*
* @param accessRecord 访问记录
* @param request 请求信息
*/
void addRecord(WebsiteAccessRecord accessRecord, HttpServletRequest request);
/**
* 浏览量PV统计
*
* @param websiteKey 站点key
* @param startTime 开始时间
* @param endTime 结束时间
* @return PV统计结果
*/
List<WebsiteAccessRecordVO> getPvCountList(String websiteKey, String startTime, String endTime);
/**
* 访客数UV统计
*
* @param websiteKey 站点key
* @param startTime 开始时间
* @param endTime 结束时间
* @return UV统计结果
*/
List<WebsiteAccessRecordVO> getUvCountList(String websiteKey, String startTime, String endTime);
}

View File

@@ -0,0 +1,34 @@
package com.codvision.monitor.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.codvision.monitor.entity.Website;
import com.codvision.monitor.entity.vo.WebsiteVO;
import com.codvision.webcore.bean.QueryPage;
import com.codvision.webcore.service.IBaseService;
/**
* <p>
* 站点信息 服务类
* </p>
*
* @author lingee
* @since 2023-11-20
*/
public interface IWebsiteService extends IBaseService<Website, WebsiteVO> {
/**
* 获取站点信息详情
*
* @param id
* @return 站点信息
*/
WebsiteVO getDetail(Long id);
/**
* 分页查询站点信息
*
* @param queryPage 分页参数
* @return 分页结果
*/
IPage<WebsiteVO> getPageResult(QueryPage<Website> queryPage);
}

View File

@@ -0,0 +1,77 @@
package com.codvision.monitor.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.codvision.monitor.entity.SysLog;
import com.codvision.monitor.entity.vo.SysLogVO;
import com.codvision.monitor.mapper.SysLogMapper;
import com.codvision.monitor.service.ISysLogService;
import com.codvision.webcore.service.impl.BaseServiceImpl;
import com.codvision.webcore.bean.QueryPage;
import com.codvision.webcore.util.PageUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.io.Serializable;
import java.util.List;
/**
* <p>
* 系统日志 服务实现类
* </p>
*
* @author lingee
* @since 2023-11-20
*/
@Service
public class SysLogServiceImpl extends BaseServiceImpl<SysLogMapper, SysLog, SysLogVO> implements ISysLogService {
@Override
public SysLogVO getDetail(Long id) {
SysLogVO vo = new SysLogVO();
SysLog po = this.getById(id);
if (null != po) {
BeanUtil.copyProperties(po, vo);
}
return vo;
}
@Override
public IPage<SysLogVO> getPageResult(QueryPage<SysLog> queryPage) {
QueryWrapper<SysLog> queryWrapper = queryPage.getWrapper();
queryWrapper.orderByDesc("create_time");
IPage<SysLogVO> pageResult = this.getBasePage(queryPage.getPage(), queryWrapper);
return pageResult;
}
@Override
public List<SysLogVO> listAll(SysLog queryBean) {
QueryWrapper<SysLog> wrapper = PageUtil.initWrapper(queryBean);
List<SysLog> list = this.list(wrapper);
return BeanUtil.copyToList(list, SysLogVO.class);
}
@Override
public boolean save(SysLog sysLog) {
Assert.notNull(sysLog, "系统日志不能为空");
getBaseMapper().insert(sysLog);
return true;
}
@Override
public boolean updateById(SysLog sysLog) {
Assert.notNull(sysLog, "系统日志不能为空");
Assert.notNull(sysLog.getId(), "系统日志id不能为空");
getBaseMapper().updateById(sysLog);
return true;
}
@Override
public boolean removeById(Serializable id) {
SysLog sysLog = getById(id);
Assert.notNull(sysLog, "系统日志不存在");
getBaseMapper().deleteById(id);
return true;
}
}

View File

@@ -0,0 +1,52 @@
package com.codvision.monitor.service.impl;
import cn.hutool.extra.servlet.ServletUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.codvision.monitor.entity.Website;
import com.codvision.monitor.entity.WebsiteAccessRecord;
import com.codvision.monitor.entity.vo.WebsiteAccessRecordVO;
import com.codvision.monitor.mapper.WebsiteAccessRecordMapper;
import com.codvision.monitor.service.IWebsiteAccessRecordService;
import com.codvision.monitor.service.IWebsiteService;
import com.codvision.webcore.service.impl.BaseServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
/**
* <p>
* 站点访问记录 服务实现类
* </p>
*
* @author lingee
* @since 2023-11-20
*/
@Service
public class WebsiteAccessRecordServiceImpl extends BaseServiceImpl<WebsiteAccessRecordMapper, WebsiteAccessRecord, WebsiteAccessRecordVO> implements IWebsiteAccessRecordService {
@Resource
private IWebsiteService websiteService;
@Override
public void addRecord(WebsiteAccessRecord accessRecord, HttpServletRequest request) {
Website website = websiteService.getOne(Wrappers.<Website>lambdaQuery().eq(Website::getKey, accessRecord.getWebsiteKey()));
if (website == null) {
return;
}
accessRecord.setIp(ServletUtil.getClientIP(request));
this.save(accessRecord);
}
@Override
public List<WebsiteAccessRecordVO> getPvCountList(String websiteKey, String startTime, String endTime) {
return getBaseMapper().getPvCountList(websiteKey, startTime, endTime);
}
@Override
public List<WebsiteAccessRecordVO> getUvCountList(String websiteKey, String startTime, String endTime) {
return getBaseMapper().getUvCountList(websiteKey, startTime, endTime);
}
}

View File

@@ -0,0 +1,69 @@
package com.codvision.monitor.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.codvision.monitor.entity.Website;
import com.codvision.monitor.entity.vo.WebsiteVO;
import com.codvision.monitor.mapper.WebsiteMapper;
import com.codvision.monitor.service.IWebsiteService;
import com.codvision.webcore.bean.QueryPage;
import com.codvision.webcore.service.impl.BaseServiceImpl;
import com.codvision.webcore.util.PageUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.io.Serializable;
import java.util.List;
/**
* <p>
* 站点信息 服务实现类
* </p>
*
* @author lingee
* @since 2023-11-20
*/
@Service
public class WebsiteServiceImpl extends BaseServiceImpl<WebsiteMapper, Website, WebsiteVO> implements IWebsiteService {
@Override
public WebsiteVO getDetail(Long id) {
WebsiteVO vo = new WebsiteVO();
Website po = this.getById(id);
if (null != po) {
BeanUtil.copyProperties(po, vo);
}
return vo;
}
@Override
public IPage<WebsiteVO> getPageResult(QueryPage<Website> queryPage) {
IPage<Website> page = queryPage.getPage();
Website queryBean = queryPage.getCondition();
List<WebsiteVO> pageResult = this.getBaseMapper().findAll(page, queryBean.getWebsiteName(), queryBean.getKey());
return PageUtil.convertPage(page, pageResult);
}
@Override
public boolean save(Website website) {
Assert.notNull(website, "站点信息不能为空");
getBaseMapper().insert(website);
return true;
}
@Override
public boolean updateById(Website website) {
Assert.notNull(website, "站点信息不能为空");
Assert.notNull(website.getId(), "站点信息id不能为空");
getBaseMapper().updateById(website);
return true;
}
@Override
public boolean removeById(Serializable id) {
Website website = getById(id);
Assert.notNull(website, "站点信息不存在");
getBaseMapper().deleteById(id);
return true;
}
}

View File

@@ -0,0 +1,116 @@
package com.codvision.monitor.support;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* 精确的浮点数运算
* @author hxl
*/
@SuppressWarnings("all")
public class Arith {
/**
* 默认除法运算精度
*/
private static final int DEF_DIV_SCALE = 10;
/**
* 这个类不能实例化
*/
private Arith() {
}
/**
* 提供精确的加法运算。
*
* @param v1 被加数
* @param v2 加数
* @return 两个参数的和
*/
public static double add(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
/**
* 提供精确的减法运算。
*
* @param v1 被减数
* @param v2 减数
* @return 两个参数的差
*/
public static double sub(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2).doubleValue();
}
/**
* 提供精确的乘法运算。
*
* @param v1 被乘数
* @param v2 乘数
* @return 两个参数的积
*/
public static double mul(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue();
}
/**
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
* 小数点以后10位以后的数字四舍五入。
*
* @param v1 被除数
* @param v2 除数
* @return 两个参数的商
*/
public static double div(double v1, double v2) {
return div(v1, v2, DEF_DIV_SCALE);
}
/**
* 提供相对精确的除法运算。当发生除不尽的情况时由scale参数指
* 定精度,以后的数字四舍五入。
*
* @param v1 被除数
* @param v2 除数
* @param scale 表示表示需要精确到小数点以后几位。
* @return 两个参数的商
*/
public static double div(double v1, double v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
if (b1.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ZERO.doubleValue();
}
return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue();
}
/**
* 提供精确的小数位四舍五入处理。
*
* @param v 需要四舍五入的数字
* @param scale 小数点后保留几位
* @return 四舍五入后的结果
*/
public static double round(double v, int scale) {
if (scale < 0) {
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = BigDecimal.ONE;
return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue();
}
}

View File

@@ -0,0 +1,19 @@
/*
* Copyright (c) 2023 codvision.com All Rights Reserved.
*/
package com.codvision.monitor.support;
/**
* 监控服务常量类
*
* @author lingee
* @date 2023/11/20
*/
public class MonitorConstant {
// 网站key
public static final String WEBSITE_KEY = "WEBSITE_KEY";
// LINUX
public static final String LINUX = "CentOS Linux";
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (c) 2023 codvision.com All Rights Reserved.
*/
package com.codvision.monitor.task;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.codvision.logcore.aop.SysLogAspect;
import com.codvision.logcore.bean.SysLogMessage;
import com.codvision.monitor.entity.SysLog;
import com.codvision.monitor.service.ISysLogService;
import com.codvision.mqcore.annotation.MQHandler;
import com.codvision.mqcore.annotation.MQListener;
import lombok.extern.slf4j.Slf4j;
import javax.annotation.Resource;
/**
* 关闭订单消费者
*/
@Slf4j
@MQHandler
public class SysLogMQTask {
@Resource
private ISysLogService sysLogService;
@MQListener(queues = SysLogAspect.SYS_LOG_QUEUE_NAME)
public void sysLogListener(SysLogMessage sysLogMessage) {
log.info("接收系统操作日志");
if (ObjectUtil.isNotEmpty(sysLogMessage)) {
SysLog sysLog = BeanUtil.toBean(sysLogMessage, SysLog.class);
sysLogService.save(sysLog);
}
}
}

View File

@@ -0,0 +1 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.codvision.monitor.config.MonitorConfig

View File

@@ -0,0 +1,27 @@
# 数据源配置
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: org.postgresql.Driver
username: postgres
password: 123456
url: jdbc:postgresql://127.0.0.1:5432/boot_base?useUnicode=true&characterEncoding=utf8&autoReconnect=true&stringtype=unspecified
servlet:
multipart:
max-file-size: 500MB
max-request-size: 500MB
# knife4j接口文档配置
swagger:
basic:
enable: false
username: CVER
password: Swagger@2023
# 底座配置
cvbp:
# 认证配置
auth:
enabled: false
host: http://127.0.0.1:9050
tokenName: Authorization

View File

@@ -0,0 +1,19 @@
# 数据源配置
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: org.postgresql.Driver
username: postgres
password: 123456
url: jdbc:postgresql://127.0.0.1:5432/boot_base?useUnicode=true&characterEncoding=utf8&autoReconnect=true&stringtype=unspecified
# knife4j接口文档配置
swagger:
production: true
# 底座配置
cvbp:
# 认证配置
auth:
enabled: false
host: http://127.0.0.1:9050
tokenName: Authorization

View File

@@ -0,0 +1,8 @@
spring:
profiles:
active: @profiles.active@
server:
port: 8050
logging:
level:
root: info

View File

@@ -0,0 +1,155 @@
-- ----------------------------
-- Sequence structure for tbl_sys_log_id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."tbl_sys_log_id_seq";
CREATE SEQUENCE "public"."tbl_sys_log_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
ALTER SEQUENCE "public"."tbl_sys_log_id_seq" OWNER TO "postgres";
-- ----------------------------
-- Sequence structure for tbl_website_access_record_id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."tbl_website_access_record_id_seq";
CREATE SEQUENCE "public"."tbl_website_access_record_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 9223372036854775807
START 1
CACHE 1;
ALTER SEQUENCE "public"."tbl_website_access_record_id_seq" OWNER TO "postgres";
-- ----------------------------
-- Sequence structure for tbl_website_id_seq
-- ----------------------------
DROP SEQUENCE IF EXISTS "public"."tbl_website_id_seq";
CREATE SEQUENCE "public"."tbl_website_id_seq"
INCREMENT 1
MINVALUE 1
MAXVALUE 2147483647
START 1
CACHE 1;
ALTER SEQUENCE "public"."tbl_website_id_seq" OWNER TO "postgres";
-- ----------------------------
-- Table structure for tbl_sys_log
-- ----------------------------
DROP TABLE IF EXISTS "public"."tbl_sys_log";
CREATE TABLE "public"."tbl_sys_log" (
"id" int4 NOT NULL DEFAULT nextval('tbl_sys_log_id_seq'::regclass),
"type" varchar(255) COLLATE "pg_catalog"."default",
"operator" varchar(255) COLLATE "pg_catalog"."default",
"operator_uid" int4,
"content" text COLLATE "pg_catalog"."default",
"method" varchar(255) COLLATE "pg_catalog"."default",
"create_time" timestamp(6) DEFAULT now(),
"ip" varchar(255) COLLATE "pg_catalog"."default",
"params" text COLLATE "pg_catalog"."default"
)
;
ALTER TABLE "public"."tbl_sys_log" OWNER TO "postgres";
COMMENT ON COLUMN "public"."tbl_sys_log"."id" IS '主键';
COMMENT ON COLUMN "public"."tbl_sys_log"."type" IS '日志类型';
COMMENT ON COLUMN "public"."tbl_sys_log"."operator" IS '操作人';
COMMENT ON COLUMN "public"."tbl_sys_log"."operator_uid" IS '操作人用户id';
COMMENT ON COLUMN "public"."tbl_sys_log"."content" IS '日志内容';
COMMENT ON COLUMN "public"."tbl_sys_log"."method" IS '操作接口';
COMMENT ON COLUMN "public"."tbl_sys_log"."create_time" IS '创建时间';
COMMENT ON COLUMN "public"."tbl_sys_log"."ip" IS 'ip地址';
COMMENT ON COLUMN "public"."tbl_sys_log"."params" IS '参数';
COMMENT ON TABLE "public"."tbl_sys_log" IS '系统日志';
-- ----------------------------
-- Table structure for tbl_website
-- ----------------------------
DROP TABLE IF EXISTS "public"."tbl_website";
CREATE TABLE "public"."tbl_website" (
"id" int4 NOT NULL DEFAULT nextval('tbl_website_id_seq'::regclass),
"key" varchar(255) COLLATE "pg_catalog"."default",
"website_name" varchar(255) COLLATE "pg_catalog"."default",
"website_url" varchar(255) COLLATE "pg_catalog"."default",
"icon_url" varchar(255) COLLATE "pg_catalog"."default",
"is_main" bool NOT NULL DEFAULT false,
"create_time" timestamp(6) DEFAULT now(),
"update_time" timestamp(6) DEFAULT now()
)
;
ALTER TABLE "public"."tbl_website" OWNER TO "postgres";
COMMENT ON COLUMN "public"."tbl_website"."id" IS '主键';
COMMENT ON COLUMN "public"."tbl_website"."key" IS '网站key';
COMMENT ON COLUMN "public"."tbl_website"."website_name" IS '网站名称';
COMMENT ON COLUMN "public"."tbl_website"."website_url" IS '网站链接';
COMMENT ON COLUMN "public"."tbl_website"."icon_url" IS '网站图标';
COMMENT ON COLUMN "public"."tbl_website"."is_main" IS '当前系统标志';
COMMENT ON COLUMN "public"."tbl_website"."create_time" IS '创建时间';
COMMENT ON COLUMN "public"."tbl_website"."update_time" IS '更新时间';
COMMENT ON TABLE "public"."tbl_website" IS '站点信息';
-- ----------------------------
-- Table structure for tbl_website_access_record
-- ----------------------------
DROP TABLE IF EXISTS "public"."tbl_website_access_record";
CREATE TABLE "public"."tbl_website_access_record" (
"id" int8 NOT NULL DEFAULT nextval('tbl_website_access_record_id_seq'::regclass),
"website_key" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,
"url" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,
"visitor_uid" int4 NOT NULL,
"visitor_name" varchar(255) COLLATE "pg_catalog"."default",
"ip" varchar(255) COLLATE "pg_catalog"."default",
"error_msg" text COLLATE "pg_catalog"."default",
"type" int2 NOT NULL,
"create_time" timestamp(6) DEFAULT now(),
"update_time" timestamp(6) DEFAULT now()
)
;
ALTER TABLE "public"."tbl_website_access_record" OWNER TO "postgres";
COMMENT ON COLUMN "public"."tbl_website_access_record"."id" IS '主键';
COMMENT ON COLUMN "public"."tbl_website_access_record"."website_key" IS '网站key';
COMMENT ON COLUMN "public"."tbl_website_access_record"."url" IS '访问界面地址';
COMMENT ON COLUMN "public"."tbl_website_access_record"."visitor_uid" IS '访问者ID';
COMMENT ON COLUMN "public"."tbl_website_access_record"."visitor_name" IS '访问者用户名';
COMMENT ON COLUMN "public"."tbl_website_access_record"."ip" IS 'IP地址';
COMMENT ON COLUMN "public"."tbl_website_access_record"."error_msg" IS '错误信息';
COMMENT ON COLUMN "public"."tbl_website_access_record"."type" IS '类型 0-pv/uv、1-错误信息';
COMMENT ON COLUMN "public"."tbl_website_access_record"."create_time" IS '创建时间';
COMMENT ON COLUMN "public"."tbl_website_access_record"."update_time" IS '更新时间';
COMMENT ON TABLE "public"."tbl_website_access_record" IS '站点访问记录';
-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
ALTER SEQUENCE "public"."tbl_sys_log_id_seq"
OWNED BY "public"."tbl_sys_log"."id";
SELECT setval('"public"."tbl_sys_log_id_seq"', 100, true);
-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
ALTER SEQUENCE "public"."tbl_website_access_record_id_seq"
OWNED BY "public"."tbl_website_access_record"."id";
SELECT setval('"public"."tbl_website_access_record_id_seq"', 3755, true);
-- ----------------------------
-- Alter sequences owned by
-- ----------------------------
ALTER SEQUENCE "public"."tbl_website_id_seq"
OWNED BY "public"."tbl_website"."id";
SELECT setval('"public"."tbl_website_id_seq"', 3, true);
-- ----------------------------
-- Primary Key structure for table tbl_sys_log
-- ----------------------------
ALTER TABLE "public"."tbl_sys_log" ADD CONSTRAINT "tbl_sys_log_pkey" PRIMARY KEY ("id");
-- ----------------------------
-- Primary Key structure for table tbl_website
-- ----------------------------
ALTER TABLE "public"."tbl_website" ADD CONSTRAINT "tbl_website_pkey" PRIMARY KEY ("id");
-- ----------------------------
-- Primary Key structure for table tbl_website_access_record
-- ----------------------------
ALTER TABLE "public"."tbl_website_access_record" ADD CONSTRAINT "tbl_website_access_record_pkey" PRIMARY KEY ("id");

View File

@@ -0,0 +1,191 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL如果设置为WARN则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时配置文档如果发生改变将会被重新加载默认值为true -->
<!-- scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。
当scan为true时此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时将打印出logback内部日志信息实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="10 seconds">
<contextName>logback</contextName>
<!-- name的值是变量的名称value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义后可以使“${}”来使用变量。 -->
<property name="log.path" value="logs/cvbp-monitor/" />
<!--0. 日志格式和颜色渲染 -->
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!--1. 输出到控制台-->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!--此日志appender是为开发使用只配置最底级别控制台输出的日志级别是大于或等于此级别的日志信息-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debug</level>
</filter>
<encoder>
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
<!-- 设置字符集 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!--2. 输出到文档-->
<!-- 2.1 level为 DEBUG 日志,时间滚动输出 -->
<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文档的路径及文档名 -->
<file>${log.path}/log_debug.log</file>
<!--日志文档输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志归档 -->
<fileNamePattern>${log.path}/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文档保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文档只记录debug级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>debug</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 2.2 level为 INFO 日志,时间滚动输出 -->
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文档的路径及文档名 -->
<file>${log.path}/log_info.log</file>
<!--日志文档输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 每天日志归档路径以及格式 -->
<fileNamePattern>${log.path}/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文档保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文档只记录info级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>info</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 2.3 level为 WARN 日志,时间滚动输出 -->
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文档的路径及文档名 -->
<file>${log.path}/log_warn.log</file>
<!--日志文档输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文档保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文档只记录warn级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>warn</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 2.4 level为 ERROR 日志,时间滚动输出 -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 正在记录的日志文档的路径及文档名 -->
<file>${log.path}/log_error.log</file>
<!--日志文档输出格式-->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文档保留天数-->
<maxHistory>15</maxHistory>
</rollingPolicy>
<!-- 此日志文档只记录ERROR级别的 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!--
<logger>用来设置某一个包或者具体的某一个类的日志打印级别、
以及指定<appender>。<logger>仅有一个name属性
一个可选的level和一个可选的addtivity属性。
name:用来指定受此logger约束的某一个包或者具体的某一个类。
level:用来设置打印级别大小写无关TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
还有一个特俗值INHERITED或者同义词NULL代表强制执行上级的级别。
如果未设置此属性那么当前logger将会继承上级的级别。
addtivity:是否向上级logger传递打印信息。默认是true。
<logger name="org.springframework.web" level="info"/>
<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>
-->
<!--
使用mybatis的时候sql语句是debug下才会打印而这里我们只配置了info所以想要查看sql语句的话有以下两种操作
第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql不过这样日志那边会出现很多其他消息
第二种就是单独给dao下目录配置debug模式代码如下这样配置sql语句会打印其他还是正常info级别
【logging.level.org.mybatis=debug logging.level.dao=debug】
-->
<!--
root节点是必选节点用来指定最基础的日志输出级别只有一个level属性
level:用来设置打印级别大小写无关TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
不能设置为INHERITED或者同义词NULL。默认是DEBUG
可以包含零个或多个元素标识这个appender将会添加到这个logger。
-->
<!-- 4. 最终的策略 -->
<!-- 4.1 开发环境:打印控制台-->
<logger name="com.codvision" level="debug"/>
<root level="debug">
<appender-ref ref="CONSOLE" />
<appender-ref ref="DEBUG_FILE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="WARN_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
<!-- 4.2 生产环境:输出到文档
<springProfile name="prd">
<root level="info">
<appender-ref ref="CONSOLE" />
<appender-ref ref="DEBUG_FILE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="ERROR_FILE" />
<appender-ref ref="WARN_FILE" />
</root>
</springProfile> -->
</configuration>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.codvision.monitor.mapper.SysLogMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.codvision.monitor.entity.SysLog">
<id column="id" property="id" />
<result column="type" property="type" />
<result column="operator" property="operator" />
<result column="operator_uid" property="operatorUid" />
<result column="content" property="content" />
<result column="method" property="method" />
<result column="create_time" property="createTime" />
<result column="ip" property="ip" />
<result column="params" property="params" />
</resultMap>
</mapper>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.codvision.monitor.mapper.WebsiteAccessRecordMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.codvision.monitor.entity.WebsiteAccessRecord">
<id column="id" property="id" />
<result column="website_key" property="websiteKey" />
<result column="url" property="url" />
<result column="visitor_uid" property="visitorUid" />
<result column="visitor_name" property="visitorName" />
<result column="ip" property="ip" />
<result column="error_msg" property="errorMsg" />
<result column="type" property="type" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
</resultMap>
<select id="getPvCountList" resultType="com.codvision.monitor.entity.vo.WebsiteAccessRecordVO">
SELECT
day,
(SELECT COUNT(1) FROM tbl_website_access_record WHERE type = 0 AND website_key = #{websiteKey} AND create_time::date = s.day) pvNum
FROM (SELECT GENERATE_SERIES(#{startTime}::date, #{endTime}, '1 days')::date as day) s
</select>
<select id="getUvCountList" resultType="com.codvision.monitor.entity.vo.WebsiteAccessRecordVO">
SELECT
day,
(SELECT COUNT(DISTINCT visitor_uid) FROM tbl_website_access_record WHERE type = 0 AND website_key = #{websiteKey} AND create_time::date = s.day) uvNum
FROM (SELECT GENERATE_SERIES(#{startTime}::date, #{endTime}, '1 days')::date as day) s
</select>
</mapper>

View File

@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.codvision.monitor.mapper.WebsiteMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.codvision.monitor.entity.Website">
<id column="id" property="id" />
<result column="key" property="key" />
<result column="website_name" property="websiteName" />
<result column="website_url" property="websiteUrl" />
<result column="icon_url" property="iconUrl" />
<result column="is_main" property="isMain" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
</resultMap>
<select id="findAll" resultType="com.codvision.monitor.entity.vo.WebsiteVO">
WITH today_data as (SELECT * FROM tbl_website_access_record WHERE type = 0 AND to_char(create_time, 'yyyy-MM-dd') = to_char(now(), 'yyyy-MM-dd')),
yesterday_data as (SELECT * FROM tbl_website_access_record WHERE type = 0 AND to_char(create_time, 'yyyy-MM-dd') = to_char(now() - INTERVAL '1 day', 'yyyy-MM-dd'))
SELECT
DISTINCT w.id, w.*,
(SELECT COUNT(1) FROM today_data t WHERE w.key = t.website_key) todayPvNum,
(SELECT COUNT(DISTINCT visitor_uid) FROM today_data t WHERE w.key = t.website_key) todayUvNum,
(SELECT COUNT(DISTINCT ip) FROM today_data t WHERE w.key = t.website_key) todayIpNum,
(SELECT COUNT(1) FROM yesterday_data y WHERE w.key = y.website_key) yesterdayPvNum,
(SELECT COUNT(DISTINCT visitor_uid) FROM yesterday_data y WHERE w.key = y.website_key) yesterdayUvNum,
(SELECT COUNT(DISTINCT ip) FROM yesterday_data y WHERE w.key = y.website_key) yesterdayIpNum
FROM tbl_website w
<where>
<if test="websiteName != null and websiteName != ''">
w.website_name like '%' || #{websiteName} || '%'
</if>
<if test="websiteKey != null and websiteKey != ''">
w.key = #{websiteKey}
</if>
</where>
ORDER BY w.create_time DESC
</select>
</mapper>