我們在開發中經常會寫日志,所以需要有個日志可視化界面管理,使用ELK可以實現高效集中化的日志管理與分析,提升性能穩定性,滿足安全合規要求,支持開發運維工作。
下述是我在搭建ELK時遇到的許許多多的坑,希望能替大家避開.
1. 環境準備
-
Elasticsearch: 用于存儲和檢索日志數據。
-
Logstash: 用于收集、處理和轉發日志數據。
-
Kibana: 用于可視化和分析日志數據。
2. 安裝 ELK 組件
你可以通過 Docker 快速安裝 ELK 組件:
# 拉取 ELK 鏡像
docker pull docker.elastic.co/elasticsearch/elasticsearch:7.10.0
docker pull docker.elastic.co/logstash/logstash:7.10.0
docker pull docker.elastic.co/kibana/kibana:7.10.0# 啟動 Elasticsearch
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.10.0# 啟動 Logstash
docker run -d --name logstash -p 5044:5044 docker.elastic.co/logstash/logstash:7.10.0# 啟動 Kibana
docker run -d --name kibana -p 5601:5601 --link elasticsearch:elasticsearch docker.elastic.co/kibana/kibana:7.10.0
若不通過Docker,可直接官網下載,如下:
2.1 下載Elasticsearch
? ? ? ?-?訪問?Elasticsearch 下載頁面,選擇適合的版本(如 8.17.3)。
? ? ? ? - 解壓下載的文件
? ? ? ? - 啟動 Elasticsearch:
????????????????默認情況下,Elasticsearch 會監聽?9200
?端口。
????????????????訪問?http://localhost:9200
,確認 Elasticsearch 是否正常運行。
? ? ? ?
????????避坑點1:
? ? ? ?在啟動時,發現老是報錯,查了很久都沒有結果,最終終于排查出來是環境變量配置的問題.
? ? ? ? 我們可以看下述它自帶的配置文件,文件中說明了若配置了ES_JAVA_HOME,則會使用此配置指向的JDK,但是此處JAVA_HOME和CLASS_PATH的環境變量會影響啟動,所以如果想要直接使用它自帶的JDK,需要將JAVA_HOME和CLASS_PATH的環境變量暫時注釋掉.
set SCRIPT=%0rem determine Elasticsearch home; to do this, we strip from the path until we
rem find bin, and then strip bin (there is an assumption here that there is no
rem nested directory under bin also named bin)
for %%I in (%SCRIPT%) do set ES_HOME=%%~dpI:es_home_loop
for %%I in ("%ES_HOME:~1,-1%") do set DIRNAME=%%~nxI
if not "%DIRNAME%" == "bin" (for %%I in ("%ES_HOME%..") do set ES_HOME=%%~dpfIgoto es_home_loop
)
for %%I in ("%ES_HOME%..") do set ES_HOME=%%~dpfIrem now set the classpath
set ES_CLASSPATH=!ES_HOME!\lib\*
set ES_MODULEPATH=!ES_HOME!\lib
set LAUNCHERS_CLASSPATH=!ES_CLASSPATH!;!ES_HOME!\lib\launchers\*;!ES_HOME!\lib\java-version-checker\*
set SERVER_CLI_CLASSPATH=!ES_CLASSPATH!;!ES_HOME!\lib\tools\server-cli\*set HOSTNAME=%COMPUTERNAME%if not defined ES_PATH_CONF (set ES_PATH_CONF=!ES_HOME!\config
)rem now make ES_PATH_CONF absolute
for %%I in ("%ES_PATH_CONF%..") do set ES_PATH_CONF=%%~dpfIset ES_DISTRIBUTION_TYPE=zipcd /d "%ES_HOME%"rem now set the path to java, pass "nojava" arg to skip setting ES_JAVA_HOME and JAVA
if "%1" == "nojava" (exit /b
)rem comparing to empty string makes this equivalent to bash -v check on env var
rem and allows to effectively force use of the bundled jdk when launching ES
rem by setting ES_JAVA_HOME=
if defined ES_JAVA_HOME (set JAVA="%ES_JAVA_HOME%\bin\java.exe"set JAVA_TYPE=ES_JAVA_HOMEif not exist !JAVA! (echo "could not find java in !JAVA_TYPE! at !JAVA!" >&2exit /b 1)rem check the user supplied jdk version!JAVA! -cp "%ES_HOME%\lib\java-version-checker\*" "org.elasticsearch.tools.java_version_checker.JavaVersionChecker" || exit /b 1
) else (rem use the bundled JDK (default)set JAVA="%ES_HOME%\jdk\bin\java.exe"set "ES_JAVA_HOME=%ES_HOME%\jdk"set JAVA_TYPE=bundled JDK
)rem do not let JAVA_TOOL_OPTIONS slip in (as the JVM does by default)
if defined JAVA_TOOL_OPTIONS (echo warning: ignoring JAVA_TOOL_OPTIONS=%JAVA_TOOL_OPTIONS%set JAVA_TOOL_OPTIONS=
)rem warn that we are not observing the value of $JAVA_HOME
if defined JAVA_HOME (echo warning: ignoring JAVA_HOME=%JAVA_HOME%; using %JAVA_TYPE% >&2
)rem JAVA_OPTS is not a built-in JVM mechanism but some people think it is so we
rem warn them that we are not observing the value of %JAVA_OPTS%
if defined JAVA_OPTS ((echo|set /p=warning: ignoring JAVA_OPTS=%JAVA_OPTS%; )echo pass JVM parameters via ES_JAVA_OPTS
)cd %ES_HOME%
成功啟動后,訪問地址效果:
2.2 安裝 Logstash
-
下載 Logstash:
-
訪問?Logstash 下載頁面,選擇適合的版本(如 8.17.3)。
-
解壓下載的文件
-
??使用?-e
?參數進行簡單測試
bin/logstash -e 'input { stdin {} } output { stdout { codec => rubydebug } }'
若啟動成功,可訪問http://localhost:9600/看是否有json數據返回即可.
到此處,說明下載的Logstash沒問題.
????????
????????2.?配置文件編寫
????????Logstash 的配置文件分為兩類:主配置文件(logstash.conf
)和管道配置文件(pipelines.yml
)。
????????
????????1)logstash.conf
?配置文件
logstash.conf
是 Logstash 的核心配置文件,定義了數據的輸入、過濾和輸出。它通常位于 Logstash 安裝目錄的 config
文件夾中。
-
輸入(Input):定義數據源,例如日志文件、網絡端口等。
示例:input {file {path => "/var/log/*.log"start_position => "beginning"} }
-
過濾(Filter):對數據進行解析和處理,例如使用 Grok 插件解析日志。
示例:filter {grok {match => { "message" => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request}" }} }
-
輸出(Output):定義數據的輸出目標,例如 Elasticsearch、文件或控制臺。
示例: -
output {elasticsearch {hosts => ["http://localhost:9200"]index => "logstash-%{+YYYY.MM.dd}"}stdout {codec => rubydebug} }
????????(2)pipelines.yml
?配置文件
pipelines.yml
文件用于定義管道的配置,包括管道的名稱和配置文件路徑。它通常位于 Logstash 安裝目錄的 config
文件夾中。
- pipeline.id: mainpath.config: "config/logstash-sample.conf"
避坑點2:
此處不知道怎么配置都會顯示 No configuration found in the configured sources. 一直沒找出原因
重新從配置的信息中找原因,最終發現是conf配置文件的問題.
logstash-sample.conf? 示例如下:
input {# 示例3:HTTP 接收數據http {port => 8080codec => "json"}
}output {# 示例1:輸出到 Elasticsearch(帶安全認證)elasticsearch {hosts => ["http://localhost:9200"]index => "logs-%{+YYYY.MM.dd}"user => "elastic"password => "password"ssl => false}
}
?logstash.yml? 此文件需要配置上去,否則會一直報錯,很多教程中沒有指這一點!!!
# 節點名稱(用于集群標識)
node.name: "my-logstash-node"# 管道配置路徑(可指定多個管道)
path.config: "config/pipelines/*.conf"# 數據存儲路徑(隊列和持久化數據)
path.data: "data/"# 日志路徑
path.logs: "logs/"# HTTP API 配置(用于監控和管理)
api.http.host: "0.0.0.0"
api.http.port: 9600# 性能調優(根據硬件調整線程和批處理大小)
pipeline.workers: 2 # 工作線程數(建議等于CPU核心數)
pipeline.batch.size: 125 # 每批處理事件數
上述坑點避開后,基本上都能啟動了。效果如下:
2.3 安裝 Kibana
-
下載 Kibana:
-
訪問?Kibana 下載頁面,選擇適合的版本(如 8.17.3)。
-
解壓下載的文件
-
-
配置 Kibana:
編輯?config/kibana.yml
?文件,設置 Elasticsearch 的地址:elasticsearch.hosts: ["http://localhost:9200"] server.host: "0.0.0.0"
-
啟動 Kibana:
./bin/kibana
-
Kibana 會監聽?
5601
?端口。 -
訪問?
http://localhost:5601
,確認 Kibana 是否正常運行。
-
首次啟動時,報了下述錯誤:
?從日志上看起來應該是配置問題,依舊先檢查配置文件?config/kibana.yml
原來是按上述的配置文件內容是不足夠的,所以我又添加了一些配置信息(Elastic連接信息、Kibana安全參數等)
# 配置Kibana服務運行的主機地址,允許遠程訪問時可設置為"0.0.0.0"
server.host: "localhost"# 配置Kibana服務運行的端口
server.port: 5601# 配置Elasticsearch的地址,如果有多個節點,可以像下面這樣列出
elasticsearch.hosts:- "http://localhost:9200"# 啟用Kibana的安全功能
xpack.security.enabled: true# 配置Elasticsearch的用戶名和密碼
elasticsearch.username: "elastic"
elasticsearch.password: "your_password"
按上述配置文件重啟后,依舊報錯:
原因:kibana連接Elasticsearch不允許直接使用超級賬號elastics,需要按照下述方式創建專用賬號
使用elasticsearch-service-tokens
?CLI工具
-
打開終端或命令提示符。
-
運行以下命令來創建服務賬號令牌:
bash復制
elasticsearch-service-tokens create elastic/kibana <token_name>
其中
elastic/kibana
是Kibana的服務賬號,<token_name>
是你為這個令牌指定的名稱,例如kibana-token
。 -
該命令會在
$ES_HOME/config/service_tokens
文件中保存新的服務令牌,并在終端輸出Bearer令牌。
# 配置Kibana服務運行的主機地址,允許遠程訪問時可設置為"0.0.0.0"
server.host: "localhost"# 配置Kibana服務運行的端口
server.port: 5601# 配置Elasticsearch的地址,如果有多個節點,可以像下面這樣列出
elasticsearch.hosts:- "http://localhost:9200"elasticsearch.serviceAccountToken: "AAEAAWVsYXN0aXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1NldHZlZjdm9B"
根據生成的TOKEN,按上述最終的配置信息,重啟服務即可,訪問localhost:5601,出現下述界面說明成功了!
3. 集成項目
上述三個服務全部安裝完成之后,我們就可以開始對接項目了.
Spring Boot 項目配置
3.1 添加依賴
在?pom.xml
?中添加依賴:
<dependency><groupId>net.logstash.logback</groupId><artifactId>logstash-logback-encoder</artifactId><version>6.6</version>
</dependency>
3.2 添加配置
在?src/main/resources
?目錄下創建?logback-spring.xml
?文件(此處需注意,若已存在logback相關xml文件,則不需要重新創建):
<?xml version="1.0" encoding="UTF-8"?>
<configuration><include resource="org/springframework/boot/logging/logback/base.xml"/><appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender"><destination>localhost:5044</destination><encoder class="net.logstash.logback.encoder.LogstashEncoder"/></appender><root level="INFO"><appender-ref ref="LOGSTASH"/><appender-ref ref="console"/></root>
</configuration>
添加上述配置,注意root節點不能重復,重復的話會以最后一個root節點為主.
3.3?測試:
在你的項目中將日志打印出來
logger.info("用戶列表日志記錄!!!");
若上述有問題,則需要檢查是否已經創建了索引,先檢查logstash的配置文件:
input {tcp {port => 5044codec => json_lines}
}output {# 示例1:輸出到 Elasticsearch(帶安全認證)elasticsearch {hosts => ["http://localhost:9200"]index => "springboot-logs-%{+YYYY.MM.dd}"user => "elastic"password => "XXX"ssl => false}
}
此處的tcp監聽是監聽springboot配置文件中對應的端口.
3.4?查看索引
output中的index則是elastic的索引名稱,訪問此路徑確認索引是否創建成功:http://localhost:9200/_cat/indices?v
若創建成功,在下圖中就能看到了
3.5?查看日志
有了索引,我們就可以在kibana中查看了,如下圖:
Stack Management? ->?Data views -> Create data view
Discover 中搜索并查看,如下圖:
這樣我們整個過程就結束了,也成功使用ELK查看到日志了!