pom
4.0.0
org.springframework.boot
spring-boot-starter-parent
1.5.22.RELEASE
com.example
xxjob-actouor
0.0.1-SNAPSHOT
xxjob-actouor
xxjob-actouor
1.8
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-aop
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-devtools
runtime
true
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-actuator
1.5.22.RELEASE
org.springframework.boot
spring-boot-maven-plugin
org.projectlombok
lombok
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
spring-snapshots
Spring Snapshots
https://repo.spring.io/snapshot
false
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
spring-snapshots
Spring Snapshots
https://repo.spring.io/snapshot
false
yml
server.port=9000
# 控制是否打印日志 false 不打印日志 true 打印日志
health.flag=true
# 日志策类配置 default 默认日志类 caChe 添加缓存的日志类
health.strategy=default
# 健康检查结果缓存超时时间,只有 health.strategy=caChe 这项配置才有意义
health.timeOut=10
code
Strategy
HealthLogsSuper
package com.example.xxjobactouor.Strategy;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* @Description 健康检查日志策略父类
* @ClassName HealthSuper
* @Author 康世行
* @Date 21:23 2023/6/7
* @Version 1.0
**/
public abstract class HealthLogsSuper {
//获取健康检查结果
public abstract Object getHealthLogs( ProceedingJoinPoint joinPoint );
}
DefaultHealthLogs
package com.example.xxjobactouor.Strategy;
import com.example.xxjobactouor.Strategy.common.HealthCommonPrint;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @Description 默认日志策略-控制日志是否打印
* @ClassName DefaultHealth
* @Author 康世行
* @Date 21:34 2023/6/7
* @Version 1.0
**/
@Service
@Slf4j
public class DefaultHealthLogs extends HealthLogsSuper {
@Autowired
private HealthCommonPrint healthPrintLogs;
@Override
public Object getHealthLogs(ProceedingJoinPoint joinPoint) {
Object proceed=null;
//目标类
Object target = joinPoint.getTarget();
//接口请求开始时间
long start=System.currentTimeMillis();
try {
//进入类之前打印日志
healthPrintLogs.printPreHealthLogs(target);
proceed=joinPoint.proceed();
//进入类之后的日志
healthPrintLogs.printAftHealthLogs(target,start);
} catch (Throwable e) {
throw new RuntimeException(e);
}
return proceed;
}
}
CacheHealthLogs
package com.example.xxjobactouor.Strategy;
import com.example.xxjobactouor.Strategy.common.CacheHealth;
import com.example.xxjobactouor.Strategy.common.HealthCommonPrint;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
/**
* @Description 对结果进行缓存的日志策略
* @ClassName LogsAndCacheHealth
* @Author 康世行
* @Date 21:38 2023/6/7
* @Version 1.0
**/
@Service
@Slf4j
public class CacheHealthLogs extends HealthLogsSuper {
@Autowired
private CacheHealth cacheHealth;
@Value("${health.timeOut:5}")
private long timeOut;
//缓存key
private final static String cacheKey="healthInfo";
//打印日志
@Autowired
private HealthCommonPrint healthPrintLogs;
@Override
public Object getHealthLogs(ProceedingJoinPoint joinPoint) {
Object proceed=null;
//目标类
Object target = joinPoint.getTarget();
//接口请求开始时间
long start=System.currentTimeMillis();
try {
//进入类之前打印日志
healthPrintLogs.printPreHealthLogs(target);
//从缓存获取健康检查信息
proceed= cacheHealth.get(cacheKey);
if (proceed==null){
//再次获取健康检查的信息并保存到缓存,用于下次使用提高接口查询效率
proceed=joinPoint.proceed();
cacheHealth.put(cacheKey,proceed,timeOut, TimeUnit.SECONDS);
}
//进入类之后的日志
healthPrintLogs.printAftHealthLogs(target,start);
} catch (Throwable e) {
throw new RuntimeException(e);
}
return proceed;
}
}
HealthLogsContext
package com.example.xxjobactouor.Strategy;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @Description
* 健康检查日志策略上下文类-用于维护 具体使用的那个策略对象 结合简单工厂使用
* @ClassName HealthLogsContext
* @Author 康世行
* @Date 21:46 2023/6/7
* @Version 1.0
**/
@Service
public class HealthLogsContext {
HealthLogsSuper logsSuper;
@Autowired
private DefaultHealthLogs defaultHealthLogs;
@Autowired
private CacheHealthLogs cacheHealthlogs;
//设置具体策略
public void setStrategy(String strategy){
switch (strategy){
case "default":
logsSuper=defaultHealthLogs;
break;
case "caChe":
logsSuper=cacheHealthlogs;
break;
}
}
//执行具体策略
public Object getResult(ProceedingJoinPoint joinPoint ){
Object healthLogs = logsSuper.getHealthLogs(joinPoint);
return healthLogs;
}
}
HealthLogs
package com.example.xxjobactouor;
import com.example.xxjobactouor.Strategy.HealthLogsContext;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
* @Description 记录监控检查-日志
* @ClassName HealthLogs
* @Author 康世行
* @Date 20:15 2023/6/7
* @Version 1.0
**/
@Aspect
@Component
@Slf4j
public class HealthLogs {
@Pointcut("execution(public * com.example.xxjobactouor.Healthimpl.health())")
public void logs(){};
@Autowired
private HealthLogsContext context;
@Value("${health.strategy:default}")
private String strategy;
@Around("logs()")
public Object log(ProceedingJoinPoint joinPoint){
Object proceed=null;
//设置使用那个日志策略
context.setStrategy(strategy);
// 获取健康检查返回值
proceed= context.getResult(joinPoint);
return proceed;
}
}
common
CacheHealth
package com.example.xxjobactouor.Strategy.common;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* @Description TODO
* @ClassName CacheHealth
* @Author 康世行
* @Date 20:50 2023/6/7
* @Version 1.0
**/
@Component
public class CacheHealth {
private final Map cacheHealth=new ConcurrentHashMap<>();
public void put(String key, Object value, long ttl, TimeUnit timeUnit) {
cacheHealth.put(key, value);
Executors.newSingleThreadScheduledExecutor().schedule(() -> cacheHealth.remove(key,value), ttl, timeUnit);
}
public Object get(String key) {
return cacheHealth.get(key);
}
}
HealthCommonPrint
package com.example.xxjobactouor.Strategy.common;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
* @Description 日志打印类-所有日志策略公共类
* @ClassName HealthPrintLogs
* @Author 康世行
* @Date 22:30 2023/6/7
* @Version 1.0
**/
@Service
@Slf4j
public class HealthCommonPrint {
@Value("${health.flag:false}")
private boolean flag;
//打印执行前健康检查日志
public void printPreHealthLogs(Object joinPoint) {
if (flag){
log.info("进入"+joinPoint.getClass().getName()+"类之前");
}
}
//打印执行后健康检查日志
public void printAftHealthLogs(Object joinPoint,long start) {
if (flag){
log.info("进入"+joinPoint.getClass().getName()+"类之后");
}
if (flag){
long end=System.currentTimeMillis()-start;
log.info("耗时"+end);
}
}
}