自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

別小看tail 命令,它難倒了技術(shù)總監(jiān)

系統(tǒng) Linux
tail命令能夠看到日志的滾動(dòng),非常方便。于是xjjdog想,既然我們能夠用這個(gè)命令,看到所有的日志,那能不能使用tail命令,做日志收集呢?

[[350507]]

 本文轉(zhuǎn)載自微信公眾號(hào)「小姐姐味道」,作者小姐姐養(yǎng)的狗 。轉(zhuǎn)載本文請(qǐng)聯(lián)系小姐姐味道公眾號(hào)。 

tail命令能夠看到日志的滾動(dòng),非常方便。于是xjjdog想,既然我們能夠用這個(gè)命令,看到所有的日志,那能不能使用tail命令,做日志收集呢?

想象歸想象,如果你想要一個(gè)快速的實(shí)時(shí)日志收集工具,那tail確實(shí)是個(gè)非常棒的工具。它比什么flume、logstatsh,比什么filebeat之類的,快捷的多。事實(shí)上,在工具缺乏的舊年代,我就曾經(jīng)這么干過,而且它工作的很好。

下面是一段使用Java語言書寫的代碼。我們可以按行讀取日志,然后使用自己喜歡的語言,做任何事情。

  1. import java.io.BufferedReader; 
  2. import java.io.InputStreamReader; 
  3.  
  4. public class TailReader { 
  5.     public static void main(String[] args) throws Exception { 
  6.         ProcessBuilder ps = new ProcessBuilder("tail""-f""/tmp/tail0"); 
  7.         //把錯(cuò)誤輸出也打印 
  8.         ps.redirectErrorStream(true); 
  9.         Process process = ps.start(); 
  10.  
  11.         //持續(xù)讀取tail的輸出 
  12.         try (BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()))) { 
  13.             String line; 
  14.             while ((line = in.readLine()) != null) { 
  15.                 setLogToKafka(line); 
  16.                 //注意這里不要產(chǎn)生異常,否則會(huì)打斷while循環(huán) 
  17.             } 
  18.         } 
  19.     } 
  20.  
  21.     //模擬發(fā)送到kafka,我們這里只簡(jiǎn)單的打印出來 
  22.     static void setLogToKafka(String line) { 
  23.         System.out.println(line); 
  24.     } 

主要的思想,就是使用Java的Process啟動(dòng)一個(gè)子tail進(jìn)程,一直監(jiān)控著文件的輸出。然后把標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤流,全部定向到BufferedReader中。接下來,你能做你想要做的任何事。

這有一定的風(fēng)險(xiǎn),假如tail命令被殺掉了,我們的Java程序就失去了作用。

程序很簡(jiǎn)單,但xjjdog在這里討論的卻不是這個(gè)簡(jiǎn)單的收集程序,而是tail命令的一些有趣的特性,你可以從中一窺一些日志收集工具對(duì)文件的特殊處理。

你知道tail -f和tail -F的區(qū)別么?

在回答這個(gè)問題之前,我們先回憶一下,Java常用的日志框架,對(duì)日志的處理。

 

  1. <configuration> 
  2.   <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"
  3.     <!-- Support multiple-JVM writing to the same log file --> 
  4.     <prudent>true</prudent> 
  5.     <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"
  6.       <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern> 
  7.       <maxHistory>30</maxHistory>  
  8.       <totalSizeCap>3GB</totalSizeCap> 
  9.     </rollingPolicy> 
  10.  
  11.     <encoder> 
  12.       <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern> 
  13.     </encoder> 
  14.   </appender>  
  15.  
  16.   <root level="DEBUG"
  17.     <appender-ref ref="FILE" /> 
  18.   </root> 
  19. </configuration> 

上面的配置,將在每晚凌晨的時(shí)候,滾動(dòng)形成一個(gè)新的文件。

那這個(gè)滾動(dòng),是如何做的呢?我們可以收工模擬這個(gè)過程。

  1. mv run.log run.2020-11-02.log 
  2. touch run.log 

測(cè)試一下

文件滾動(dòng),會(huì)生成新的文件,那tail命令還能跟蹤到么?

我們來測(cè)試一下。

第一步,創(chuàng)建要監(jiān)控的文件

  1. touch /tmp/tail0 

第二步,啟動(dòng)我們的Java代碼

第三步,生成一個(gè)不間斷的流

  1. watch -n 1  'echo `date` >> /tmp/tail0 ' 

上面的命令每隔1秒鐘,往我們的文件中打印一下當(dāng)前的日期,可以看到Java端已經(jīng)收到了這些數(shù)據(jù)。

