使用ELK堆栈进行日志聚合

1.简介

随着微服务的使用,创建稳定的分布式应用程序和摆脱许多遗留问题变得很容易。

但是微服务的使用也带来了一些挑战, 分布式日志管理就是其中之一。

由于微服务是隔离的,因此它们不共享数据库和日志文件,因此实时搜索,分析和查看日志数据变得充满挑战。

这就是ELK堆栈的救援之处。

2. ELK

它是三个开源产品的集合:

  • 弹性搜索是基于JSON的NoSQL数据库
  • Logstash一个日志管道工具,可从各种来源获取输入,执行不同的转换并将数据导出到各种目标(此处为弹性搜索)
  • Kibana是可视化层,可在弹性搜索之上

请参考下面给出的架构:



ELK堆栈

日志存储从微服务中获取日志。

提取的日志将转换为JSON并提供给弹性搜索。

开发人员可以使用Kibana查看弹性搜索中存在的日志。

3.安装ELK

ELK基于Java。

在安装ELK之前,必须确保已JAVA_HOMEPATH ,并且已使用JDK 1.8完成安装。

3.1 Elasticsearch

  • 可以从下载页面下载最新版本的Elasticsearch,并且可以将其提取到任何文件夹中
  • 可以使用bin\elasticsearch.bat从命令提示符处执行它
  • 默认情况下,它将从http:// localhost:9200开始

3.2基巴纳

  • 可以从下载页面下载最新版本的Kibana,并且可以将其提取到任何文件夹中
  • 可以使用bin\kibana.bat在命令提示符下执行它
  • 成功启动后,Kibana将在默认端口5601上启动,并且Kibana UI将位于http:// localhost:5601

3.3 Logstash

  • 可以从下载页面下载最新版本的Logstash,并将其解压缩到任何文件夹中
  • 根据配置说明创建一个文件cst_logstash.conf
  • 可以使用bin/logstash -f cst_logstash.conf从命令提示符处执行以启动logstash

4.创建一个示例微服务组件

创建微服务是必需的,以便logstash可以指向API日志。

下面的清单显示了示例微服务的代码。

pom.xml

<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"><modelVersion>4.0.0</modelVersion><groupId>com.xyz.app</groupId><artifactId>ArtDemo1001_Rest_Controller_Full_Deployment_Logging</artifactId><version>0.0.1-SNAPSHOT</version><!-- Add Spring repositories --><!-- (you don't need this if you are using a .RELEASE version) --><repositories><repository><id>spring-snapshots</id><url>http://repo.spring.io/snapshot</url><snapshots><enabled>true</enabled></snapshots></repository><repository><id>spring-milestones</id><url>http://repo.spring.io/milestone</url></repository></repositories><pluginRepositories><pluginRepository><id>spring-snapshots</id><url>http://repo.spring.io/snapshot</url></pluginRepository><pluginRepository><id>spring-milestones</id><url>http://repo.spring.io/milestone</url></pluginRepository></pluginRepositories><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.2.RELEASE</version></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><spring-cloud.version>Dalston.SR3</spring-cloud.version></properties><!-- Add typical dependencies for a web application --><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><!-- Package as an executable jar --><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement></project>

上面的pom.xml代码已配置了基于Spring Boot的项目所需的依赖项。

EmployeeDAO.java

