微服务中的日志管理 — ELK

微服务中的日志管理 — ELK通过使用微服务,我们能够解决许多在单体应用中暴露的问题,并且它允许我们创建稳定的分布式应用程序,并对代码,团队规模,维护,发布周期,云计算等进行所需要的控制。但同时微服务也引入了一些挑战,例如分布式日志管理和查看。需要提供在众多服务中查看分布的完整事务日志和分布式调试的能力。实际上,挑战在于微服务是相互隔离的,它们不共享公共数据库和日志文件。随着微服务数量的增加以及我们使用自动化持续集成工具实现…

大家好,又见面了,我是你们的朋友全栈君。

通过使用微服务,我们能够解决许多在单体应用中暴露的问题,并且它允许我们创建稳定的分布式应用程序,并对代码,团队规模,维护,发布周期,云计算等进行所需要的控制。但同时微服务也引入了一些挑战,例如分布式日志管理和查看。需要提供在众多服务中查看分布的完整事务日志和分布式调试的能力。

实际上,挑战在于微服务是相互隔离的,它们不共享公共数据库和日志文件。随着微服务数量的增加以及我们使用自动化持续集成工具实现云部署,当我们遇到任何问题时,非常有必要对组件进行调试。

幸运的我们已经拥有了一系列工具,可将它们一起使用发挥魔力。一组流行的工具是Elastic Search,Logstash和Kibana —— 放在一起被称为ELK堆栈。它们用于实时搜索,分析和可视化日志数据。

在本文中,介绍了如何将ELK堆栈集成到微服务生态系统中。

1. 什么是ELK

  • Elasticsearch是一种基于JSON的分布式搜索和分析引擎,提供水平可扩展性,为高可靠性和易管理性而设计。
  • Logstash是一个动态数据收集管道,具有可扩展的插件生态系统和强大的Elasticsearch协同作用。
  • Kibana通过 UI 提供数据可视化。

ELK 架构

Logstash根据我们设置的过滤条件处理应用程序日志文件,并将这些日志发送到Elasticsearch。通过Kibana,我们可以在需要时查看和分析这些日志。

ELK操作方式

2. ELK安装

所有这三个工具都基于JVM,在开始安装之前,请验证JDK是否已正确配置。检查标准JDK 1.8安装,JAVA_HOME并且PATH已经完成设置。

2.1 Elasticsearch

  • 从此下载页面下载最新版本的Elasticsearch 并将其解压缩到任何文件夹中。
  • 在命令提示符下运行bin\elasticsearch.bat。
  • 默认情况下,它可从http://localhost:9200开始访问

2.2 Kibana

  • 下载页面下载最新的发行版并解压缩到任何文件夹中。
  • 在编辑器中打开config/kibana.yml,并设置elasticsearch.url指向您的Elasticsearch实例。在我们的例子中,elasticsearch.url: “http://localhost:9200
  • 在命令提示符下运行bin\kibana.bat。
  • 成功启动后,Kibana将启动默认端口5601,Kibana UI将通过http://localhost:5601访问

2.3 Logstash

  • 下载页面下载最新的发行版并解压缩到任何文件夹中。
  • 根据配置说明创建一个文件logstash.conf。我们将在后面实际演示时再次确定配置。
  • 现在运行bin/logstash -f logstash.conf以启动logstash。

3. 创建微服务

3.1 创建Spring Boot项目

让我们使用spring boot创建一个应用程序。MAVEN依赖如下:

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>1.5.6.RELEASE</version>
	<relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
	<java.version>1.8</java.version>
</properties>

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-data-rest</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
</dependencies>

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>

3.2 添加REST端点

新建一个RestController类来暴露一些端点/elk,/elkdemo,/exception。实际上我们只是输出了几个日志语句,因此可以根据您的选择随意添加/修改日志。

@RestController
public class ELKController {
	private static final Logger LOG = Logger.getLogger(ELKController.class.getName());
	
	@Autowired
	RestTemplate restTemplete;
	
	@Bean
	RestTemplate restTemplate() {
		return new RestTemplate();
	}
	
	@RequestMapping(value = "/elkdemo")
	public String helloWorld() {
		String response = "Hello user ! " + new Date();
		LOG.log(Level.INFO, "/elkdemo - > " + response);

		return response;
	}
	
