專案原始碼已上傳至 https://gitee.com/yangleliu/learning.git,免費索取
微信搜一搜【AI碼師】關注帥氣的我,回復【干貨領取】,領取2021最新面試資料一份
【前言】
開發任務后,提交代碼的那一刻,心情是自由自在……速度是八十邁……

以為接下來是游戲、逛GAI或暖烘烘的被窩,
然而,夢想何其豐滿,現實何其骨干,
總有測驗小姐姐教你緊急剎車,回頭做(改)人(bug):AI大師,你這不行啊!(吃瓜群眾排排坐,笑歪了嘴)
我低頭看了看自己的八塊腹肌:行不行可不是你說了算!
小姐姐也不是吃素的,擼起袖子,打開她的聯想十代:你行你連連報錯,毒奶隊友!
我:(⊙o⊙)…原來你說的是這個不行,我還以為……
小姐姐一臉疑惑:以為什么?真以為自己是大神了!
我清咳掉自己的尷尬,絕不認輸:我認為是你傳錯了引數,畢竟本大師在本地除錯時可沒有任何問題,
小姐姐久經沙場,從無敗績:不!可!能!是你是你就是你!我從來不會錯,
那一刻,我仿佛看到生理期的女朋友在面前閃現,內心是崩潰的,

我們倆就這樣爭執了很久,最后自然不出意料,繳械投降的還是我,
畢竟——
中華民族的傳統美(糟)德(粕)是:好男不跟女斗!
于是我只能去服務器上看看日志,但是日志內容累累如高山,多多如牛毛,足足3.5個g,無奈的我只好使用一堆linux騷命令,將檔案切割成一個個小檔案,好在最后終于找到了那次請求,排查后找到了原因,

通過這件事,我痛定思痛:如果有一個平臺能實時收集我們的日志,并能以可視化的界面呈現出來,那該多好啊!這樣我們就再也不用在那堆厚重的日志檔案里面找資料了,
【秘籍展示】
其實,這種神奇的平臺早就有了,那就是ELK,它是三大神獸Elasticsearch(搜索引擎), Logstash(日志收集), Kibana(可視化的web界面)的組合:
我們來看下架構圖:

對照架構圖,我們來看下這三大神獸的作業程序
- 用戶發送請求到我們的服務端
- 服務端將需要落日志的資料通過網路請求傳送到logstash
- logstash對資料進行過濾清洗后,再傳給Elasticsearch
- Elasticsearch 負責對資料創建索引,進行存盤
- 用戶通過訪問kibana的web頁面,能夠實時查看日志
好吧,秘籍都告訴你了,現在需要帶領你們去實戰了
【必備心法】
在打仗之前,我們需要士兵們必須具備以下技能,不然上了戰場后,只會被虐的體無完膚
- 了解elk三大組件
- 有實操過docker
- 本地有docker環境
- IDEA工具
- 配置相對高一點的武器(電腦),不然會崩潰的
【準備糧草】 準備一個Springboot專案
首先創建一個springboot專案,專案結構如下

引入專案必備依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.35</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.0</version>
</dependency>
創建一些基礎組件

創建切面,實作低耦合記錄日志
核心代碼
// 使用環繞通知
@Around("controllerLog()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
// 獲取當前請求物件
ServletRequestAttributes attributes =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 記錄請求資訊
ReqRspLog webLog = new ReqRspLog();
Object result = joinPoint.proceed();
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
// 通過反射,獲取入參和出參,封裝成json,落日志
long endTime = System.currentTimeMillis();
String urlStr = request.getRequestURL().toString();
webLog.setBasePath(StrUtil.removeSuffix(urlStr, URLUtil.url(urlStr).getPath()));
webLog.setIp(request.getRemoteUser());
webLog.setMethod(request.getMethod());
webLog.setParameter(getParameter(method, joinPoint.getArgs()));
webLog.setResult(result);
webLog.setSpendTime((int) (endTime - startTime));
webLog.setStartTime(startTime);
webLog.setUri(request.getRequestURI());
webLog.setUrl(request.getRequestURL().toString());
logger.info("{}", JSONUtil.parse(webLog));
return result;
}
創建測驗介面
@RestController
@RequestMapping("/api")
public class ApiController {
@GetMapping
public R<String> addLog(@RequestParam(value = "param1",required = false) String param1){
return R.success("你好,這段話將被日志記錄");
}
}
我們現在請求一下介面,會發現在控制臺列印出 這樣一段日志
{"method":"GET","uri":"/api","url":"http://localhost:8080/api","result":{"code":200,"data":"你好,這段話將被日志記錄","message":"操作成功"},"basePath":"http://localhost:8080","parameter":{"param1":"測驗ELK"},"startTime":1611529379353,"spendTime":9}
使用切面,實作日志記錄并列印到控制臺上已經完成了,現在我們按照架構圖,需要通過logstash把日志發送到es里面,接下來整合logstash實作傳送日志的功能
【招兵買馬】 整合Logstash
添加logstash依賴
<!--集成logstash-->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>5.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
編輯組態檔logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<!--應用名稱-->
<property name="APP_NAME" value="mall-admin"/>
<!--日志檔案保存路徑-->
<property name="LOG_FILE_PATH" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/logs}"/>
<contextName>${APP_NAME}</contextName>
<!--每天記錄日志到檔案appender-->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!--輸出到logstash的appender-->
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<!--可以訪問的logstash日志收集埠-->
<destination>127.0.0.1:4560</destination>
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder"/>
</appender>
<root level="info">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="LOGSTASH"/>
</root>
</configuration>
編輯完之后,專案結構是這樣的:

