1.简介

ELK(elasticsearch+logstash+kibana)是目前比较常用的日志分析系统,包括日志收集(logstash),日志存储搜索(elasticsearch),展示查询(kibana),使用ELK作为日志的存储分析系统并通过为每个请求分配requestId链接相关日志。ELK具体结构如下图所示:

1.1es基本概念

Index

类似于mysql数据库中的database

Type

类似于mysql数据库中的table表,es中可以在Index中建立type(table),通过mapping进行映射。

Document

由于es存储的数据是文档型的,一条数据对应一篇文档即相当于mysql数据库中的一行数据row, 一个文档中可以有多个字段也就是mysql数据库一行可以有多列。

Field

es中一个文档中对应的多个列与mysql数据库中每一列对应

Mapping

可以理解为mysql或者solr中对应的schema,只不过有些时候es中的mapping增加了动态识别功能,感觉很强大的样子, 其实实际生产环境上不建议使用,最好还是开始制定好了对应的schema为主。

indexed

就是名义上的建立索引。mysql中一般会对经常使用的列增加相应的索引用于提高查询速度,而在es中默认都是会加 上索引的,除非你特殊制定不建立索引只是进行存储用于展示,这个需要看你具体的需求和业务进行设定了。

Query DSL

类似于mysql的sql语句,只不过在es中是使用的json格式的查询语句,专业术语就叫:QueryDSL

GET/PUT/POST/DELETE

分别类似与mysql中的select/update/delete......

1.2es架构

elasticsearch提供了一个分布式多用户能力的全文搜索引擎,基于RESTfulweb接口。ElasticSearch是用Java开发的, 并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。构建在全 文检索开源软件Lucene之上的Elasticsearch,不仅能对海量规模的数据完成分布式索引与检索,还能提供数据聚合分析。据国际权威的 数据库产品评测机构DBEngines的统计,在2016年1月,Elasticsearch已超过Solr等,成为排名第一的搜索引擎类应用 概括:基于Restful标准的高扩展高可用的实时数据分析的全文搜索工具,elasticsearch架构

Gateway层

es用来存储索引文件的一个文件系统且它支持很多类型,例如:本地磁盘、共享存储(做snapshot的时候需要用到)、hadoop 的hdfs分布式存储、亚马逊的S3。它的主要职责是用来对数据进行长持久化以及整个集群重启之后可以通过gateway重新恢复数据。

Distributed Lucene Directory

Gateway上层就是一个lucene的分布式框架,lucene是做检索的,但是它是一个单机的搜索引擎,像这种es分布式搜索引擎系 统,虽然底层用lucene,但是需要在每个节点上都运行lucene进行相应的索引、查询以及更新,所以需要做成一个分布式的运 行框架来满足业务的需要。

四大模块组件

districted lucene directory之上就是一些es的模块

1. Index Module是索引模块,就是对数据建立索引也就是通常所说的建立一些倒排索引等;

2. Search Module是搜索模块,就是对数据进行查询搜索;

3. Mapping模块是数据映射与解析模块,就是你的数据的每个字段可以根据你建立的表结构 通过mapping进行映射解析,如果你没有建立表结构,es就会根据你的数据类型推测你 的数据结构之后自己生成一个mapping,然后都是根据这个mapping进行解析你的数据;

4. River模块在es2.0之后应该是被取消了,它的意思表示是第三方插件,例如可以通过一 些自定义的脚本将传统的数据库(mysql)等数据源通过格式化转换后直接同步到es集群里, 这个river大部分是自己写的,写出来的东西质量参差不齐,将这些东西集成到es中会引发 很多内部bug,严重影响了es的正常应用,所以在es2.0之后考虑将其去掉。

Discovery、Script

es4大模块组件之上有 Discovery模块:es是一个集群包含很多节点,很多节点需要互相发现对方,然后组成一个集群包括选 主的,这些es都是用的discovery模块,默认使用的是Zen,也可是使用EC2;es查询还可以支撑多种script即脚本语言,包括 mvel、js、python等等。