	@RequestMapping(value = "/exception")
	public String exception() {
		String rsp = "";
		try {
			int i = 1 / 0;
			// should get exception
		} catch (Exception e) {
			e.printStackTrace();
			LOG.error(e);
			
			StringWriter sw = new StringWriter();
			PrintWriter pw = new PrintWriter(sw);
			e.printStackTrace(pw);
			String sStackTrace = sw.toString(); // stack trace as a string
			LOG.error("Exception As String :: - > "+sStackTrace);
			
			rsp = sStackTrace;
		}

		return rsp;
	}
	
	@RequestMapping(value = "/elk")
	public String helloWorld1() {

		String response = restTemplete.exchange("http://localhost:8080/elkdemo", HttpMethod.GET, null, new ParameterizedTypeReference<String>() {
		}).getBody();
		LOG.log(Level.INFO, "/elk - > " + response);

		try {
			String exceptionrsp = restTemplete.exchange("http://localhost:8080/exception", HttpMethod.GET, null, new ParameterizedTypeReference<String>() {
			}).getBody();
			LOG.log(Level.INFO, "/elk trying to print exception - > " + exceptionrsp);
			response = response + " === " + exceptionrsp;
		} catch (Exception e) {
			// exception should not reach here. Really bad practice :)
		}

		return response;
	}
}

3.3 配置Spring boot Logging

logging.file=elk-example.log
spring.application.name = elk-example

3.4 验证微服务生成的日志

构建并启动应用程序,通过浏览器访问http://localhost:8080/elk。会看到一些异常信息输出。

转到应用程序根目录并检查是否已创建日志文件elk-example.log,并对端点执行几次访问并验证日志文件中是否添加了日志。

4. Logstash配置

我们需要创建一个logstash配置文件,以便让它监听日志文件并将日志消息推送到Elasticsearch。以下是示例中介绍了logstash 配置,请根据你的设置更改日志路径。

input {
  file {
    type => "java"
    path => "D:/eclipse-workspace/java-samples/elk-example-spring-boot/elk-example.log"
    codec => multiline {
      pattern => "^%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{TIME}.*"
      negate => "true"
      what => "previous"
    }
  }
}
 
filter {
  #If log line contains tab character followed by 'at' then we will tag that entry as stacktrace
  if [message] =~ "\tat" {
    grok {
      match => ["message", "^(\tat)"]
      add_tag => ["stacktrace"]
    }
  }
 
 grok {
    match => [ "message",
               "(?<timestamp>%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{TIME})  %{LOGLEVEL:level} %{NUMBER:pid} --- \[(?<thread>[A-Za-z0-9-]+)\] [A-Za-z0-9.]*\.(?<class>[A-Za-z0-9#_]+)\s*:\s+(?<logmessage>.*)",
               "message",
               "(?<timestamp>%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{TIME})  %{LOGLEVEL:level} %{NUMBER:pid} --- .+? :\s+(?<logmessage>.*)"
             ]
  }
 
  
  date {
    match => [ "timestamp" , "yyyy-MM-dd HH:mm:ss.SSS" ]
  }
}
 
output {
   
  stdout {
    codec => rubydebug
  }
 
  # Sending properly parsed log events to elasticsearch
  elasticsearch {
    hosts => ["localhost:9200"]
  }
}

5. Kibana配置

在查看Kibana中的日志之前,我们需要配置索引模式。我们可以配置logstash-*为默认配置。

在Kibana中,打开“Management”,然后单击“Index Patterns”。如果这是你的第一个索引模式,则会自动打开“Create index pattern”页面。 否则,单击左上角的“Create index pattern”。在索引模式Index pattern 字段中输入logstash-*。

创建索引模式

单击下一步Next step。在配置设置Configure settings中,在时间过滤器字段名称Time Filter field name下拉菜单中选择@timestamp。

时间过滤器

注意:
定义索引模式时,与该模式匹配的索引必须存在于Elasticsearch中,并且它们必须包含数据。 要检查哪些索引可用,
可使用curl -XGET “http://localhost:9200/_cat/indices?v”。