package com.xyz.app.dao;import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;import org.springframework.stereotype.Repository;import com.xyz.app.model.Employee;@Repository
public class EmployeeDAO {/*** Map is used to Replace the Database * */static public Map<Integer,Employee> mapOfEmloyees = new LinkedHashMap<Integer,Employee>();static int count=10004;static{mapOfEmloyees.put(10001, new Employee("Jack",10001,12345.6,1001));mapOfEmloyees.put(10002, new Employee("Justin",10002,12355.6,1002));mapOfEmloyees.put(10003, new Employee("Eric",10003,12445.6,1003));}/*** Returns all the Existing Employees* */public Collection getAllEmployee(){return mapOfEmloyees.values();			}/**Get Employee details using EmployeeId .* Returns an Employee object response with Data if Employee is Found* Else returns a null* */public Employee getEmployeeDetailsById(int id){return mapOfEmloyees.get(id);}/**Create Employee details.* Returns auto-generated Id* */public Integer addEmployee(Employee employee){count++;employee.setEmployeeId(count);mapOfEmloyees.put(count, employee);return count;}/**Update the Employee details,* Receives the Employee Object and returns the updated Details  * */public Employee updateEmployee (Employee employee){mapOfEmloyees.put(employee.getEmployeeId(), employee);return employee;}/**Delete the Employee details,* Receives the EmployeeID and returns the deleted employee's Details  * */public Employee removeEmployee (int id){Employee emp= mapOfEmloyees.remove(id);return emp;}}

上面的代码表示应用程序的DAO层。

CRUD操作在包含Employee对象的Map集合上执行,以避免数据库依赖性并保持应用程序轻巧。

EmployeeController.java

package com.xyz.app.controller;import java.util.Collection;import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;import com.xyz.app.dao.EmployeeDAO;
import com.xyz.app.model.Employee;@RestController
public class EmployeeController {@Autowired private EmployeeDAO employeeDAO;public static Logger logger = Logger.getLogger(EmployeeController.class);/** Method is used to get all the employee details and return the same */ @RequestMapping(value="emp/controller/getDetails",method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_VALUE)public ResponseEntity<Collection> getEmployeeDetails(){logger.info("From Producer method[getEmployeeDetails] start");logger.debug("From Producer method[getEmployeeDetails] start");Collection  listEmployee =employeeDAO.getAllEmployee();logger.debug("From Producer method[getEmployeeDetails] start");logger.info("From Producer method[getEmployeeDetails] end");return new ResponseEntity<Collection>(listEmployee, HttpStatus.OK);}/** Method finds an employee using employeeId and returns the found Employee If no employee is not existing corresponding to the employeeId, then null is returned with HttpStatus.INTERNAL_SERVER_ERROR as status*/ @RequestMapping(value="emp/controller/getDetailsById/{id}",method=RequestMethod.GET,produces=MediaType.APPLICATION_JSON_VALUE)public ResponseEntity getEmployeeDetailByEmployeeId(@PathVariable("id") int myId){logger.info("From Producer method[getEmployeeDetailByEmployeeId] start");Employee employee = employeeDAO.getEmployeeDetailsById(myId);if(employee!=null){logger.info("From Producer method[getEmployeeDetailByEmployeeId] end");return new ResponseEntity(employee,HttpStatus.OK);}else{logger.info("From Producer method[getEmployeeDetailByEmployeeId] end");return new ResponseEntity(HttpStatus.NOT_FOUND);}}/** Method creates an employee and returns the auto-generated employeeId */ @RequestMapping(value="/emp/controller/addEmp",method=RequestMethod.POST,consumes=MediaType.APPLICATION_JSON_VALUE,produces=MediaType.TEXT_HTML_VALUE)public ResponseEntity addEmployee(@RequestBody Employee employee){logger.info("From Producer method[addEmployee] start");logger.debug("From Producer method[addEmployee] start");int empId= employeeDAO.addEmployee(employee);logger.debug("From Producer method[addEmployee] start");logger.info("From Producer method[addEmployee] end");return new ResponseEntity("Employee added successfully with id:"+empId,HttpStatus.CREATED);}/** Method updates an employee and returns the updated Employee If Employee to be updated is not existing, then null is returned with HttpStatus.INTERNAL_SERVER_ERROR as status*/ @RequestMapping(value="/emp/controller/updateEmp",method=RequestMethod.PUT,consumes=MediaType.APPLICATION_JSON_VALUE,produces=MediaType.APPLICATION_JSON_VALUE)public ResponseEntity updateEmployee(@RequestBody Employee employee){logger.info("From Producer method[updateEmployee] start");if(employeeDAO.getEmployeeDetailsById(employee.getEmployeeId())==null){Employee employee2=null;return new ResponseEntity(employee2,HttpStatus.INTERNAL_SERVER_ERROR);}System.out.println(employee);employeeDAO.updateEmployee(employee);logger.info("From Producer method[updateEmployee] end");return new ResponseEntity(employee,HttpStatus.OK);}/** Method deletes an employee using employeeId and returns the deleted Employee If Employee to be deleted is not existing, then null is returned with HttpStatus.INTERNAL_SERVER_ERROR as status*/ @RequestMapping(value="/emp/controller/deleteEmp/{id}",method=RequestMethod.DELETE,produces=MediaType.APPLICATION_JSON_VALUE)public ResponseEntity deleteEmployee(@PathVariable("id") int myId){logger.info("From Producer method[deleteEmployee] start");if(employeeDAO.getEmployeeDetailsById(myId)==null){Employee employee2=null;return new ResponseEntity(employee2,HttpStatus.INTERNAL_SERVER_ERROR);}Employee employee = employeeDAO.removeEmployee(myId);System.out.println("Removed: "+employee);logger.info("From Producer method[deleteEmployee] end");return new ResponseEntity(employee,HttpStatus.OK);}
}

