Logstash+ Kafka基于AOP 实时同步日志到es
Logstash是一个开源数据收集引擎,具有实时管道功能。Logstash可以动态地将来自不同数据源的数据统一起来,并将数据标准化到你所选择的目的地,logstash丰富的插件(logstash-input-jdbc,logstash-input-kafka,logstash-input-rabbitmq,logstash-input-flie,logstash-input-syslog等,github地址: https://github.com/logstash-plugins)
1.logstash-input-kafka将微服务日志同步到 elasticsearch
1.1 基于AOP+Kafka同步数据原理
原理其实很简单,就是基于JAVA的AOP技术拦截方法收集请求日志和异常日志发送到Kafka,然后通过logstash订阅相应的topic来消费消息(即发布订阅模式)output到es来实现日志收集
1.2 日志收集配置文件
szhuangl_goods_log.conf
input {
kafka {
#kafaka服务地址
bootstrap_servers => "server.natappfree.cc:33402"
topics => ["szhuangl_goods_log"]
}
}
output {
stdout { codec => rubydebug }
elasticsearch {
#es服务地址
hosts => ["127.0.0.1:9200"]
index => "szhuangl_goods_log"
}
}
Kafka消息提供者代码
package com.szhuangl.basic.elk.kafka; import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.SendResult;
import org.springframework.stereotype.Component;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback; /**
* @program: szhunagl-shop-parent
* @author: Brian Huang
* @create: 2019-10-19 16
**/
@Component
@Slf4j
public class KafkaSender<T> { @Value("${szhuangl.log.topic: szhuangl_log}")
private String log_topic; @Autowired
private KafkaTemplate<String, Object> kafkaTemplate; /**
* kafka 发送消息
*
* @param obj
* 消息对象
*/ public void send(T obj) {
String jsonObj = JSON.toJSONString(obj); // 发送消息
ListenableFuture<SendResult<String, Object>> future = kafkaTemplate.send(log_topic, jsonObj);
future.addCallback(new ListenableFutureCallback<SendResult<String, Object>>() { @Override
public void onFailure(Throwable throwable) {
log.info("Produce: The message failed to be sent:" + throwable.getMessage());
} @Override
public void onSuccess(SendResult<String, Object> stringObjectSendResult) {
// TODO 业务处理
log.info("Produce: The message was sent successfully:");
log.info("Produce: >>>>>>>>>>>>>>>>>>> result: " + stringObjectSendResult.toString());
}
});
}
}
AOP切面收集日志代码
package com.szhuangl.basic.elk.aop; import com.alibaba.fastjson.JSONObject;
import com.szhuangl.basic.elk.kafka.KafkaSender;
import com.szhuangl.common.web.util.IpUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays; /**
* @program: kafka日志收集切面类
* @author: Brian Huang
* @create: 2019-10-19 16
**/
@Aspect
@Component
@Slf4j
public class AopLogAspect { @Autowired
private KafkaSender<JSONObject> kafkaSender; // 申明一个切点 里面是 execution表达式
@Pointcut("execution(* com.szhuangl.impl.*.service.*.*(..))")
private void serviceAspect() {
} // 请求method前打印内容
@Before(value = "serviceAspect()")
public void methodBefore(JoinPoint joinPoint) {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest(); String ip = IpUtils.getIpAddress(request);
int localPort = request.getLocalPort();
log.info("---localPort---:" + localPort);
int serverPort = request.getServerPort();
log.info("---serverPort---:" + serverPort);
int remotePort = request.getRemotePort();
log.info("---remotePort---:" + remotePort);
JSONObject jsonObject = new JSONObject(); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); jsonObject.put("request_time", LocalDateTime.now().format(dateTimeFormatter));
jsonObject.put("request_ip_port", ip);
jsonObject.put("request_url", request.getRequestURL().toString());
jsonObject.put("request_method", request.getMethod());
jsonObject.put("signature", joinPoint.getSignature());
jsonObject.put("request_args", Arrays.toString(joinPoint.getArgs()));
JSONObject requestJsonObject = new JSONObject();
requestJsonObject.put("szhuangl_request", jsonObject);
kafkaSender.send(requestJsonObject);
} // 在方法执行完结后打印返回内容
@AfterReturning(returning = "o", pointcut = "serviceAspect()")
public void methodAfterReturing(Object o) {
JSONObject respJSONObject = new JSONObject();
JSONObject jsonObject = new JSONObject();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
jsonObject.put("response_time", LocalDateTime.now().format(dateTimeFormatter));
jsonObject.put("response_content", JSONObject.toJSONString(o));
respJSONObject.put("szhuangl_response", jsonObject);
kafkaSender.send(respJSONObject);
}
}
异常日志收集代码
package com.szhuangl.basic.elk.aop.error; import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import com.szhuangl.basic.elk.kafka.KafkaSender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest; /**
*
* @description: 全局捕获异常
*/
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler { @Autowired
private KafkaSender<JSONObject> kafkaSender; @ExceptionHandler(RuntimeException.class)
@ResponseBody
public JSONObject exceptionHandler(Exception e) {
log.info("<<<<<<<<<<<<<<<全局捕获异常>>>>>>>>>>>>>>>>>,error:{}", e);
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest(); // 1.封装异常日志信息
JSONObject errorJson = new JSONObject();
JSONObject logJson = new JSONObject();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
logJson.put("request_time", LocalDateTime.now().format(dateTimeFormatter));
logJson.put("error_info", e);
errorJson.put("szhuangl_request_error", logJson);
kafkaSender.send(errorJson);
// 2. 返回错误信息
JSONObject result = new JSONObject();
result.put("code", 500);
result.put("msg", "系统错误");
return result;
}
}
application.yml kafka配置信息
###服务端口
server:
port: 8700
###eurake
eureka:
client:
service-url:
defaultZone: http://localhost:8100/eureka
spring:
application:
name: szhuangl-server-goods
data:
elasticsearch:
cluster-name: szhuangl_es
cluster-nodes: j1ekxg71oe.52http.tech:51267
repositories:
enable: true
kafka:
#kafka配置信息
bootstrap-servers: server.natappfree.cc:33402 #配置kafka的־topic
szhuangl:
log:
topic: szhuangl_goods_log
Logstash+ Kafka基于AOP 实时同步日志到es的更多相关文章
- spring+mybatis基于 AOP实现业务日志管理
最近在项目上用到了操作日志的相关,之前的解决方案就是自己写一个日志project,然后统一调用日志接口即可,这样方便自定义定制,因为有很多设备控制之类的都是需要确认一下的,但是,对数据的操作,比如,增 ...
- 微服务日志监控与查询logstash + kafka + elasticsearch
使用 logstash + kafka + elasticsearch 实现日志监控 https://blog.csdn.net/github_39939645/article/details/788 ...
- mysql数据实时同步到Elasticsearch
业务需要把mysql的数据实时同步到ES,实现低延迟的检索到ES中的数据或者进行其它数据分析处理.本文给出以同步mysql binlog的方式实时同步数据到ES的思路, 实践并验证该方式的可行性,以供 ...
- lsyncd替代inotify+rsync实现实时同步
因公司业务需要需要实时同步日志文件,刚一开始使用的是inotify+rsync来实现实时同步,但时间久而久之发现同步的速度越来越慢,往往延迟好几个小时.查了一下网上的inotify+rsync方案基本 ...
- 基于Canal和Kafka实现MySQL的Binlog近实时同步
前提 近段时间,业务系统架构基本完备,数据层面的建设比较薄弱,因为笔者目前工作重心在于搭建一个小型的数据平台.优先级比较高的一个任务就是需要近实时同步业务系统的数据(包括保存.更新或者软删除)到一个另 ...
- 基于Flume+Kafka+ Elasticsearch+Storm的海量日志实时分析平台(转)
0背景介绍 随着机器个数的增加.各种服务.各种组件的扩容.开发人员的递增,日志的运维问题是日渐尖锐.通常,日志都是存储在服务运行的本地机器上,使用脚本来管理,一般非压缩日志保留最近三天,压缩保留最近1 ...
- 基于OGG的Oracle与Hadoop集群准实时同步介绍
版权声明:本文由王亮原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/220 来源:腾云阁 https://www.qclou ...
- 和我一起打造个简单搜索之Logstash实时同步建立索引
用过 Solr 的朋友都知道,Solr 可以直接在配置文件中配置数据库连接从而完成索引的同步创建,但是 ElasticSearch 本身并不具备这样的功能,那如何建立索引呢?方法其实很多,可以使用 J ...
- sersync基于rsync+inotify实现数据实时同步
一.环境描述 需求:服务器A与服务器B为主备服务模式,需要保持文件一致性,现采用sersync基于rsync+inotify实现数据实时同步 主服务器A:192.168.1.23 从服务器B:192. ...
随机推荐
- idea常用设置汇总
https://www.cnblogs.com/wangmingshun/p/6427088.html
- linux /lib64/libc.so.6: version `GLIBC_2.17′ not found
使用root权限安装Glances,需要用到glibc,安装失败后所有命令都不好用了,执行回报“/lib64/libc.so.6: version `GLIBC_2.17′ not found ”的错 ...
- CDN工作机制
CDN(content delivery network),即内容分布网络,是一种构建在现有Internet上的一种先进的流量分配网络.CDN以缓存网站中的静态数据为主,当用户请求动态内容时,先从CD ...
- python3 爬虫继续爬笔趣阁 ,,,,,,,
学如逆水行舟,不进则退 今天想看小说..找了半天,没有资源.. 只能自己爬了 想了半天.,,,忘记了这个古老的技能 捡了一下 import requests from bs4 import Beaut ...
- Mysql 随机查询10条数据效率最快的查询方法
1)使用join 和 rand() 耗时 0.009 SELECT * FROM `t_topic` AS t1 JOIN ( SELECT ROUND( RAND() * ( (SELECT MAX ...
- 洛谷 P1432 倒水问题
目录 题目 思路 \(Code\) 题目 戳 思路 \(bfs\) 第一遍提交\(50\),第二遍就\(100\)了,qwq \(Code\) #include<iostream> #in ...
- nRF51822 硬件复位引脚
nRF51822 有一个硬件复位引脚和Debug 口SWDIO是共用的,名字叫做nReset. 实现硬件复位是怎样子的: 1.这个引脚引出来, 2.给这个引脚低电平, 3.从低电平拉到高电平,即复位. ...
- 京东Java架构师讲解购物车的原理及Java实现
今天来写一下关于购物车的东西, 这里首先抛出四个问题: 1)用户没登陆用户名和密码,添加商品, 关闭浏览器再打开后 不登录用户名和密码问:购物车商品还在吗? 2)用户登陆了用户名密码,添加商品,关闭浏 ...
- OpenFOAM——同心环中的自然对流
本算例来自<ANSYS Fluid Dynamics Verification Manual>中的VMFL009: Natural Convection in a Concentric A ...
- 菜鸟教程C++(一)
一.C++基本语法 C++程序可以定义为对象的集合,这些对象可以通过调用彼此的方法进行交互. 对象:对象具有状态和行为.例如:一只狗的状态:颜色.名称.品种等,行为:摇动.叫唤等.对象是类的实例. 类 ...