WebSocket+Nginx實現(xiàn)動態(tài)日志監(jiān)控-簡單版

由于工作需要我們想要實現(xiàn)一個從頁面能夠查看tomcat后臺日志的功能,我們有兩種方案:

  1. 將日志保存到mongo DB中,從頁面進行查看,mongo DB中的日志定期清理
  2. 通過WebSocket實現(xiàn)讀取后臺日志的功能,最簡單的就是利用tail命令實現(xiàn)

下面主要說一下我在通過WebSocket實現(xiàn)tail查看實時滾動日志時遇到的問題和解決方法

首先呢,我先在GitHub上找到了一個例子
文章的末尾有GitHub的地址,我down了下來, 需要注意三個地方

  1. pom中下面的dependency scope一定要設置成provided,避免與tomcat自帶的websocket-api沖突,我遇到問題時查了很多帖子,有些說沒有影響的,但是萬一要有影響呢,包沖突還是最好避免掉
        <dependency>
            <groupId>javax.websocket</groupId>
            <artifactId>javax.websocket-api</artifactId>
            <version>1.1</version>
            <scope>provided</scope>
        </dependency>
  1. index.html中的js腳本
<script>
    $(document).ready(function() {
        // 指定websocket路徑
        var websocket = new WebSocket('ws://192.168.80.128:8080/websocket/log');
        websocket.onmessage = function(event) {
            // 接收服務端的實時日志并添加到HTML頁面中
            $("#log-container div").append(event.data);
            // 滾動條滾動到最低部
            $("#log-container").scrollTop($("#log-container div").height() - $("#log-container").height());
        };
    });
</script>

其中
var websocket = new WebSocket('ws://192.168.80.128:8080/websocket/log');
這句的路徑一定要寫對,我從GitHub上拉下來的代碼, 是這樣的
var websocket = new WebSocket('ws://192.168.80.128:8080/log');
看著沒什么區(qū)別,因為你用本地服務器啟動時,這個路徑取決于你再IDE中的設置

Image 4.png

Image 5.png

如果路徑是像我上面那樣寫,就要按照ws://ip:port/applicationContext/requestMapping格式去寫,否則就會報無法連接的錯誤
如果你的application context是"/", 就按ws://ip:port/requestMapping格式寫就OK

我就是在這就出現(xiàn)的問題,因為我是想通過tail命令去讀tomcat logs下的catalina.out,所以我打好包,發(fā)到linux服務器進行測試時,報了404錯誤,F(xiàn)irefox 無法建立到 ws://192.168.80.128:8080/log 服務器的連接。
因為我打的包是websockettail-1.0.0.war

    <groupId>com.xxg</groupId>
    <artifactId>websockettail</artifactId>
    <version>1.0.0</version>

所以實際上默認的Application Context路徑并不是"/", 而是“websockettail-1.0.0”, 對應的ws路徑應為ws://192.168.80.128:8080/websockettail-1.0.0/log
改好之后就可以正常輸出了, 我測試的命令是"ifconfig"

Image 6.png

這里還是比較容易出錯的,一定要注意

  1. LogWebSocketController中的命令改成tail命令
    @OnOpen
    public void onOpen(Session session) {
        try {
            // 執(zhí)行tail -f命令
            process = Runtime.getRuntime().exec("tail -f /opt/XXX/logs/catalina.out -n 500");
            inputStream = process.getInputStream();

            // 一定要啟動新的線程,防止InputStream阻塞處理WebSocket的線程
            TailLogThread thread = new TailLogThread(inputStream, session);
            thread.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

這三個地方都改好后再放到Linux服務器上啟動,就沒問題了。

下面再說一下使用Nginx對Websocket進行反向代理的配置
公司的項目都是走的nginx反向代理,可以通過改nginx.conf來實現(xiàn)

修改Nginx主配置文件

$ vim /usr/local/nginx/conf/nginx.conf

# 在http上下文中增加如下配置,確保Nginx能處理正常http請求。

http{
  map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
  }

  upstream websocket {
    #ip_hash;
    server localhost:8010;  
    server localhost:8011;
  }

# 以下配置是在server上下文中添加,location指用于websocket連接的path。

  server {
    listen       80;
    server_name localhost;
    access_log /var/log/nginx/yourdomain.log;

    location / {
      proxy_pass http://websocket;
      proxy_read_timeout 300s;

      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;
        }
    }
}

最重要的就是在反向代理的配置中增加了如下兩行,其它的部分和普通的HTTP反向代理沒有任何差別。

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;

這里面的關鍵部分在于HTTP的請求中多了如下頭部:

Upgrade: websocket
Connection: Upgrade

這兩個字段表示請求服務器升級協(xié)議為WebSocket。服務器處理完請求后,響應如下報文:

狀態(tài)碼為101

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: upgrade

配置改好后執(zhí)行
nginx -s reload
就可以正常訪問


Image 7.png

參考博客地址:
http://xxgblog.com/2015/11/25/java-websocket-tail/
https://www.hi-linux.com/posts/42176.html

以上代碼可以從github上獲取, 我修改了一些東西,致敬原創(chuàng)者
https://github.com/CarolineHuang5954/websocket-tail-demo.git

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容