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的更多相关文章

  1. spring+mybatis基于 AOP实现业务日志管理

    最近在项目上用到了操作日志的相关,之前的解决方案就是自己写一个日志project,然后统一调用日志接口即可,这样方便自定义定制,因为有很多设备控制之类的都是需要确认一下的,但是,对数据的操作,比如,增 ...

  2. 微服务日志监控与查询logstash + kafka + elasticsearch

    使用 logstash + kafka + elasticsearch 实现日志监控 https://blog.csdn.net/github_39939645/article/details/788 ...

  3. mysql数据实时同步到Elasticsearch

    业务需要把mysql的数据实时同步到ES,实现低延迟的检索到ES中的数据或者进行其它数据分析处理.本文给出以同步mysql binlog的方式实时同步数据到ES的思路, 实践并验证该方式的可行性,以供 ...

  4. lsyncd替代inotify+rsync实现实时同步

    因公司业务需要需要实时同步日志文件,刚一开始使用的是inotify+rsync来实现实时同步,但时间久而久之发现同步的速度越来越慢,往往延迟好几个小时.查了一下网上的inotify+rsync方案基本 ...

  5. 基于Canal和Kafka实现MySQL的Binlog近实时同步

    前提 近段时间,业务系统架构基本完备,数据层面的建设比较薄弱,因为笔者目前工作重心在于搭建一个小型的数据平台.优先级比较高的一个任务就是需要近实时同步业务系统的数据(包括保存.更新或者软删除)到一个另 ...

  6. 基于Flume+Kafka+ Elasticsearch+Storm的海量日志实时分析平台(转)

    0背景介绍 随着机器个数的增加.各种服务.各种组件的扩容.开发人员的递增,日志的运维问题是日渐尖锐.通常,日志都是存储在服务运行的本地机器上,使用脚本来管理,一般非压缩日志保留最近三天,压缩保留最近1 ...

  7. 基于OGG的Oracle与Hadoop集群准实时同步介绍

    版权声明:本文由王亮原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/220 来源:腾云阁 https://www.qclou ...

  8. 和我一起打造个简单搜索之Logstash实时同步建立索引

    用过 Solr 的朋友都知道,Solr 可以直接在配置文件中配置数据库连接从而完成索引的同步创建,但是 ElasticSearch 本身并不具备这样的功能,那如何建立索引呢?方法其实很多,可以使用 J ...

  9. sersync基于rsync+inotify实现数据实时同步

    一.环境描述 需求:服务器A与服务器B为主备服务模式,需要保持文件一致性,现采用sersync基于rsync+inotify实现数据实时同步 主服务器A:192.168.1.23 从服务器B:192. ...

随机推荐

  1. hiveSQL常用日期函数

    注意 MM,DD,MO,TU 等要大写 Hive 可以在 where 条件中使用 case when 已知日期 要求日期 语句 结果 本周任意一天 本周一 select date_sub(next_d ...

  2. 解读 v8 排序源码

    前言 v8 是 Chrome 的 JavaScript 引擎,其中关于数组的排序完全采用了 JavaScript 实现. 排序采用的算法跟数组的长度有关,当数组长度小于等于 10 时,采用插入排序,大 ...

  3. django-购物车添加

    商品详情页detail.html添加加入购物车按钮 <a href="javascript:;" sku_id="{{ sku.id }}" class= ...

  4. spring boot+Quartz+数据库存储

    SpingBoot+Quartz+数据库存储 1.Spring整合Quartz 2.读取数据库中表达式启动定时任务1(每5s执行) 3.更改定时任务状态(启用/禁用),定时任务1停止 4.读取数据库中 ...

  5. 使用gitstats分析git 仓库代码

    gitstats 是一个很不错的git 代码提交分析工具,可以帮助我们生成图表统计结果 工具文档信息 gitstats http://gitstats.sourceforge.net/ 安装 使用ce ...

  6. cyyz: Day 4 网络流整理

    Day 4 网络流的理论性知识(算了..我自己都看不下去,还是整理些例题以后复习用吧qaq): 一.PPT(主要内容)   二.搜自度娘 定义: 年,L.R. 福特和 D.R. 富尔克森等人给出了解决 ...

  7. 洛谷 P1063 能量项链 题解

    P1063 能量项链 题目描述 在\(Mars\)星球上,每个\(Mars\)人都随身佩带着一串能量项链.在项链上有\(N\)颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并 ...

  8. cnetos6.5安装Varnish

    安装依赖包: tar -zxvf docutils-0.13.1.tar.gz python setup.py install unzip pcre2-10.23.zip ./configure -- ...

  9. linux服务器磁盘挂载

    1.先查看当前服务器挂载的磁盘个数 fdisk -l 2.将vdb磁盘挂载到/data目录下 mount /dev/vdb /data 3.df -h  检查磁盘挂载的情况

  10. Java_jdbc 基础笔记之六 数据库连接 (PreparedStatement)

    reparedStatement 是 Statement 的子接口 * ①需要预编译 SQL 语句:PreparedStatement ps = conn.preparedStatement(sql) ...