Transport协议层

再上一层就是es的通讯接口Transport,支持的也比较多:Thrift、Memcached以及Http,默认的是http,JMX就是java的一个 远程监控管理框架,因为es是通过java实现的。

RESTful接口层

最上层就是es暴露给我们的访问接口,官方推荐的方案就是这种Restful接口,直接发送http请求,方便后续使用nginx做代理、 分发包括可能后续会做权限的管理,通过http很容易做这方面的管理。如果使用java客户端它是直接调用api,在做负载均衡以 及权限管理还是不太好做。

1.3RestfulAPI

一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互类的软件。 基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。在目前主流的三种Web服务交互方案中,REST相比于S OAP(Simple Object Access protocol,简单对象访问协议)以及XML-RPC更加简单明了。

接口类型:

(Representational State Transfer 意思是:表述性状态传递)

它使用典型的HTTP方法,诸如GET,POST.DELETE,PUT来实现资源的获取,添加,修改,删除等操作。即通过HTTP动词来实现资源的状态扭转

GET 用来获取资源

POST 用来新建资源(也可以用于更新资源)

PUT 用来更新资源

DELETE 用来删除资源

1.4CRUL命令

以命令的方式执行HTTP协议的请求

GET/POST/PUT/DELETE

示例:

访问一个网页

curl www.baidu.com

curl -o tt.html www.baidu.com

显示响应的头信息

curl -i www.baidu.com

显示一次HTTP请求的通信过程

curl -v www.baidu.com

执行GET/POST/PUT/DELETE操作

curl -X GET/POST/PUT/DELETE url

2.安装logstash

2.1安装jdk

logstash需要依赖jdk,安装logstash之前先安装java环境。下载JDK,

在oracle的官方网站下载,http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html,根据操作系统的版本下载对应的JDK安装包,本次实验下载的是jdk-8u101-linux-x64.tar.gz
    上传文件到服务器并执行:

# mkdir
/usr/local/java

# tar -zxf
jdk-8u45-linux-x64.tar.gz -C /usr/local/java/

配置java环境:

export JAVA_HOME=/usr/local/java/jdk1.8.0_45

export PATH=$PATH:$JAVA_HOME/bin

export
CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPATH

执行java -version命令,打印出java版本信息表示JDK配置成功。

#     java -version

2.2下载logstash

下载并解压

#  wget
https://download.elastic.co/logstash/logstash/logstash-2.4.0.tar.gz
#  tar -xzvf logstash-2.4.0.tar.gz

进入安装目录: cd
#{dir}/logstash-2.4.0,创建logstash测试配置文件:

#  vim test.conf
编辑内容如下:

input {

stdin { }

}

output {

stdout {

codec => rubydebug {}

}

}

运行logstash测试:

#  bin/logstash -f test.conf

显示:

证明logstash已经启动了,
输入hello world

因为我们配置内容为,控制台输出日志内容,所以显示以上格式即为成功。

3. 安装elasticsearch

下载安装包:
wget https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/

tar/elasticsearch/2.4.0/elasticsearch-2.4.0.tar.gz

解压并配置:

tar -xzvf elasticsearch-2.4.0.tar.gz
#  cd #{dir}/elasticsearch-2.4.0
#  vim config/elasticsearch.yml

修改:

path.data:
/data/es        #数据路径

path.logs:
/data/logs/es    #日志路径

network.host:
本机地址  #服务器地址

http.port:
9200          #端口

配置执行用户和目录:

groupadd
elsearch

useradd elsearch
-g elsearch -p elasticsearch

chown -R
elsearch:elsearch elasticsearch-2.4.0

mkdir
/data/es

mkdir
/data/logs/es

chown -R
elsearch:elsearch /data/es

chown -R
elsearch:elsearch /data/logs/es

启动elasticsearch:

#  su elsearch
#  bin/elasticsearch

通过浏览器访问:

安装成功.
集成logstash和elasticsearch,修改Logstash配置为:

input {

stdin { }

}

output {

elasticsearch {

hosts => "elasticsearchIP:9200"

index => "logstash-test"

}

stdout {

codec => rubydebug {}

}

}

再次启动logstash,并输入任意文字:“hello
elasticsearch”

通过elasticsearch搜索到了刚才输入的文字,集成成功。通过elasticsearch的原生接口查询和展示都不够便捷直观,下面我们配置一下更方便的查询分析工具kibana。

4.安装kibana

下载安装包:
wget https://download.elastic.co/kibana/kibana/kibana-4.6.1-linux-x86_64.tar.gz
    解压kibana,并进入解压后的目录

打开config/kibana.yml,修改如下内容

#启动端口 因为端口受限 所以变更了默认端口

server.port:
8601

#启动服务的ip

server.host:
“本机ip”

#elasticsearch地址

elasticsearch.url:
http://elasticsearchIP:9200

启动程序:

bin/kibana

访问配置的ip:port,在discover中搜索刚才输入的字符,内容非常美观的展示了出来。

到这里elk环境已经配置完成,把自己java
web项目试验日志在elk中的使用。

5.创建web工程

一个普通的maven
java web工程,为了测试分布式系统日志的连续性,我们让这个项目自调用n次,并部署2个项目,相互调用,关键代码如下:

controller

@RequestMapping("http_client")

@Controller

public class
HttpClientTestController {

@Autowired

private HttpClientTestBo httpClientTestBo;

@RequestMapping(method = RequestMethod.POST)

@ResponseBody

public BaseResult doPost(@RequestBody HttpClientTestResult result) {

HttpClientTestResult testPost =
httpClientTestBo.testPost(result);

return testPost;

}

}

service

@Service

public class HttpClientTestBo {

private static Logger logger =
LoggerFactory.getLogger(HttpClientTestBo.class);

@Value("${test_http_client_url}")

private String testHttpClientUrl;

public HttpClientTestResult testPost(HttpClientTestResult result) {

logger.info(JSONObject.toJSONString(result));

result.setCount(result.getCount() + 1);

if (result.getCount() <= 3) {

Map<String, String> headerMap = new
HashMap<String, String>();

String requestId =
RequestIdUtil.requestIdThreadLocal.get();

headerMap.put(RequestIdUtil.REQUEST_ID_KEY, requestId);

Map<String, String> paramMap
= new HashMap<String, String>();

paramMap.put("status",
result.getStatus() + "");

paramMap.put("errorCode",
result.getErrorCode());

paramMap.put("message",
result.getMessage());

paramMap.put("count",
result.getCount() + "");

String resultString =
JsonHttpClientUtil.post(testHttpClientUrl, headerMap, paramMap,
"UTF-8");

logger.info(resultString);

}

logger.info(JSONObject.toJSONString(result));

return result;

}

}

为了表示调用的链接性我们在web.xml中配置requestId的filter,用于创建

/*


  requestId


  requestIdFilter


  com.virxue.baseweb.utils.RequestIdFilter

*    requestIdFilter

/*

public class RequestIdFilter
implements Filter {

private static final Logger logger =
LoggerFactory.getLogger(RequestIdFilter.class);

/* (non-Javadoc)

* @see
javax.servlet.Filter#init(javax.servlet.FilterConfig)

*/

public void init(FilterConfig filterConfig) throws ServletException {

logger.info("RequestIdFilter
init");

}

/* (non-Javadoc)

* @see
javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
javax.servlet.ServletResponse, javax.servlet.FilterChain)

*/

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException,

ServletException {

String requestId =
RequestIdUtil.getRequestId((HttpServletRequest) request);

MDC.put("requestId",
requestId);

chain.doFilter(request, response);

RequestIdUtil.requestIdThreadLocal.remove();

MDC.remove("requestId");

}

/* (non-Javadoc)

* @see javax.servlet.Filter#destroy()

*/

public void destroy() {

}

}