索引模式管理页面如下所示。通过这种配置,我们将Kibana指向你选择的Elasticsearch索引。Logstash使用名称模式创建索引,名称格式为logstash-YYYY.MM.DD

索引模式管理

6.验证

现在,当所有组件都启动并运行时,让我们验证整个生态系统。

转到应用程序并访问端点几次以便生成日志,然后转到Kibana控制台,看看日志是否正确堆叠在Kibana中,还有许多额外的功能,比如我们可以过滤,查看内置的不同图表等。

以下是Kibana中生成的日志的视图。

Kibana视图

7. 总结

在这个ELK示例中,我们学习了如何配置ELK堆栈以及如何将应用程序日志文件指向ELK,并查看和分析Kibana中的日志。除了演示的这些功能外还可以有很多其他的配置。例如:

  • 不是监听我们的日志文件,我们可以通过logback配置来使用TCP appender,通过TCP协议将日志发送到远程Logstash实例。
  • 我们可以使用Logstash指向多个日志文件。
  • 我们可以在logstash配置文件中使用更复杂的过滤器,以根据需要执行更多操作。
  • 我们可以使用远程ELK集群指向我们的日志文件,或者将日志推入,这在将应用程序部署到云中时是必需的。
  • 在logstash中创建不同的索引模式。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/134700.html原文链接:https://javaforall.net

(0)
上一篇 2022年6月6日 下午12:46
下一篇 2022年6月6日 下午12:46


相关推荐

  • java 怎么导入jar包_Eclipse怎么导入jar包 Eclipse导入jar包快捷键及图文详细教程

    java 怎么导入jar包_Eclipse怎么导入jar包 Eclipse导入jar包快捷键及图文详细教程Eclipse 导入 jar 包是使用 eclipse 进行 java 开发时至关重要的一环 一个 jar 包可能就会导致一个项目的成功与否 但是有许多朋友还不是很清楚不是很熟练 eclipse 导入 jar 包的快捷键或者方法 小编为大家带来了 eclipse 导入 jar 包的快捷键教学以及导入 jar 包的详细教程 Eclipse 导入 jar 包详细教程 方法 01 最常用的普通操作方式 基本步骤式右击 项目 选择 Pr

    2026年3月18日
    2
  • DriversBackup[通俗易懂]

    DriversBackup[通俗易懂]备份驱动:提前建立好驱动存放的目录,例,G:\DriversBackup然后在cmd下执行以下命令dism/online/export-driver/destination:G:\Driv

    2022年7月2日
    36
  • 统计案例 | 三门问题

    统计案例 | 三门问题统计案例 三门问题一 前言二 背景三 思路 1 直观解释四 思路 2 列出概率空间与所有事件五 思路 3 条件概率法六 思路 4 Python 模拟七 写在最后一 前言今天小编和各位小伙伴来聊一档综艺节目 最高奖项是汽车一辆 就很刺激 以及其背后的统计案例 三门问题 二 背景 三门问题 又称蒙提霍尔问题或蒙提霍尔悖论 要讲清楚这个问题 我们首先得从一档综艺节目说起 这档综艺节目同时也是 三门问题 的来源 想象一下在一档综艺节目中 作为参赛者的你会看见三扇关闭了的门 其中一扇的后面有一辆汽车 选中后

    2026年3月17日
    1
  • android安卓源码海量项目合集打包-1

    android安卓源码海量项目合集打包-1下载地址最后更新共计 113 个分类 5177 套源码 29 2GB 卷新加卷的文件夹 PATH 列表卷序列号为 000002005E7A 7F30F 前台界面 3D 标签云卡片热门 AndroidTagCl 云标签的灵活运用 rar Android 实现标签拖动改变位置 rar android 流式布局和热门标签 zip

    2026年3月26日
    1
  • php三个数从大到小排列_php常用的流程控制语句

    php三个数从大到小排列_php常用的流程控制语句<?php$a = rand(100,999);$b = rand(100,999);$c = rand(100,999);echo “a=”.”$a”.”<br>”;echo “b=”.”$b”.”<br>”;echo “c=”.”$c”.”<br>”;if(($a > $b ) && ($a > …

    2022年8月18日
    11
  • maven安装命令_windows安装maven

    maven安装命令_windows安装mavenLinux安装Maven教程

    2022年8月30日
    7

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号