雖然在專案中已經集成了logstash功能,但是logstash還不知道把日志往哪里發,因為我們還沒有城池,
既然沒有,那就建造吧!
【搭建城池】 搭建ELK環境
ELK這里我使用dokcer-compose搭建,一個字:快!
首先我們約定一個根目錄:/user/aimashi/docker
按要求執行如下命令
mkdir -p /Users/yangle/docker
cd /Users/yangle/docker
mkdir elk_stanrd
cd elk_stanrd
mkdir logstash
cd logstash
vim logstash.conf
將以下檔案內容復制到logstash.conf
input {
tcp {
mode => "server"
host => "0.0.0.0"
port => 4560
codec => json_lines
}
}
output {
elasticsearch {
hosts => "es:9200"
index => "logstash-service-%{+YYYY.MM.dd}"
}
}
繼續執行如下命令
cd ../
vim docker-compose.yml
同樣將以下內容復制到組態檔中
version: '3'
services:
elasticsearch:
image: elasticsearch:6.4.0
container_name: elasticsearch
environment:
- "cluster.name=elasticsearch" #設定集群名稱為elasticsearch
- "discovery.type=single-node" #以單一節點模式啟動
- "ES_JAVA_OPTS=-Xms512m -Xmx512m" #設定使用jvm記憶體大小
volumes:
- /Users/yangle/docker/elk_stanrd/elasticsearch/plugins:/usr/share/elasticsearch/plugins #插件檔案掛載
- /Users/yangle/docker/elk_stanrd/elasticsearch/data:/usr/share/elasticsearch/data #資料檔案掛載
ports:
- 9200:9200
- 9300:9300
kibana:
image: kibana:6.4.0
container_name: kibana
links:
- elasticsearch:es #可以用es這個域名訪問elasticsearch服務
depends_on:
- elasticsearch #kibana在elasticsearch啟動之后再啟動
environment:
- "elasticsearch.hosts=http://es:9200" #設定訪問elasticsearch的地址
ports:
- 5601:5601
logstash:
image: logstash:6.4.0
container_name: logstash
volumes:
- ~/Users/yangle/docker/elk_stanrd/logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf #掛載logstash的組態檔
depends_on:
- elasticsearch #kibana在elasticsearch啟動之后再啟動
links:
- elasticsearch:es #可以用es這個域名訪問elasticsearch服務
ports:
- 4560:4560
到目前為止,搭建elk環境的準備作業已經完成,
現在需要啟動elk,在/Users/yangle/docker/elk_stanrd目錄下執行如下命令
docker-compose up -d
執行之后出現如下提示,則代表初創建成功

接下來,我們執行docker ps 來查看容器是否啟動

如果和圖中一樣,代表容器正常啟動,但是還需等待一分鐘左右,才能訪問可視化平臺
訪問地址 http://localhost:5601/

如果出現這個頁面,則代表elk已經搭建完成,現在,我們需要往里面塞點資料
【發起進攻】 發送請求
elk環境搭建完成之后,需要產生一點資料,該怎么做呢?
只要呼叫 http://localhost:8080/api?param1=測驗ELK 介面,多呼叫幾次,就會產生一些測驗資料,
除此之外,還需要做一些配置才能讓es去收集這些日志,用戶才能看到:


選擇欄位,創建索引

成功創建索引之后的界面


選擇logstash-servicez之后,界面是這樣的:

可以看到系統中的日志已經被收集上來了,試下搜索“你好”

所有包含“你好”的日志都被篩選出來,當然這里還可以有很多檢索條件,例如右上角有一個時間過濾檢索,我就不一一演示了,大家有興趣的話可以自己研究下,
倉庫:https://gitee.com/yangleliu/learning.git
樂于助人、大公無私的五好青年——我已將以上所有代碼全部上傳到git倉庫中,大家自行獲取,記得start啊
【戰后總結】
每個新技術的出現,都是為了解決某一類問題,
就像elk的出現,就是為了減少日漸脫發的代碼攻城獅們從海量日志中找資料的時間,節省出更多的精力放在業務處理上面,
有了elk,我們只需要在輸入框中,輕松輸入關鍵字,敲下回車,需要的資料就會呈現在我們面前,
測驗小姐姐等待的時間短了,心情好了,矛盾自然也就少了,
如此想來,如果能有一個平臺,將女友的十萬個情緒爆發的原因實時展現出來,那世界將是多么美好的明天!
噓~
如果大家感興趣的話,可以給我點個贊哦,我將會更有動力為大家帶來更好的實戰文章,后面將會對這個日志系統進行優化,引入更加成熟的架構filebeat+kafka+logstash+Elasticsearch+kibana,敬請期待!
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/253521.html
標籤:其他