第四步,模擬文件滾動(dòng)

  1. mv /tmp/tail0 /tmp/tail.bak 
  2. touch /tmp/tail0 

此時(shí),我們可以看到,Java端此時(shí)已經(jīng)接受不到數(shù)據(jù)了。

Why?

為了看到這是為什么,我們使用兩個(gè)命令來看一下進(jìn)程的一些狀態(tài)。

首先,使用ps命令,查看當(dāng)前的tail進(jìn)程。

  1. ps -ef|grep tail 
  2.   501 21374 21373   0  1:51PM ??         0:00.01 tail -f /tmp/tail0 

這正是我們的命令。

我們使用lsof命令去查看這個(gè)進(jìn)程所關(guān)聯(lián)的文件。

  1. lsof -p 21374 | awk '{print $4 "\t"  $9}' 
  2. FD NAME 
  3. cwd /tmp/ 
  4. txt /usr/bin/tail 
  5. txt /usr/lib/dyld 
  6. 3r /private/tmp/tail.bak 

我們看到tail進(jìn)程所監(jiān)控的文件,其實(shí)是tail.bak文件,已經(jīng)和tail命令沒什么關(guān)系了。

我們嘗試像tail.bak輸入一點(diǎn)內(nèi)容。

  1. echo "haha: xjjdog, i am from tail.bak" >> /tmp/tail.bak 

此時(shí)如我們所愿,Java進(jìn)程有反應(yīng)了,正常輸出了這句話。

怎么辦?

就如同我們問題中問的一樣,把tail -f換成tail -F就可以了。

tail -f的意思是,根據(jù)文件描述符進(jìn)行追蹤。

tail -F的意思是,根據(jù)文件名進(jìn)行追蹤,它會(huì)有重試的動(dòng)作。

所以,我們的日志收集程序,毫無疑問是根據(jù)日志名稱追蹤的,應(yīng)該把f改成F。

End

既然知道了這些小區(qū)別,我們就對(duì)日常工作中遇到的一些靈異問題有了解釋。

大家都知道rm命令,能夠刪除一個(gè)文件。如果有這個(gè)文件,正在被其他進(jìn)程所使用,那這些文件你看起來像是刪掉了,但它的內(nèi)容卻不釋放。

  1. lsof | grep deleted 

上面這個(gè)命令,能夠看到這些失控的文件。一般你kill掉相應(yīng)的進(jìn)程,這些句柄也就釋放了。但你刪除這些文件的本意,就是為了避免重啟應(yīng)用,這可真讓人糾結(jié)。

  1. cat /dev/null > logpath 

所以我們?cè)趧h除文件的時(shí)候,一般不會(huì)使用rm,而應(yīng)該使用重定向符號(hào)。將萬物皆空的/dev/null,發(fā)向它們。

作者簡(jiǎn)介:小姐姐味道 (xjjdog),一個(gè)不允許程序員走彎路的公眾號(hào)。聚焦基礎(chǔ)架構(gòu)和Linux。十年架構(gòu),日百億流量,與你探討高并發(fā)世界,給你不一樣的味道。我的個(gè)人微信xjjdog0,歡迎添加好友,進(jìn)一步交流。

 

責(zé)任編輯:武曉燕 來源: 小姐姐味道
相關(guān)推薦

2021-01-15 08:00:31

日志技術(shù)Log4j

2021-01-07 08:23:02

日志

2021-07-29 06:28:13

網(wǎng)絡(luò)網(wǎng)工網(wǎng)絡(luò)中斷

2023-09-20 08:03:32

JavaScript編程語言

2019-09-01 23:28:50

命令行Linux系統(tǒng)性能監(jiān)控

2020-02-25 22:52:42

工具代碼開發(fā)

2016-12-19 13:18:19

思科

2022-08-28 16:20:44

模型數(shù)學(xué)

2023-03-24 10:07:46

tail命令

2024-06-11 08:17:00

2022-09-07 07:08:28

架構(gòu)應(yīng)用場(chǎng)景數(shù)據(jù)流

2025-04-27 04:02:00

機(jī)器學(xué)習(xí)模型網(wǎng)絡(luò)

2009-04-05 10:26:47

2013-11-14 09:58:23

紅帽redhat

2021-08-20 10:41:47

開發(fā)工具代碼

2020-02-25 17:03:29

技術(shù)研發(fā)指標(biāo)

2020-09-01 09:31:38

程序員技能開發(fā)者

2009-08-04 09:53:21

linux創(chuàng)建文件命令tail命令自解壓

2009-05-26 16:43:41

虛擬化CIOIT

2024-06-06 12:50:55

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)