springcloud日志管理--为新服务添加日志管理
傻瓜式为springcloud服务添加日志管理,按步骤执行即可。
参考链接:
https://www.jianshu.com/p/213827ebc08c
https://www.cnblogs.com/ityouknow/p/6120544.html
https://blog.****.net/fanduo12345/article/details/54626802
->整体逻辑(反向开发)
preprocess-service: 请求->PreprocessController->SysLoggerAspect->LoggerService->RabbitConfig->发送封装好的消息到消息队列;
log-service: 接收消息队列中的消息->RabbitConfig->Receiver->PreproLogService->PreproRecoveryDAO->将消息对象写入数据库;
->准备工作
1.将springcloud代码拷贝到idea工作区,修改log-service-dev.yml与preprocess-service-dev.yml的数据库url、name、password,修改为你本地mysql对应信息即可。修改完成后上传至YTKJCloudService_Config远程git仓(这个不是YTKJCloudService代码仓)。
2.可尝试将log-service与preprocess-service跑起来测试看一下效果,添加新的service日志服务时对应修改即可,本文以给preprocess-service服务添加日志管理为例。测试代码如下(url,resp等地方需要自行修改):
import requests
import json
def Analyze(text):
# 构建请求头
header = {}
header['Content-Type'] = 'application/json'
header['Accept'] = 'application/json'
# 请求服务地址
url = 'http://localhost:8766/preprocess/recovery'
# 发起post请求
resp = requests.post(url, headers=header, verify=False, json={'rawText':text})
# 设置响应体编码
resp.encoding = 'utf-8'
print("resp.status_code:", resp.status_code)
if resp and resp.status_code == 200:
return json.loads(resp.text)
return None
#返回的数据,格式是list
if __name__ == '__main__':
result=Analyze("我看了书")
print(result)
->preprocess-service服务
1.在entry包中创建PreproRecoveryLog.java实体类,各属性与数据库表结构对应一致,并生产get、set方法。
2.在web包下PreprocessController中的recovery接口上添加SysLogger注解;
3.在aop包(如果没有则创建,下面同理)下添加SysLoggerAspect.java文件,接着在此文件中创建日志信息对象并赋值;
public class SysLoggerAspect {
@Autowired
private LoggerService loggerService;
@Pointcut("@annotation(com.ytkj.common.annotation.SysLogger)")
public void loggerPointCut() {
}
@Before("loggerPointCut()")
public void saveSysLog(JoinPoint joinPoint) {
PreproRecoveryLog preproRecoveryLog = new PreproRecoveryLog();
//设置日志各字段信息
preproRecoveryLog.setXXX();
//保存系统日志
System.out.println("********aop out success*********");
loggerService.log(preproRecoveryLog);
}
}
4.在config包下创建RabbitConfig.java文件,定义消息队列名称等消息并绑定该队列;(如果多个日志信息,则在RabbitConfig中定义多个消息队列,内容格式如***意@bean的方法名)
@Configuration
public class RabbitConfig {
public final static String queueNamePrepro = "spring-boot-preprocess";
@Bean
Queue queue() {
return new Queue(queueNamePrepro, false);
}
@Bean
TopicExchange exchange() {
return new TopicExchange("spring-boot-exchange-preprocess");
}
@Bean
Binding binding(Queue queue, TopicExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with(queueNamePrepro);
}
}
5.在service包下创建LoggerService.java文件,定义方法将封装的日志信息发送到指定消息队列;
@Service
public class LoggerService {
@Autowired
private AmqpTemplate rabbitTemplate;
public void log(PreproRecoveryLog preproRecoveryLog){
rabbitTemplate.convertAndSend(RabbitConfig.queueNamePrepro, JSON.toJSONString(preproRecoveryLog));
}
}
->log-service服务
1.在entry包下创建PreproRecoveryLog.java文件,各属性与数据库表结构对应一致,注意:该文件名对应数据库中表名,对应规则为:
文件名:PreproRecoveryLog
表名:prepro_recovery_log
2.在config包下创建RabbitConfig.java文件,当多个service或者接口调用信息需要写到数据库时,则应该建立多个消息队列。多消息队列创建、绑定、添加监听、处理方法如下:
@Configuration
public class RabbitConfig {
//新的消息队列按如下方式进行创建、绑定、监听、处理
public final static String queueName = "spring-boot";
public final static String queueNamePrepro = "spring-boot-preprocess";
@Bean
Queue queue() {
return new Queue(queueName, false);
}
@Bean
Queue queuePrepro() {
return new Queue(queueNamePrepro, false);
}
@Bean
TopicExchange exchange() {
return new TopicExchange("spring-boot-exchange");
}
@Bean
TopicExchange exchangePrepro() {
return new TopicExchange("spring-boot-exchange-preprocess");
}
@Bean
Binding binding(Queue queue, TopicExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with(queueName);
}
@Bean
Binding bindingPrepro(Queue queuePrepro, TopicExchange exchangePrepro) {
return BindingBuilder.bind(queuePrepro).to(exchangePrepro).with(queueNamePrepro);
}
@Bean
SimpleMessageListenerContainer container(ConnectionFactory connectionFactory, Receiver receiver) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
//新的服务监听将对应的队列名加入setQueueNames方法
container.setQueueNames(queueName, queueNamePrepro);
//新的服务处理将对应的队列处理方法加入下方处理中
container.setMessageListener((MessageListener) message -> {
if (queueName.equals(message.getMessageProperties().getConsumerQueue())){
receiver.receiveMessage(new String(message.getBody()));
} else if (queueNamePrepro.equals(message.getMessageProperties().getConsumerQueue())){
receiver.receivePreMessage(new String(message.getBody()));
}
});
return container;
}
3.在rabbit包下的Receiver.java文件下定义消息接收的方法,并自动装配preproLogService对接收到的消息进行处理:
@Component
public class Receiver {
private CountDownLatch latch = new CountDownLatch(1);
@Autowired
SysLogService sysLogService;
@Autowired
PreproLogService preproLogService;
public void receiveMessage(String message) {
System.out.println("Received <" + message + ">");
SysLog sysLog = JSON.parseObject(message,SysLog.class);
sysLogService.saveLogger(sysLog);
latch.countDown();
}
public void receivePreMessage(String message) {
System.out.println("Received Preprocess <" + message + ">");
PreproRecoveryLog preproRecoveryLog = JSON.parseObject(message, PreproRecoveryLog.class);
preproLogService.savePreproRecoveryLogger(preproRecoveryLog);
latch.countDown();
}
}
4.在service包中创建PreproLogService.java文件,调用DAO层方法将消息对象写入数据库:
@Service
public class PreproLogService {
@Autowired
PreproRecoveryDAO preproRecoveryDAO;
public void savePreproRecoveryLogger(PreproRecoveryLog preproRecoveryLog){
preproRecoveryDAO.save(preproRecoveryLog);
}
}
5.在dao包中创建PreroRecoveryDAO.java文件并定义DAO方法继承自JpaRepository,实现底层对数据库的操作:
public interface PreproRecoveryDAO extends JpaRepository<PreproRecoveryLog, Long> {
}
至此,preprocess-service的日志管理功能已完成,可尝试上述提到的测试方法进行测试。
注:
当某个表的日志需要修改时,首先修改数据库表结构,接着参照表结构修改preprocess-servce与log-service中的实体类,然后在preprocess-servce的aop包中的SysLoggerAspect给添加的字段进行赋值操作。即可。