上面的代码代表具有请求处理程序的应用程序的控制器层。

请求处理程序调用DAO层函数并执行CRUD操作。

application.properties

server.port = 8090logging.level.com.xyz.app.controller.EmployeeController=DEBUG#name of the log file to be created#same file will be given as input to logstashlogging.file=app.logspring.application.name = producer

上面的代码表示为基于Spring Boot的应用程序配置的属性。

5. Logstash配置

如3.3节所述,需要为logstash创建配置文件。

logstash将使用此配置文件从微服务日志中获取输入。

日志被转换为JSON并馈入elasticsearch。

cst_logstash.conf

input {file {# If more than one log files from different microservices have to be tracked then a comma-separated list of log files can # be providedpath => ["PATH-TO-UPDATE/app.log"]codec => multiline {pattern => "^%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{TIME}.*"negate => "true"what => "previous"}}
}
output {stdout {codec => rubydebug}# Sending properly parsed log events to elasticsearchelasticsearch {hosts => ["localhost:9200"]}
}

上面的logstash配置文件侦听日志文件,并将日志消息推送到弹性搜索。

注意 :根据您的设置更改日志路径。

6.执行与输出

6.1为日志执行微服务

可以使用clean install spring-boot:run部署Spring Boot应用程序,并可以从浏览器或邮递员客户端访问以下URL: http:// localhost:8090 / emp / controller / getDetails 。

这将击中微服务并在微服务方面生成日志。

这些日志将由logstash读取,并推送到弹性搜索中,此外,可以使用Kibana进行后续步骤来查看这些日志。

6.2在Kibana上查看输出的步骤

  • 在管理控制台中配置索引。 使用索引值作为logstash-*作为默认配置。 打开链接: http:// localhost:5601 / app / kibana#/ management / kibana / index?_g =() ,它将显示如下屏幕:
Kibana Index Creation- 1
  • 单击下一步,将显示以下屏幕
Kibana Index Creation- 2

选择上面突出显示的选项,然后单击“创建索引模式”

  • 从左侧菜单中选择“发现”选项后,页面显示如下:
在Kibana-1上查看日志
  • 可以根据上面突出显示的属性来可视化和过滤日志。 将鼠标悬停在任何属性上后,将显示该属性的“添加”按钮。 在选择消息属性视图后,将显示如下所示:
在Kibana- 2上查看日志

7.参考

  • https://logz.io/learn/complete-guide-elk-stack/
  • https://howtodoinjava.com/microservices/elk-stack-tutorial-example/
  • https://dzone.com/articles/logging-with-elastic-stack

8.下载Eclipse项目

下载您可以在此处下载此示例的完整源代码: microservice

翻译自: https://www.javacodegeeks.com/2018/12/log-aggregation-using-elk-stack.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/344528.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【渝粤教育】广东开放大学 网络整合营销 形成性考核 (53)

选择题 题目&#xff1a; 网络营销应在&#xff08; &#xff09;层面做好格局方面的准备 答案&#xff1a;看左侧 题目&#xff1a; 在互联网社交时代&#xff0c;下列哪个不是其时代特征的产物。&#xff08; &#xff09; 答案&#xff1a;看左侧 题目&#xff1a; 移动端发…

mysql主从延时这么长_MySQL主从延迟问题解决

今天我们就来看看为什么会产生主从延迟以及主从延迟如何处理等相关问题。坐好了&#xff0c;准备发车&#xff01;主从常见架构随着日益增长的访问量&#xff0c;单台数据库的应接能力已经捉襟见肘。因此采用主库写数据&#xff0c;从库读数据这种将读写分离开的主从架构便随之…

【渝粤教育】广东开放大学 跨文化商务沟通 形成性考核 (42)

选择题 题目&#xff1a; The “OK” sign means in France that you think something is _________. 答案&#xff1a;看左侧 题目&#xff1a; Many words from Chinese and English are different in both the denotational meanings and connotational meanings. Which o…

python的zip方法_python zip()函数使用方法解析

这篇文章主要介绍了python zip()函数使用方法解析,文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下参数iterable为可迭代的对象&#xff0c;并且可以有多个参数。该函数返回一个以元组为元素的列表&#xff0c;其…

aes256加密java_使用Java和JCEKS进行AES-256加密

aes256加密java总览 由于最近爱德华斯诺登 &#xff08; Edward Snowden&#xff09;发布了文件&#xff0c;以及针对JC Penny &#xff0c; Sony和Target等在线商业商店的黑客攻击激增&#xff0c;安全性已成为近年来讨论的重要话题。 尽管本文不会为您提供帮助防止使用非法来…

【渝粤教育】电大中专Windows操作系统作业 题库

学习好Windows10应用这门课程&#xff0c;应该&#xff08;&#xff09;。 A重视理论学习 B重视上机操作&#xff0c;多练多试 C只看不练 D可以随便学习一下 正确 正确答案&#xff1a;左边查询 学生答案&#xff1a;B 2在使用Windows时遇到困难&#xff0c;&#xff08;&#…

高可用mysql笔记_MySQL笔记-高可用方案

MySQL笔记-高可用方案一、概述MYSQL高可用方案有多种&#xff0c;本次针对其中部分方案进行实践。包括主从&#xff0c;双主&#xff0c;myqlkeepalived, mysqlmycatkeepalived。纸上得来终觉浅&#xff0c;亲自实验一下。环境信息注意两台机器时间需要保持同步&#xff0c;网络…

【渝粤教育】电大中专办公设备使用与维护 (2)_1作业 题库

1以下哪个不是现代办公硬件需求的主要依赖&#xff08;&#xff09;。 A扫描仪 B计算机 C办公桌 D打印机 错误 正确答案&#xff1a;左边查询 学生答案&#xff1a;B 2现代办公设备可分为计算机、通信&#xff08;&#xff09;三大类。 A电子工具 B办公机械 C路由器 D碎纸机 错…

无服务器冷启动不是问题-这就是为什么(对于大多数应用程序)

从无服务器开始时&#xff0c;您很快就会学习/听到有关函数冷启动的信息&#xff08;我相信无服务器云功能 API &#xff09;。 首次调用云功能时或长时间不调用后会发生冷启动。 基本上&#xff0c;服务器&#xff08;是的&#xff0c;有服务器&#xff01;&#xff09;需要一…

【渝粤教育】电大中专学前儿童健康教育作业 题库

1健康的定义是()年&#xff0c;世界卫生组织提出的。 A1945 B1948 C1955 D1958 错误 正确答案&#xff1a;左边查询 学生答案&#xff1a;A 2健康不仅仅是没有疾病或虚弱&#xff0c;而是包括身体、心理和()方面的完好状态。 A精神 B躯体 C社会 D道德 错误 正确答案&#xff1a…

python学习与数据挖掘_Python学习之数据挖掘(三)

Pandas基础处理Pandas是什么&#xff1f;为什么用&#xff1f;核心数据结构DataFramePanelSeries基本操作运算画图文件的读取与存储高级处理4.1Pandas介绍4.1.1 Pandas介绍 - 数据处理工具panel data analysispanel面板数据 - 计量经济学 三维数据4.1.2 为什么使用Pandas便捷…

【渝粤教育】电大中专学前儿童科学教育 (14)作业 题库

1学前儿童科学教育的学习重点是() A学前儿童科学教育的内涵 B学前儿童科学教育的概念 C科学的概念 D技术的概念 错误 正确答案&#xff1a;左边查询 学生答案&#xff1a;A 2学前儿童科学教育的学习难点是() A学前儿童科学教育的内涵 B学前儿童科学教育在儿童发展中的意义 C学前…

生成器作为(快速失败)状态机

这个想法是几周前在设计“ Generator”类时想到的&#xff0c;该类必须将输入发送给封装的Writer 。 实际上&#xff0c;它是Builder模式。 但是&#xff0c;规则有些复杂&#xff0c;用户必须以某种方式调用add...()方法&#xff0c;才能正确生成输出。 不用说&#xff0c;我…

【渝粤教育】电大中专市场营销管理20作业 题库

1.市场营销没有宏观市场营销和微观市场营销之分。该说法&#xff1a;&#xff08; &#xff09; A.错误 B.正确 错误 正确答案&#xff1a;左边查询 学生答案&#xff1a;B 2.战略选择的陷阱有&#xff1a;盲目跟随、墨守成规、军备竞赛、多方出击、孤注一掷、本末倒置。该说法…

源码包编译安装python_Python3.7源码包编译安装-Go语言中文社区

环境&#xff1a;[rootlocalhost python3]# cat /etc/redhat-releaseCentOS Linux release 7.5.1804 (Core)[rootlocalhost python3]#1、下载Python方式一&#xff1a;方式二&#xff1a;进入https://www.python.org/ftp/python/ 这里存放着所有版本的Python源码。往下拉看到最…

【渝粤教育】电大中专建筑力学 (4)作业 题库

1.下列说法不正确的是&#xff08;&#xff09;。 A.力偶在任何坐标轴上的投形恒为零 B.力可以平移到刚体内的任意一点 C.力系的合力在某一轴上的投形等于各分力在同一轴上投形的代数和 D.力使物体绕某一点转动的效应取决于力的大小和力作用线到该点的垂直距离 正确 正确答案&a…

java criteria and_criteria用法

Criteria Query通过面向对象化的设计&#xff0c;将数据查询条件封装为一个对象。简单来讲&#xff0c;Criteria Query可以看作是传统SQL的对象化表示&#xff0c;如&#xff1a;Java代码Criteria criteria session.createCriteria(User.class);criteria.add(Expression.eq(&q…

【渝粤教育】电大中专新媒体营销实务 (4)作业 题库

1.&#xff08; &#xff09;对新媒体的定义为&#xff1a;“以数字信息技术为基础&#xff0c;以互动传播为特点&#xff0c;具有创新形态的媒体。” A.新传媒产业联盟秘书长王斌 B.联合国教科文组织 C.华纳兄弟总裁施瓦茨威格 正确 正确答案&#xff1a;左边查询 学生答案&am…

服务网格:Istio和AWS App Mesh

本周在AWS re&#xff1a;Invent上的重大公告之一是AWS App Mesh 。 在谈论它之前&#xff0c;让我们先看一下网格到底是什么…… 什么是服务网格&#xff1f; 服务网格是微服务体系结构的基础结构层。 它处理服务之间的通信问题&#xff0c;使该通信更加可见&#xff08;或“…

【渝粤教育】电大中专消费者心理学_1作业 题库

1.在西方&#xff0c;早期思想家也有论及消费时令和消费季节的朴素思想。该说法&#xff08;&#xff09; A.错误 B.正确 正确 正确答案&#xff1a;左边查询 学生答案&#xff1a;A 2.体系凝构阶段大致自20世纪70年代延至20世纪末或21世纪初。该说法&#xff08;&#xff09; …