Hướng dẫn Cài đặt ELK cho dự án Java Spring boot + Microservice
ELK là một bộ công cụ tích hợp cho phép bạn thu thập, lưu trữ, phân tích và tìm kiếm dữ liệu trong thời gian thực. Nó bao gồm ba thành phần chính:
- E - Elasticsearch: Một công cụ tìm kiếm dựa trên Apache Lucene cho phép bạn lưu trữ và tìm kiếm dữ liệu dạng JSON một cách nhanh chóng.
- L - Logstash: Một công cụ thu thập và xử lý dữ liệu cho phép bạn thu thập dữ liệu từ nhiều nguồn khác nhau và chuyển đổi nó thành định dạng có thể được Elasticsearch xử lý.
- K - Kibana: Một công cụ trực quan hóa dữ liệu cho phép bạn tạo các biểu đồ và đồ thị để giúp bạn hiểu dữ liệu của mình.
ELK được sử dụng rộng rãi trong nhiều ngành khác nhau, bao gồm:
- Log management: ELK có thể được sử dụng để thu thập và lưu trữ nhật ký từ các ứng dụng và hệ thống khác nhau. Điều này có thể giúp bạn phát hiện các sự cố, cải thiện hiệu suất và tuân thủ các quy định.
- Security analytics: ELK có thể được sử dụng để phân tích dữ liệu nhật ký để tìm dấu hiệu của các hoạt động đáng ngờ. Điều này có thể giúp bạn bảo vệ hệ thống của mình khỏi các cuộc tấn công mạng.
- Business intelligence: ELK có thể được sử dụng để phân tích dữ liệu từ các nguồn khác nhau, chẳng hạn như dữ liệu bán hàng, dữ liệu khách hàng và dữ liệu mạng xã hội. Điều này có thể giúp bạn đưa ra quyết định kinh doanh sáng suốt.
Dưới đây là một số ví dụ cụ thể về cách ELK có thể được sử dụng:
- Một công ty có thể sử dụng ELK để thu thập và lưu trữ nhật ký từ các máy chủ web của mình. Điều này có thể giúp họ phát hiện các lỗi hoặc sự cố với trang web của mình.
- Một ngân hàng có thể sử dụng ELK để phân tích dữ liệu giao dịch để tìm dấu hiệu gian lận. Điều này có thể giúp họ bảo vệ khách hàng của mình khỏi bị lừa đảo.
- Một công ty bán lẻ có thể sử dụng ELK để phân tích dữ liệu bán hàng để tìm hiểu thêm về hành vi mua sắm của khách hàng. Điều này có thể giúp họ cải thiện các chiến lược tiếp thị của mình.
ELK là một công cụ mạnh mẽ có thể được sử dụng để thu thập, lưu trữ, phân tích và tìm kiếm dữ liệu trong thời gian thực. Nó có thể được sử dụng cho nhiều mục đích khác nhau, bao gồm log management, security analytics và business intelligence. Tiếp theo, tôi sẽ hướng dẫn các bạn xây dựng và tích hợp ELK vào dự án Java spring của bạn:
1. Cài đặt elasticsearch
Đầu tiên, chúng ta cài elasticsearch theo Link tại website elastic. Tại đây, họ đã có hướng dẫn cụ thể để cài đặt elasticsearch trong từng môi trường, ở đây môi trường Host sử dụng Centos 7, do đó tôi sử dụng yum để cài đặt như sau:
- Bước 1: Đầu tiên, các bạn hãy chạy câu lệnh sau để thêm Elasticsearch public signing key vào máy của mình để package manager trust package từ Elasticsearch repository:
rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
- Bước 2: Tiếp theo, các bạn cần tạo một tệp
elasticsearch.repo
trong thư mục/etc/yum.repos.d/
để thêm Elasticsearch repository:
vi /etc/yum.repos.d/elasticsearch.repo
Thực hiện copy nội dung dưới đây vào file và lưu. Ở đây, tôi sử dụng phiên bản mới nhất của elasticsearch 8.9.0:
[elasticsearch]
name=Elasticsearch repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=0
autorefresh=1
type=rpm-md
- Bước 3: Bây giờ chúng ta có thể cài đặt và cấu hình elasticsearch bằng lệnh sau:
sudo yum install --enablerepo=elasticsearch elasticsearch
Mặc định thì elasticsearch sẽ chạy ở port 9200
và chỉ truy cập được bằng host: localhost
. Các bạn có thể chỉnh sửa cấu hình của elasticsearch ở /etc/elasticsearch/elasticsearch.yml
để thay đổi những điều này. Ở đây, Host có IP local: 10.0.0.99
do đó tôi thiết lậpHost: "10.0.0.99"
để các Host khác có thể kết nối được đến elasticsearch (điều này là cần thiết khi bạn muốn deploy Kibana hoặc logstash ở Host khác).
- Bước 4: Sau khi cấu hình xong, thì chúng ta cùng start elasticsearch service bằng câu lệnh sau:
sudo systemctl start elasticsearch
Các bạn kiểm tra trạng thái và check lỗi cài đặt của service elasticsearch bằng lệnh:
sudo systemctl status elasticsearch
Restart service elasticsearch bằng lệnh:
sudo systemctl restart elasticsearch
Stop service elasticsearch bằng lệnh:
sudo systemctl stop elasticsearch
Chạy elasticsearch lúc khởi động máy Host:
sudo systemctl enable elasticsearch
Nếu xảy ra lỗi phát sinh do bạn đã từng cài phiên bản khác của elasticsearch trước đó trên Host. Thực hiện uninstall elasticsearch
:
sudo yum remove elasticsearch
Và thực hiện xóa tất cả các file của elasticsearch và thực hiện lại các bước 1, 2, 3, 4
find / -name elasticsearch
rm -rf [tất cả thư mục elasticsearch]
Cuối cùng, gõ lệnh sau để thấy kết quả:
curl "http://10.0.0.99:9200"
[root@ELK ~]# curl "http://10.0.0.99:9200"
{
"name" : "ELK",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "yCULEQtpTyqf2RpSHiouZg",
"version" : {
"number" : "8.9.0",
"build_flavor" : "default",
"build_type" : "rpm",
"build_hash" : "8aa461beb06aa0417a231c345a1b8c38fb498a0d",
"build_date" : "2023-07-19T14:43:58.555259655Z",
"build_snapshot" : false,
"lucene_version" : "9.7.0",
"minimum_wire_compatibility_version" : "7.17.0",
"minimum_index_compatibility_version" : "7.0.0"
},
"tagline" : "You Know, for Search"
}
3. Cài đặt Kibana
Cài đặt Kibana khá tương tự như cài đặt elasticsearch. Chúng ta có thể tham khảo tại Link website elastic download kibana để xem hướng dẫn cụ thể để cài đặt kibana trong từng môi trường khác nhau. Trong bài viết này, chúng ta tiếp tục với môi trường Host Centos 7
. Do Elasticsearch public signing key
đã thực hiện tại Bước 1 trong cài đặt elasticsearch , nên không cần thực hiện lại ở cài đặt kibana. Chúng ta vẫn sử dụng yum để cài đặt như sau:
- Bước 1: Đầu tiên, các bạn cần tạo một tệp
kibana.repo
trong thư mục/etc/yum.repos.d/
để thêm kibana repository:
vi /etc/yum.repos.d/kibana.repo
Thực hiện copy nội dung dưới đây vào file và lưu. Ở đây, tôi sử dụng phiên bản mới nhất của kibana 8.9.0:
[kibana-8.x]
name=Kibana repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
- Bước 2: Bây giờ chúng ta có thể cài đặt và cấu hình kibana bằng lệnh sau:
sudo yum install kibana
Các bạn có thể vào đây để xem hướng dẫn cài đặt nâng cao. Trong bài viết này, chúng ta chỉ thiết lập các tham số sơ bản để kibana có thể hoạt động.
Chúng ta vào file /etc/kibana/kibana.yml
để thực hiện cấu hình cho kibana:
vi /etc/kibana/kibana.yml
Điều chỉnh port của server kibana thông qua
server.host: 5601
(mặc định là 5601)
Điều chỉnh IP của Host thông qua
server.host: "10.0.0.99"
(mặc định là localhost)
Điều chỉnh elasticsearch host thông qua elasticsearch.hots: [''http://10.0.0.99:9200"] (mặc định là [''http://localhost:9200"] )
Ở đây, Chúng ta deploy kibana trên cùng Host với elasticsearch.
- Bước 4: Sau khi cấu hình xong, thì chúng ta cùng start kibana service bằng câu lệnh sau:
sudo systemctl start kibana
Các bạn kiểm tra trạng thái và check lỗi cài đặt của service elasticsearch bằng lệnh:
sudo systemctl status kibana
Restart service elasticsearch bằng lệnh:
sudo systemctl restart kibana
Stop service elasticsearch bằng lệnh:
sudo systemctl stop kibana
Chạy elasticsearch lúc khởi động máy Host:
sudo systemctl enable kibana
OK, chúng ta truy cậphttp://10.0.0.99:5601
để xem kết quả nhá.
4. Cài đặt Logstash và chỉnh sửa logstash.conf
Với các bước để cài đặt tương tự như ElasticSearch và Kibana. Tạo file .repo
[logstash-8.x]
name=Elastic repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
Sau đó install:
sudo yum install logstash
Và các bước khác tương tư như cài đặt Elasticsearch và Kibana.
Tiếp theo chúng ta đến phần cấu hình cho logstash. Logstash config là một tập tin văn bản định nghĩa cách Logstash xử lý dữ liệu. Nó bao gồm các thành phần sau:
-
Pipeline: Pipeline là một tập hợp các giai đoạn mà dữ liệu đi qua khi nó đi qua Logstash. Các giai đoạn này bao gồm:
- Input: Giai đoạn này thu thập dữ liệu từ một nguồn bên ngoài, chẳng hạn như một tệp nhật ký, một dòng dữ liệu hoặc một dịch vụ HTTP.
- Filter: Giai đoạn này xử lý dữ liệu để làm cho nó phù hợp để lưu trữ hoặc phân tích. Ví dụ: các bộ lọc có thể được sử dụng để loại bỏ các hàng không mong muốn, chuyển đổi định dạng dữ liệu hoặc thêm thông tin bổ sung.
- Output: Giai đoạn này lưu trữ dữ liệu hoặc gửi nó đến một nguồn bên ngoài, chẳng hạn như Elasticsearch, Logstash hoặc một cơ sở dữ liệu.
-
Inputs: Input là các plugin chịu trách nhiệm thu thập dữ liệu từ các nguồn khác nhau. Một số input phổ biến bao gồm:
- File input: Thu thập dữ liệu từ các tệp nhật ký.
- TCP input: Thu thập dữ liệu từ một dịch vụ TCP.
- HTTP input: Thu thập dữ liệu từ một dịch vụ HTTP.
-
Filters: Filter là các plugin chịu trách nhiệm xử lý dữ liệu để làm cho nó phù hợp để lưu trữ hoặc phân tích. Một số filter phổ biến bao gồm:
- Grok filter: Chuyển đổi định dạng dữ liệu văn bản thành cấu trúc JSON.
- Date filter: Chuyển đổi các ngày và thời gian thành định dạng nhất quán.
- GeoIP filter: Xác định vị trí địa lý của một địa chỉ IP.
-
Outputs: Output là các plugin chịu trách nhiệm lưu trữ dữ liệu hoặc gửi nó đến một nguồn bên ngoài. Một số output phổ biến bao gồm:
- Elasticsearch output: Lưu trữ dữ liệu trong Elasticsearch.
- Logstash output: Gửi dữ liệu đến một máy chủ Logstash khác.
- File output: Lưu trữ dữ liệu trong một tệp.
Logstash config có thể được viết bằng YAML hoặc JSON. YAML là một định dạng dễ đọc và viết, trong khi JSON là một định dạng tiêu chuẩn được sử dụng bởi nhiều ứng dụng khác. File config của logstash phải được tạo trong đường dẫn /etc/logstash/conf.d/logstash.conf
. Dưới đây là một ví dụ về một Logstash config đơn giản:
input {
file {
path => "/var/log/syslog"
}
}
filter {
grok {
match => {
"message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{HOSTNAME:hostname} %{GREETING:greeting}"
}
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
}
}
Config này sẽ thu thập dữ liệu từ tệp /var/log/syslog
. Sau đó, nó sẽ sử dụng bộ lọc Grok để trích xuất các trường dữ liệu từ các hàng nhật ký. Cuối cùng, nó sẽ lưu trữ dữ liệu trong Elasticsearch.
Trong hướng dẫn này, chúng ta sẽ sử dụng một config logstash đơn giản sau:
input {
tcp {
port => 5000
host => "10.0.0.99"
codec => json
}
}
output {
elasticsearch {
hosts => ["http://10.0.0.99:9200"]
index => "microservice-%{app_name}-%{+YYYY.MM.dd}"
#user => "elastic"
#password => "changeme"
}
}
Ở đây, chúng ta sẽ không có filter, việc filter tôi đã xử lý trong code Java spring. Input được nhận qua socket với giao thức TCP tại cổng port = 5000
. Host là IP máy chủ cài logstash, tùy vào kiến trúc hệ thống của bạn để xác định nó là IP local hay public, ở đây tôi sử dụng IP local 10.0.0.99 và các micro-service có thể kết nối đến thông qua IP này. Log gửi từ các micro-service sang logstash dưới dạng json.
Ở phần output, chúng ta cần cấu hình các host của elasticsearch, ở đây sử dụng một host cho elasticsearch và được cài trên cùng host với logstash. Index được cấu hình để tạo ra các index trên elasticsearch theo format "microservice-%{app_name}-%{+YYYY.MM.dd}"
với app_name là tên của service, nó sẽ được fill vào khi log được đẩy vào logstash. +YYY.MM.dd là trường thêm thông tin thời gian theo ngay, điều này tương ứng với các index được tạo ra theo ngày và theo tên của micro-service.
Sau khi lưu cấu hình, logstash sẽ tự khởi động lại theo cấu hình mới bạn đã chỉnh sửa. Sử dụng sudo systemctl status kibana
để kiểm tra trạng thái và log rút gọn của logstash để xác định nó hoạt động tốt hoặc lỗi phát sinh. Có lỗi thì các bạn cứ mạnh dạn copy lỗi lên google hoặc chatGPT nhé.
5. Tạo dự án demo và file logback-spring.xml
Trong dự án micro-service, chúng ta thêm các dependency sau vào file POM của dự án:
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
Trong file application.properties hoặc application.yml, chúng ta thêm config sau:
logging:
logstash:
name: ABC
server: ${logstash.url}
Ở đây, logging.logstash.name là tên của micro-service. logging.logstash.server là host của logstash, trong ví dụ này là 10.0.0.99:5000 nhưng được truyền vào từ biến môi trường.
Tiếp theo, chúng ta tạo file logback-spring.xml trong resources
của dự án.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration scan="true">
<springProperty scope="context" name="server_logstash" source="logging.logstash.server"/>
<springProperty scope="context" name="app_name" source="logging.logstash.name"/>
<!-- cấu hình đẩy log lên logstash thông qua TCP-->
<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>${server_logstash}</destination>
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<mdc />
<context />
<logLevel />
<loggerName />
<threadName />
<message />
<logstashMarkers />
<stackTrace />
</providers>
</encoder>
</appender>
<!--cấu hình hiện log trên STDOUT-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%d{dd-MM-yyyy HH:mm:ss.SSS} %magenta([%thread]) %highlight(%-5level) %logger{36}.%M - %msg%n
</pattern>
</encoder>
</appender>
<!--Với mỗi profile sẽ hiển thị log ở các level khác nhau-->
<springProfile name="vbcs-uat, vbcs">
<root level="INFO">
<appender-ref ref="logstash"/>
<appender-ref ref="STDOUT"/>
</root>
<logger name="vn.com.viettel" level="DEBUG">
<appender-ref ref="logstash"/>
<appender-ref ref="STDOUT"/>
</logger>
</springProfile>
<!--Với mỗi profile sẽ hiển thị log ở các level khác nhau-->
<springProfile name="dev">
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
<logger name="vn.com.viettel" level="DEBUG">
<appender-ref ref="STDOUT"/>
</logger>
</springProfile>
</configuration>
Cuối cùng, các bạn tạo các Controller và thử nghiệm thôi:
import org.springframework.web.bind.annotation.RestController;
import static net.logstash.logback.marker.Markers.append;
@RestController
@RequestMapping(value = "/api")
public class HelloController {
@GetMapping(value = "/helloWorld")
public String helloWorld(){
string resp = "Xin chào các bạn, các bạn hiểu bài này của tôi chứ :)))))";
log.info(append("note", "log vui chơi thôi nhé"), resp);
return resp;
}
}
Trong java spring, các bạn tìm hiểu thêm markers để thêm các trường vào log nhé.
CẢM ƠN CÁC BẠN!!!!!!!!
All rights reserved