elk 聚合日志_使用ELK堆栈进行日志聚合

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

elk 聚合日志

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

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

相关文章

Java对象如何实现比较规则

文章目录一、Comparable二、Comparator示例代码一、Comparable public interface Comparable 此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序&#xff0c;类的 compareTo 方法被称为它的自然比较方法。 实现此接口的对象列表&#xff08;和数组…

python教材目录,python 目录

python在安装的时候&#xff0c;就自带了很多模块&#xff0c;我们把这些模块称之为标准库&#xff0c;其中&#xff0c;有一个是使用频率比较高的&#xff0c;就是 os 。这个库中方法和属性众多&#xff0c;有兴趣的看官可以参考官方文档&#xff1a;https://docs.python.org/…

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

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

除法算式的正确表述

12 4 3&#xff0c;这个关系表达式叫作除法算式&#xff0c;表述为 12 除以 4 等于 3&#xff1b;也可以表述为 4 除 12 等于 3。

elk 日志管理_具有ELK的APIGEE API网关日志管理(弹性搜索,Logstash和Kibana)

elk 日志管理在本文中&#xff0c;我们将看到如何使用 Elastic Search &#xff0c; Logstash 和 Kibana 管理APIGEE API网关生成的日志 。 下图突出显示了日志数据如何流经ELK堆栈以进行数据可视化和监视。 作为API网关的一部分&#xff0c;我们将使用MessageLogging策略在代…

php输出分组,ThinkPHP 项目分组中的模板输出

模板输出启用了项目分组后&#xff0c;模板输出路径同原来相比有一些差别。默认输出当使用 $this->display() 指令输出默认模板时&#xff0c;输出的模板路径加上了分组名&#xff1a;TPL/模板默认主题/分组名/模块名/操作名模板后缀// 例子&#xff1a;Tpl/default/Admin/U…

平方根/立方根/根式

文章目录平方根/二次方根/二次根立方根/三次方根/三次根平方根/二次方根/二次根 如果一个正数 x 的平方等于 a&#xff0c;即 x2x^2x2 a&#xff0c;那么这个正数 x 就叫 做 a 的算术平方根&#xff08;算术二次方根&#xff09;&#xff0c;记作 a\sqrt{a}a​ &#xff0c;读…

使用junit进行单元测试_使用JUnit5对DynamoDB应用程序进行单元测试

使用junit进行单元测试在上一篇文章中&#xff0c;我描述了新的Java 2 AWS开发工具包&#xff0c;它为调用不同AWS服务的Java客户端提供了非阻塞IO支持。 在本文中&#xff0c;我将介绍一种用于单元测试AWS DynamoDB调用的方法。 有几种方法可以启动DynamoDB的本地版本– 1. …

h5jumppage.php,h5使用webviewjsbridge跟原生交互,点击标签调用2次webview

问题描述使用vue循环一个标签列表&#xff0c;点击列表里面的标签&#xff0c;调用app给的跳转页面的方法&#xff0c;第一次跳转页面后&#xff0c;点击返回按钮回到本页面&#xff0c;再次点击列表里面的标签&#xff0c;调用了2次webview&#xff0c;只有第一次点击的时候正…

Servlet的学习笔记

文章目录基本介绍入门步骤执行原理Servlet 生命周期线程安全问题解决方式Servlet 注解配置Servlet 继承与实现体系基本介绍 servlet&#xff0c;server applet&#xff0c;服务器端小程序 servlet 是一个接口&#xff0c;定义了 Java 类被浏览器访问&#xff08;tomcat 识别&…

spring框架介绍_Spring框架介绍

spring框架介绍这是Spring框架和Spring核心概念的简介。 在本教程中&#xff0c;我们将介绍Spring Framework的主要优点和功能。 在随后的教程中&#xff0c;我们将学习有关Spring和Spring Boot的更多信息。 总览 我们知道&#xff0c; Spring框架是Java开发人员中最受欢迎的应…

Java注解(Annotation)的学习

文章目录注解定义作用分类API 文档注解JDK 预定义的注解自定义注解注解的格式注解的本质注解的属性属性的返回值类型属性的特点属性的赋值元注解TargetRetentionDocumentedInherited解析注解总结注解定义 注解( Annotation)&#xff0c;也叫元数据。一种代码级别的说明。它是 …

oracle数据库硬恢复,Oracle数据库的可恢复性设置

整理自《Oracle 11g OCP/OCA 认证指南》001为了保证数据库的最大可恢复性&#xff0c;必须多路复用控制文件&#xff1b;必须多路复用联机重做日志&#xff1b;必须以归档日志模式运行数据库&#xff0c;并多路复用归档日志文件&#xff1b;最后必须作常规备份。002 保护控制文…

rest api如何创建_创建一个安全的Spring REST API

rest api如何创建“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕&#xff1f; 尝试使用Okta API进行托管身份验证&#xff0c;授权和多因素身份验证。 “如果有用&#xff0c;它将被修改。” 那些智慧的话来自我的QA老师…

IntelliJ IDEA 的 Build Project/Build Module/构建项目/构建模块/构建工程

文章目录Build ModuleRebuild ModuleBuild Module&#xff0c;构建模块。所谓“构建”&#xff0c;就是“构建”包及字节码文件&#xff0c;其实就是编译源码文件的动作了。所以 Build Module&#xff0c;就是把 src 目录的源代码文件以及 resources 下的资源文件&#xff0c;构…

oracle 修改nls_characterset,ORACLE NLS_CHARACTERSET字符集的更改

ORACLE NLS_CHARACTERSET字符集的更改      数据库创建以后&#xff0c;如果需要修改字符集&#xff0c;通常需要重建数据库&#xff0c;通过导入导出的方式来转换。      我们也可以通过以下方式更改      ALTER DATABASE CHARACTER SET      注意&#xff1a…

commons cli_从Commons CLI迁移到picocli

commons cli最初于2002年发布的Apache Commons CLI可能是使用最广泛的Java命令行解析器&#xff0c;但是它的API显示了它的年龄。 寻找具有最少样板代码的现代方法的应用可能对picocli感兴趣。 为什么要花麻烦的钱进行迁移&#xff0c;以及如何将基于Commons CLI的应用程序迁移…

乘方(幂)的运算法则/规则

文章目录乘方的定义运算法则正分数指数幂法则负分数指数幂法则同底数幂法则负整数指数幂法则乘方的定义 求相同因数的积叫做乘方。乘方运算的结果叫幂。 当 ana^nan 看作 a 的 n 次乘方的结果时&#xff0c;也可读作“a 的 n 次幂”或“ a 的 n 次方”。其中&#xff0c;a 叫…

php响应式布局,响应式布局之弹性布局的介绍

响应式布局的实现是前端工程中一个非常大的跨越&#xff0c;它非常灵活的可塑造性使得同一个网站能在不同的终端设备上展现出不同的活力。就今天这个机会&#xff0c;我想与大家分享并探讨一些常用来实现响应式布局方法中的弹性布局。弹性布局是一种十分方便的&#xff0c;只需…

qt弹簧教程_弹簧启动执行器教程

qt弹簧教程朋友您好&#xff0c;在本教程中&#xff0c;我们将学习弹簧执行器及其所有帮助。 1.什么是弹簧执行器&#xff1f; 2.如何在Maven项目或Gradle项目中添加弹簧执行器&#xff1f; 3.创建一个具有Spring Actuator依赖项的Spring Boot项目。 4.使用弹簧执行器端点监…