utils

public class RequestIdUtil {

public static final String REQUEST_ID_KEY = "requestId";

public static ThreadLocal<String> requestIdThreadLocal = new
ThreadLocal<String>();

private static final Logger logger =
LoggerFactory.getLogger(RequestIdUtil.class);

/**

* 获取requestId

* @Title getRequestId

* @Description TODO

* @return

*

* @author zhengkai

* @date 2019年10月3日 下午21:58:28

*/

public static String getRequestId(HttpServletRequest request) {

String requestId = null;

String parameterRequestId =
request.getParameter(REQUEST_ID_KEY);

String headerRequestId =
request.getHeader(REQUEST_ID_KEY);

if (parameterRequestId == null
&& headerRequestId == null) {

logger.info("request parameter
和header 都没有requestId入参");

requestId = UUID.randomUUID().toString();

} else {

requestId = parameterRequestId !=
null ? parameterRequestId : headerRequestId;

}

requestIdThreadLocal.set(requestId);

return requestId;

}

}

我们使使用了Logback作为日志输出的插件,并且使用它的MDC类,可以无侵入的在任何地方输出requestId,具体的配置如下:

UTF-8

${log_base}/java-base-web.log

${log_base}/java-base-web-%d{yyyy-MM-dd}-%i.log 10 200MB

%d^|^%X{requestId}^|^%-5level^|^%logger{36}%M^|^%msg%n

这里的日志格式使用了“^|^”做为分隔符,方便logstash进行切分。在测试服务器部署2个web项目,并且修改日志输出位置,并修改url调用链接使项目相互调用。

6. 修改logstash读取项目输出日志

新增stdin.conf,内容如下:

input {

file {

path =>
["/data/logs/java-base-web1/java-base-web.log",
"/data/logs/java-base-web2/java-base-web.log"]

type => "logs"

start_position => "beginning"

codec => multiline {

pattern =>
"^\[\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2}"

negate => true

what => "next"

}

}

}

filter{

mutate{

split=>["message","^|^"]

add_field => {

"messageJson" =>
"{datetime:%{[message][0]},
requestId:%{[message][1]},level:%{[message][2]}, class:%{[message][3]},
content:%{[message][4]}}"

}

remove_field => ["message"]

}

}

output {

elasticsearch {

hosts => "10.160.110.48:9200"

index => "logstash-${type}"

}

stdout {

codec => rubydebug {}

}

}

其中path为日志文件地址;codec
=> multiline为处理Exception日志,使换行的异常内容和异常头分割在同一个日志中;filter为日志内容切分,把日志内容做为json格式,方便查询分析,测试一下:

