赞
踩
Elasticsearch是一种开源的搜索和分析引擎,最初由开源搜索引擎Lucene的作者于2010年创建。它提供了一个可伸缩、高性能的搜索和数据分析平台,可用于多种用途,包括文本搜索、应用程序性能监控、业务分析、日志聚合等。
Elasticsearch使用分布式架构,可以处理大量数据并实现快速搜索和聚合。它使用基于JSON的RESTful API进行交互,并支持各种语言的客户端库。Elasticsearch还提供了大量的插件和整合方案,例如集成Kibana和Logstash进行数据可视化和日志分析。
Elasticsearch主要特点有:
分布式架构,可以水平扩展和处理多个节点上的数据
实时搜索和分析,支持实时的文本搜索和分析
高可用性和冗余性,支持节点复制和故障转移
全文搜索和模糊查询,支持全文搜索、模糊查询和聚合操作
可扩展性和灵活性,支持各种格式的数据和第三方插件
总之,Elasticsearch是一个功能强大、可伸缩、用途广泛的搜索和数据分析引擎,适用于大量的数据处理和搜索场景。
以下是Elasticsearch中的一些主要的名词和概念:
索引(Index):在Elasticsearch中,一个 索引 类似于传统关系数据库中的一个 数据库 ,是一个存储关系型文档的地方。
文档(Document):文档是Elasticsearch中的基本单位,类似于关系型数据库中的记录或行。每个文档都有一个唯一的标识符,称为文档ID。
分片(Shard):分片是将一个索引分成多个部分的过程,以便能够在多个节点之间共享和平衡负载。每个索引都被分成多个分片,并可以分配到不同的节点上。
副本(Replica):副本是在多个节点之间复制分片的过程,以便可以提高可用性和容错性。每个主分片都可以有多个副本,而每个副本都在不同的节点上。
集群(Cluster):集群是多个节点的集合,用于共同协作以处理数据和查询。每个集群都有一个唯一的名称,并且可以容纳多个索引和多个节点。
节点(Node):节点是一个单独的Elasticsearch实例,它通过加入一个集群来参与搜索和分析。每个节点都有一个唯一的名称,并且可以是一个主节点(Master node)或一个工作节点(Data node)。
映射(Mapping):映射是文档存储和索引方式的定义,用于描述文档中每个字段的数据类型和其它属性。每个索引都有一个映射,用于确定该索引中的文档如何被存储和搜索。
查询(Query):查询是在Elasticsearch中搜索文档的方法,可以通过各种查询类型进行检索,如全文搜索、聚合操作、过滤等。
这些是Elasticsearch中的一些重要概念和名词,了解它们可以更好地理解Elasticsearch的运作方式和特性。
Elasticsearch 是面向文档型数据库,一条数据在这里就是一个文档。为了方便大家理解,
我们将 Elasticsearch 里存储文档数据和关系型数据库 MySQL 存储数据的概念进行一个类比
Elasticsearch | MySQL |
---|---|
Index(索引) | Dotobase(数据库) |
Type(类型) | Table(数据表) |
Dcoument(文档) | Row(行) |
Mapping | Schema |
Fields(字段) | Column(列) |
ES 里的 Index 可以看做一个库,而 Types 相当于表,Documents 则相当于表的行。这里 Types 的概念已经被逐渐弱化,Elasticsearch 6.X 中,一个 index 下已经只能包含一个type,Elasticsearch 7.X 中, Type 的概念已经被删除了。
对比关系型数据库,创建索引就等同于创建数据库。向 ES 服务器发 PUT 请求:
在ApiFox中:http://127.0.0.1:9200/csy
在Kibana中:PUT /csy
响应:
{
"acknowledged" 【响应结果】: true, # true 操作成功
"shards_acknowledged"【分片结果】 : true,# 分片操作成功
"index" 【索引名称】: "csy"
}
查看所有索引: 向 ES 服务器发 GET 请求
在 ApiFox中: http://127.0.0.1:9200/_cat/indices?v
这里请求路径中的_cat 表示查看的意思, indices 表示索引,查看当前 ES服务器中的所有索引,就像 MySQL 中的 show tables
在Kibana中: GET/_cat/indices?v
查看单个索引:
在 ApiFox中: http://127.0.0.1:9200/csy
在Kibana中: GET/csy
响应:
"csy" : { //索引名 "aliases": {},//别名 "mappings": {},//映射 "settings": {//设置 "index" : { //设置 - 索引 "routing" : { "allocation" : { "include" : { "_tier_preference" : "data_content" } } }, "number_of_shards" : "1", //设置 - 索引 - 主分片数量 "provided_name" : "csy", "creation_date" : "1679450796617", //设置 - 索引 - 创建时间 "number_of_replicas" : "1", //设置 - 索引 - 主分片数量 "uuid" : "x-bQnnvzT6-ooWVf8bdrTQ", //设置 - 索引 - 唯一标识 "version" : { //设置 - 索引 - 版本 "created" : "7170399" } } } } }
向 ES 服务器发 DELETE 请求 :
在 ApiFox中: http://127.0.0.1:9200/csy
在Kibana中: DELETE /csy
响应结果:
{
"acknowledged" : true
}
索引已经创建好了,接下来我们来创建文档,并添加数据。这里的文档可以类比为关系型数
据库中的表数据,添加的数据格式为 JSON 格式
向 ES 服务器发 POST 请求:
请求内容为:
{
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":3999.00
}
在 ApiFox中: http://127.0.0.1:9200/csy/_doc 并将上述内容以Json的形式发送
在Kibana中:
POST /csy/_doc
{
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":3999.00
}
响应结果:
{
"_index" : "csy",
"_type" : "_doc", //类型-文档
"_id" : "7vklB4cBPMxSmKFid4CY", //唯一标识 #可以类比为 MySQL 中的主键,随机生成
"_version" : 1,
"result" : "created", //这里的 create 表示创建成功
"_shards" : { // 分片
"total" : 2, //分片 - 总数
"successful" : 1, //分片 - 成功
"failed" : 0 // 分片 - 失败
},
"_seq_no" : 0,
"_primary_term" : 1
}
上面的数据创建后,由于没有指定数据唯一性标识(ID),默认情况下,ES 服务器会随机生成一个。
如果想要自定义唯一性标识,需要在创建时指定:
http://127.0.0.1:9200/csy/_doc/1
查看文档时,需要指明文档的唯一性标识,类似于 MySQL 中数据的主键查询,向 ES 服务器发 GET 请求。
ApiFox: http://127.0.0.1:9200/csy/_doc/7vklB4cBPMxSmKFid4CY
Kibana: GET /csy/_doc/7vklB4cBPMxSmKFid4CY
和新增文档一样,输入相同的 URL 地址请求附带上唯一标识,如果请求体变化,会将原有的数据内容覆盖,向 ES 服务器发 POST 请求。
在 ApiFox中: http://127.0.0.1:9200/csy/_doc/7vklB4cBPMxSmKFid4CY 并将下述内容以Json的形式发送
{
"doc": {
"price":3000.00
}
}
在Kibana中:
POST /csy/_doc/7vklB4cBPMxSmKFid4CY
{
"doc": {
"price":3000.00
}
}
修改数据时,也可以只修改某一给条数据的局部信息。向 ES 服务器发 POST 请求。
在 ApiFox中: http://127.0.0.1:9200/csy/_update/7vklB4cBPMxSmKFid4CY 并将上述内容以Json的形式发送
在Kibana中:
POST /csy/_update/7vklB4cBPMxSmKFid4CY
{
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":3999.00
}
删除一个文档不会立即从磁盘上移除,它只是被标记成已删除(逻辑删除)。向 ES 服务器发 DELETE 请求。
在 ApiFox中: http://127.0.0.1:9200/csy/_doc/7vklB4cBPMxSmKFid4CY
在Kibana中: DELETE/csy/_doc/7vklB4cBPMxSmKFid4CY
响应结果:
{
"_index" : "csy",
"_type" : "_doc",
"_id" : "7vklB4cBPMxSmKFid4CY",
"_version" : 2,
"result" : "deleted", //deleted 表示数据被标记为删除
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1
}
向 ES 服务器发 POST 请求 。
在 ApiFox中: http://127.0.0.1:9200/csy/_delete_by_query
{
"query":{
"match":{
"price":4000.00
}
}
}
在Kibana中: POST /csy/_delete_by_query
{
"query":{
"match":{
"price":4000.00
}
}
}
响应结果:
{ "took" : 27, //耗时 "timed_out" : false, "total" : 1, "deleted" : 1, //删除数量 "batches" : 1, "version_conflicts" : 0, "noops" : 0, "retries" : { "bulk" : 0, "search" : 0 }, "throttled_millis" : 0, "requests_per_second" : -1.0, "throttled_until_millis" : 0, "failures" : [ ] }
有了索引库,等于有了数据库中的 database。接下来就需要建索引库(index)中的映射了,类似于数据库(database)中的表结构(table)。创建数据库表需要设置字段名称,类型,长度,约束等;索引库也一样,需要知道这个类型下有哪些字段,每个字段有哪些约束信息,这就叫做映射(mapping)
向 ES 服务器发 PUT 请求 。
在 ApiFox中: http://127.0.0.1:9200/csy/_mapping 请求体内容为 { "properties": { "name":{ "type": "text", "index": true }, "sex":{ "type": "text", "index": false }, "age":{ "type": "long", "index": false } } }
在Kibana中: PUT/csy/_mapping { "properties": { "name":{ "type": "text", "index": true }, "sex":{ "type": "text", "index": false }, "age":{ "type": "long", "index": false } } }
映射数据说明:
向 ES 服务器发 GET 请求。
在 ApiFox中: http://127.0.0.1:9200/csy/_mapping
在Kibana中: GET/csy/_mapping
响应结果:
{ "csy" : { "mappings" : { "properties" : { "age" : { "type" : "long", "index" : false }, "category" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } }, "images" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } }, "name" : { "type" : "text" }, "price" : { "type" : "float" }, "query" : { "properties" : { "match" : { "properties" : { "price" : { "type" : "float" } } } } }, "sex" : { "type" : "text", "index" : false }, "title" : { "type" : "text", "fields" : { "keyword" : { "type" : "keyword", "ignore_above" : 256 } } } } } } }
向 ES 服务器发 PUT 请求 。
在 ApiFox中: http://127.0.0.1:9200/csy1 { "settings": {}, "mappings": { "properties": { "name":{ "type": "text", "index": true }, "sex":{ "type": "text", "index": false }, "age":{ "type": "long", "index": false } } } }
在Kibana中: PUT /csy1 { "settings": {}, "mappings": { "properties": { "name":{ "type": "text", "index": true }, "sex":{ "type": "text", "index": false }, "age":{ "type": "long", "index": false } } } }
响应:
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "csy1"
}
Elasticsearch 提供了基于 JSON 提供完整的查询 DSL 来定义查询
定义数据:
# POST /student/_doc/1001 { "name":"zhangsan", "nickname":"zhangsan", "sex":"男", "age":30 } # POST /student/_doc/1002 { "name":"lisi", "nickname":"lisi", "sex":"男", "age":20 } # POST /student/_doc/1003 { "name":"wangwu", "nickname":"wangwu", "sex":"女", "age":40 } # POST /student/_doc/1004 { "name":"zhangsan1", "nickname":"zhangsan1", "sex":"女", "age":50 } # POST /student/_doc/1005 { "name":"zhangsan2", "nickname":"zhangsan2", "sex":"女", "age":30 }
以下所有的操作均在Kibana中操作
GET _search
{
"query": {
"match_all": {}
}
}
// "query":这里的 query 代表一个查询对象,里面可以有不同的查询属性
//"match_all":查询类型,例如:match_all(代表查询所有), match,term , range 等等
//{查询条件}:查询条件会根据类型的不同,写法也有差异
查询结果:
#! Deprecation: this request accesses system indices: [.apm-agent-configuration, .kibana_1, .kibana_task_manager_1, .security-7], but in a future major version, direct access to system indices will be prevented by default { "took" : 769, //查询花费时间,单位毫秒 "timed_out" : false, //是否超时 "_shards" : { //分片信息 "total" : 12, //总数 "successful" : 12, //成功 "skipped" : 0,//忽略 "failed" : 0 // 失败 }, "hits" : { //搜索命中结果 "total" : { //搜索条件匹配的文档总数 "value" : 10000, //总命中计数的值 "relation" : "gte" //计数规则 }, "max_score" : 1.0, //匹配度分值 "hits" : [ } //命中结果集合 ] } }
match 匹配类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是 or 的关系,向 ES 服务器发 GET 请求。
GET /student/_search
{
"query": {
"match": {
"name":"zhangsan"
}
}
}
multi_match 与 match 类似,不同的是它可以在多个字段中查询。向 ES 服务器发 GET 请求
GET /student/_search
{
"query": {
"multi_match": {
"query": "zhangsan",
"fields": ["name","nickname"]
}
}
}
term 查询,精确的关键词匹配查询,不对查询条件进行分词。向 ES 服务器发 GET 请求。
GET /student/_search
{
"query": {
"term": {
"name": {
"value": "zhangsan"
}
}
}
}
terms 查询和 term 查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件,类似于 mysql 的 in,向 ES 服务器发 GET 请求。
GET /student/_search
{
"query": {
"terms": {
"name": ["zhangsan","lisi"]
}
}
}
GET /student/_search
{
"_source": ["name","nickname"],
"query": {
"terms": {
"nickname": ["zhangsan"]
}
}
}
我们也可以通过:
向 ES 服务器发 GET 请求 :
GET /student/_search { "_source": { "includes": ["name","nickname"] }, "query": { "terms": { "nickname": ["zhangsan"] } } } //或 { "_source": { "excludes": ["name","nickname"] }, "query": { "terms": { "nickname": ["zhangsan"] } } }
bool
把各种其它查询通过must
(必须 )、must_not
(必须不)、should
(应该)的方
式进行组合,向 ES 服务器发 GET 请求.
GET /student/_search { "query": { "bool": { "must": [ { "match": { "name": "zhangsan" } } ], "must_not": [ { "match": { "age": "40" } } ], "should": [ { "match": { "sex": "男" } } ] } } }
range 查询找出那些落在指定区间内的数字或者时间。range 查询允许以下字符
操作符 | 说明 |
---|---|
gt | > |
gte | >= |
lt | < |
lte | <= |
向 ES 服务器发 GET 请求
GET /student/_search
{
"query": {
"range": {
"age": {
"gte": 30,
"lte": 35
}
}
}
}
返回包含与搜索字词相似的字词的文档。编辑距离是将一个术语转换为另一个术语所需的一个字符更改的次数。这些更改可以包括:
为了找到相似的术语,fuzzy 查询会在指定的编辑距离内创建一组搜索词的所有可能的变体
或扩展。然后查询返回每个扩展的完全匹配。通过 fuzziness 修改编辑距离。一般使用默认值 AUTO,根据术语的长度生成编辑距离。向 ES 服务器发 GET 请求 :
GET /student/_search { "query": { "fuzzy": { "name": { "value": "lisi" } } } } GET /student/_search { "query": { "fuzzy": { "name": { "value": "lisi", "fuzziness": 2 } } } }
sort 可以让我们按照不同的字段进行排序,并且通过 order 指定排序的方式。desc 降序,asc
升序。向 ES 服务器发 GET 请求。
GET /student/_search
{
"query": {
"match": {
"name":"zhangsan"
}
},
"sort": [{
"age": {
"order":"desc"
}
}]
}
假定我们想要结合使用 age 和 _score 进行查询,并且匹配的结果首先按照年龄排序,然后
按照相关性得分排序,向 ES 服务器发 GET 请求。
GET /student/_search { "query": { "match_all": {} }, "sort": [ { "age": { "order": "desc" } }, { "_score":{ "order": "desc" } } ] }
在进行关键字搜索时,搜索出的内容中的关键字会显示不同的颜色,称之为高亮。
Elasticsearch 可以对查询内容中的关键字部分,进行标签和样式(高亮)的设置。
在使用 match 查询的同时,加上一个 highlight 属性:
向 ES 服务器发 GET 请求 。
GET /student/_search
{
"query": {
"match": {
"name": "zhangsan"
}
},
"highlight": {
"pre_tags": "<font color='red'>",
"post_tags": "</font>",
"fields": {
"name": {}
}
}
}
from:当前页的起始索引,默认从 0 开始。 from = (pageNum - 1) * size
size:每页显示多少条,向 ES 服务器发 GET 请求
GET /student/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"age": {
"order": "desc"
}
}
],
"from": 0,
"size": 2
}
聚合允许使用者对 es 文档进行统计分析,类似与关系型数据库中的 group by,当然还有很
多其他的聚合,例如取最大值、平均值等等。
向 ES 服务器发 GET 请求 :
GET /student/_search
{
"aggs":{
"max_age":{
"max":{"field":"age"}
}
},
"size":0
}
GET /student/_search
{
"aggs":{
"min_age":{
"min":{"field":"age"}
}
},
"size":0
}
对某个字段求和 sum
GET /student/_search
{
"aggs":{
"sum_age":{
"sum":{"field":"age"}
}
},
"size":0
}
GET /student/_search
{
"aggs":{
"avg_age":{
"avg":{"field":"age"}
}
},
"size":0
}
对某个字段的值进行去重之后再取总数
GET /student/_search
{
"aggs":{
"distinct_age":{
"cardinality":{"field":"age"}
}
},
"size":0
}
GET /student/_search
{
"aggs":{
"stats_age":{
"stats":{"field":"age"}
}
},
"size":0
}
桶聚和相当于 sql 中的 group by 语句
GET /student/_search
{
"aggs":{
"age_groupby":{
"terms":{"field":"age"}
}
},
"size":0
}
GET /student/_search
{
"aggs":{
"age_groupby":{
"terms":{"field":"age"}
}
},
"size":0
}
<properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <elastic.version>7.17.3</elastic.version> <jackson.version>2.12.3</jackson.version> <jakarta.version>2.0.1</jakarta.version> <logstash.version>7.3</logstash.version> </properties> <dependencies> <!--elasticsearch--> <dependency> <groupId>co.elastic.clients</groupId> <artifactId>elasticsearch-java</artifactId> <version>${elastic.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>jakarta.json</groupId> <artifactId>jakarta.json-api</artifactId> <version>${jakarta.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-core --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </dependency> <dependency> <groupId>net.logstash.logback</groupId> <artifactId>logstash-logback-encoder</artifactId> <version>${logstash.version}</version> </dependency> </dependencies>
@SpringBootConfiguration @ConfigurationProperties(prefix = "es") @Data public class ElasticConfig { private String host; private Integer port; private String username; private String password; public static final RequestOptions COMMON_OPTIONS; static { RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder(); // builder.addHeader("Authorization", "Bearer " + TOKEN); // builder.setHttpAsyncResponseConsumerFactory( // new HttpAsyncResponseConsumerFactory // .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024 * 1024)); COMMON_OPTIONS = builder.build(); } // 同步客户端 @Bean public ElasticsearchClient esClient() { final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password)); // Create the low-level client RestClient restClient = RestClient.builder(new HttpHost(this.getHost(), this.getPort(),"http")) .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder .setDefaultCredentialsProvider(credentialsProvider)).build(); // Create the transport with a Jackson mapper ElasticsearchTransport transport = new RestClientTransport( restClient, new JacksonJsonpMapper()); // And create the API client return new ElasticsearchClient(transport); } }
@SpringBootTest @Slf4j public class SearchApplicationTest { @Resource private ElasticsearchClient elasticsearchClient; @Data @ToString static class Product { private String Sku; private String cityBike; private double price; public Product(String Sku, String cityBike, double price) { } } /** * 保存信息 */ @Test void indexData() throws IOException { Product product = new Product("bk-1", "City bike", 123.0); IndexResponse response = elasticsearchClient.index(i -> i .index("products") .id(product.getSku()) .document(product) ); log.info("Indexed with version " + response.version()); } /** * 查询信息 */ @Test public void searchDataProduct() throws IOException { GetResponse<Product> response = elasticsearchClient.get(g -> g .index("products") .id("bk-1"), Product.class ); log.info("Found source " + response.source() + ", version " + response.version() + ", index " + response.index() + ", id " + response.id()); } /** * 搜索索引为users的信息 */ @Test public void searchDataUser() throws IOException { // 1.创建检索请求 SearchResponse<Map> users = elasticsearchClient.search(s -> s .index("users"), Map.class); log.info("max score " + users.hits().hits()); } /** * 搜索文档 */ @Test public void searchData() throws IOException { Query query = MatchQuery.of(q -> q .field("address") .query("mill") )._toQuery(); // 1.创建检索请求 SearchResponse<Account> response = elasticsearchClient.search(s -> s .index("bank") .query(query) // 按照年龄值分布聚合 .aggregations("ageAgg", a -> a .terms(h -> h .field("age") .size(10) )) // 计算平均薪资 .aggregations("balanceAvg", b -> b .avg(h -> h .field("balance"))), Account.class ); log.info("max score " + response.hits().maxScore()); log.info("response.aggregations" + response.aggregations()); } }
ELK平台是一种开源的实时数据分析平台,由三个免费的软件组成:Elasticsearch、Logstash和Kibana。它允许用户从不同来源收集、存储、搜索、分析和可视化大量日志数据和其他数据类型,以便更好地管理和监视应用程序和系统。每个工具有以下职责:
Elasticsearch: Elasticsearch 是一个分布式、可扩展和高可用性的分析引擎,使您可以轻松地存储、搜索和分析大量数据。
Logstash:Logstash 是一个日志收集、处理和传输的工具。它可以将来自不同系统、应用程序和存储位置的日志数据收集到一个集中的位置进行处理。
Kibana:Kibana 是一个用于可视化和分析数据的界面,使您可以以各种方式查看一个或多个数据源中的数据。
ELK平台的优势在于其能够集中管理和监视来自多个源的日志数据。这使得用户可以更好地了解他们的应用程序和系统的性能和问题,并且可以采取适当措施来解决这些问题。
elasticsearch
# 安装es docker pull elasticsearch:7.17.3 mkdir -p /mydata/elasticsearch/config mkdir -p /mydata/elasticsearch/data echo "http.host: 0.0.0.0" >> /mydata/elasticsearch/config/elasticsearch.yml chmod -R 777 /mydata/elasticsearch/ docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \ -e "discovery.type=single-node" \ -e ES_JAVA_OPTS="-Xms512m -Xmx512m" \ --restart=always --privileged=true \ -v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \ -v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \ -v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \ -d elasticsearch:7.17.3
logstach
# logstash安装
docker run -d --name logstash \
-p 5043:5043 -p 5044:5044 --privileged=true \
-v /mydata/logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf \
-v /mydata/logstash/logstash.yml:/usr/share/logstash/config/logstash.yml \
logstash:7.17.3
kibana
# 安装es可视化工具kibana
docker pull kibana:7.17.3
# ELASTICSEARCH_HOSTS=http://本机ip:9200
docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.56.101:9200 -p 5601:5601 \
--restart=always --privileged=true -d kibana:7.17.3
elasticsearch
修改 /mydata/elasticsearch/config/elasticsearch.yml
http.host: 0.0.0.0
http.cors.enabled: true
http.cors.allow-origin: "*"
http.cors.allow-headers: Authorization
xpack.security.enabled: true
# Enable encryption and mutual authentication between cluster nodes
xpack.security.transport.ssl.enabled: true
# Enable encryption for HTTP API client connections, such as Kibana, Logstash, and Agents
xpack.security.http.ssl.enabled: false
重启之后进入容器
./bin/elasticsearch-setup-passwords interactive
logstach
新增/mydata/logstash/logstash.conf文件
input { stdin { } tcp { mode => "server" host => "0.0.0.0" port => 5043 codec => json_lines } } output { stdout { codec => rubydebug } elasticsearch { hosts => "localhost:9200" index => "springboot-%{+YYYY.MM.dd}" user => "username" password => "password" } }
进入容器执行
docker exec -it logstash /bin/bash
/usr/share/logstash/bin/logstash-plugin install logstash-codec-json_lines //安装json_lines所需的插件
pom
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>7.3</version>
</dependency>
在resources文件夹下,创建logback.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="false"> <!--获取springboot的yml配置信息--> <springProperty scope="context" name="applicationName" source="spring.application.name" defaultValue="default"/> <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径--> <property name="LOG_HOME" value="/home"/> <!--输出到控制台--> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter> <withJansi>false</withJansi> <encoder> <!--<pattern>%d %p (%file:%line)- %m%n</pattern>--> <!--格式化输出:%d:表示日期 %thread:表示线程名 %-5level:级别从左显示5个字符宽度 %msg:日志消息 %n:是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss} %highlight(%-5level) -- %boldMagenta([%thread]) %boldCyan(%logger) : %msg%n</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- 日志发送至logstash --> <appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender"> <!-- logstash的服务器地址和通信端口 --> <destination>你的虚拟机IP地址:5043</destination> <!-- encoder is required --> <encoder class="net.logstash.logback.encoder.LogstashEncoder"> <!-- 在elasticsearch的index中追加applicationName字段 --> <customFields>{"applicationName":"${applicationName}"}</customFields> </encoder> </appender> <!-- 按照每天生成日志文件 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!--日志文件输出的文件名--> <FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern> <!--日志文件保留天数--> <MaxHistory>30</MaxHistory> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> <!--日志文件最大的大小--> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <MaxFileSize>10MB</MaxFileSize> </triggeringPolicy> </appender> <!-- 日志输出级别 --> <!-- 线上环境,日志配置 --> <springProfile name="prod"> <root level="INFO"> <appender-ref ref="LOGSTASH"/> </root> </springProfile> <!-- 本地、开发环境,日志配置 可以写logback支持的所有节点 --> <springProfile name="dev,test"> <root level="INFO"> <appender-ref ref="LOGSTASH"/> <appender-ref ref="console"/> </root> </springProfile> </configuration>
@RestController
public class TestController {
private final static Logger logger= LoggerFactory.getLogger(TestController.class);
@GetMapping("/testELK")
public void test(){
logger.info("日志开始"+System.currentTimeMillis());
logger.info("日志结束"+System.currentTimeMillis());
}
}
访问完请求后,进入Stack Management找到索引管理,回看到一条新的记录存到es中。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。