es+logstash+kibana搭建的更多相关文章

  1. Elasticsearch + Logstash + Kibana 搭建教程

    # ELK:Elasticsearch + Logstash + Kibana 搭建教程 Shipper:日志收集者.负责监控本地日志文件的变化,及时把日志文件的最新内容收集起来,输出到Redis暂存 ...

  2. 用ElasticSearch,LogStash,Kibana搭建实时日志收集系统

    用ElasticSearch,LogStash,Kibana搭建实时日志收集系统 介绍 这套系统,logstash负责收集处理日志文件内容存储到elasticsearch搜索引擎数据库中.kibana ...

  3. 键盘侠Linux干货| ELK(Elasticsearch + Logstash + Kibana) 搭建教程

    前言 Elasticsearch + Logstash + Kibana(ELK)是一套开源的日志管理方案,分析网站的访问情况时我们一般会借助 Google / 百度 / CNZZ 等方式嵌入 JS ...

  4. 【转】ELK(ElasticSearch, Logstash, Kibana)搭建实时日志分析平台

    [转自]https://my.oschina.net/itblog/blog/547250 摘要: 前段时间研究的Log4j+Kafka中,有人建议把Kafka收集到的日志存放于ES(ElasticS ...

  5. ELK6.0部署:Elasticsearch+Logstash+Kibana搭建分布式日志平台

    一.前言 1.ELK简介 ELK是Elasticsearch+Logstash+Kibana的简称 ElasticSearch是一个基于Lucene的分布式全文搜索引擎,提供 RESTful API进 ...

  6. 【Big Data - ELK】ELK(ElasticSearch, Logstash, Kibana)搭建实时日志分析平台

    摘要: 前段时间研究的Log4j+Kafka中,有人建议把Kafka收集到的日志存放于ES(ElasticSearch,一款基于Apache Lucene的开源分布式搜索引擎)中便于查找和分析,在研究 ...

  7. Elasticsearch+Logstash+Kibana搭建分布式日志平台

    一.前言 编译安装 1.ELK简介 下载相关安装包地址:https://www.elastic.co/cn/downloads ELK是Elasticsearch+Logstash+Kibana的简称 ...

  8. Elasticsearch+Logstash+Kibana搭建日志平台

    1 ELK简介 ELK是Elasticsearch+Logstash+Kibana的简称 ElasticSearch是一个基于Lucene的分布式全文搜索引擎,提供 RESTful API进行数据读写 ...

  9. ELK(ElasticSearch+Logstash+ Kibana)搭建实时日志分析平台

    一.简介 ELK 由三部分组成elasticsearch.logstash.kibana,elasticsearch是一个近似实时的搜索平台,它让你以前所未有的速度处理大数据成为可能. Elastic ...

随机推荐

  1. ios证书制作与上架指南

    项目开发完了,要上架 ios AppStore 记录一下经过,以及需要提前准备和预防的东西,以便下次省心! 一.首先要申请开发者账号: 账号按流程注册申请,当时申请了够10遍,总结以下经验: 1.申请 ...

  2. android studio学习----The project encoding (windows-1252) does not match the encoding specified in the Gradle build files (UTF-8)

    Warning:The project encoding (windows-1252) does not match the encoding specified in the Gradle buil ...

  3. JAVA concurrent包下Semaphore、CountDownLatch等用法

    CountDownLatch 跟join的区别 CountDownLatch用处跟join很像,但是CountDownLatch更加灵活,如果子线程有多个阶段a.b.c; 那么我们可以实现在a阶段完成 ...

  4. TP框架命令行操作

    cmd进入到tp项目根目录 php think route:list #查看以定义路由 php think version #框架版本 php think list #指令列表 php think h ...

  5. django-URL路由系统

    配置 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表.你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个U ...

  6. nginx常用伪静态设置

    nginx里使用伪静态是直接在nginx.conf 中写规则的,并不需要像apache要开启写模块(mod_rewrite)才能进行伪静态. nginx只需要打开nginx.conf配置文件,在ser ...

  7. javascript打开窗口

    项目中javascript代码,早期使用了只有ie支持的方法:Window createPopup() 方法 那个时候是2009年,而现在已经是2019-12-11了.如何改造这个早期的代码呢? 找到 ...

  8. tf.Variable()、tf.get_variable()和tf.placeholder()

    1.tf.Variable() tf.Variable(initializer,name) 功能:tf.Variable()创建变量时,name属性值允许重复,检查到相同名字的变量时,由自动别名机制创 ...

  9. MySQL | MySQL 数据库系统(一)

    ## 1.什么是 MySQL 数据库? MySQL 数据库是一个关系型数据库管理系统,是服务器领域中受欢迎的开源数据库系统,目前有 Oracle 公司主要负责运营与维护: ## 2.MySQL 数据库 ...

  10. 28 让树莓派开机“说”出自己的IP地址

    http://shumeipai.nxez.com/2019/02/02/analogue-audio-redux.html 树莓派音频口底噪消除的方法