go基于docker SDK,前端頁面動態顯示容器日志
需要用到的包
github.com/gin-gonic/gin
nhooyr.io/websocket
github.com/docker/docker/client
檔案目錄
├── docker
│ ├── conn.go
│ └── conn_test.go
├── go.mod
├── go.sum
├── html
│ └── index.html
└── main.go
靜態頁面
代碼展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
</style>
</head>
<body>
<div id="app">
<div>
<input type="button" value="查看" v-on:click="connWs">
</div>
<div v-for="msgn in msgList">
<span>${ msgn }</span>
</div>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
let gWs
let app = new Vue({
el: '#app',
data: {
msgList: [],
msg: "",
},
methods: {
connWs: function () {
let that = this
let host = location.host;
gWs = new WebSocket("ws://" + host + "/ws");
gWs.onopen = function () {
}
gWs.onmessage = function (evt) {
let receive = JSON.parse(evt.data)
that.msgList.push(receive)
}
gWs.onerror = function (evt) {
console.log("websocket 發生錯誤")
console.log(evt)
}
gWs.onclose = function () {
console.log("conn 已經關閉")
}
},
sendMessage: function () {
let msg = JSON.stringify({"content": this.msg})
gWs.send(msg)
this.msg = ""
}
},
delimiters: ['${', '}']
})
</script>
</html>
前端 WebSocket 的核心是建構式和幾個回呼函式,
- new WebSocket:創建一個 WebSocket 實體,提供服務端的 ws 地址,地址可以跟 HTTP 協議一樣,加上請求引數,注意,如果你使用 HTTPS 協議,相應的 WebSocket 地址協議要改為 wss;
- WebSocket.onopen:用于指定連接成功后的回呼函式;
- WebSocket.onerror:用于指定連接失敗后的回呼函式;
- WebSocket.onmessage:用于指定當從服務器接收到資訊時的回呼函式;
- WebSocket.onclose:用于指定連接關閉后的回呼函式;
在用戶點擊進入聊天室時,根據 Vue 系結的事件,會執行上面的代碼,發起 WebSocket 連接,服務端會將相關資訊通過 WebSocket 長連接回傳給客戶端,客戶端通過 WebSocket.onmessage 回呼進行處理,
得益于 Vue 的雙向系結,在資料顯示、事件系結等方面,處理起來很方便,
關于前端的實作,這里有幾點提醒下讀者:
- Vue 默認的分隔符是
{{}},和 Go 的一樣,避免沖突進行了修改; - WebSocket 有兩個方法:send 和 close,一個用來發送訊息,一個用于主動斷開鏈接;
server端
代碼展示
獲取容器日志(conn.go)
package docker
import (
"context"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"io"
"log"
)
func Conn() io.Reader {
//創建連接
client, err := client.NewClientWithOpts(client.WithHost("tcp://10.0.0.20:2375"))
if err != nil {
log.Println(err)
}
//使用連接獲取容器日志,回傳一個io.Reader
logs, err := client.ContainerLogs(context.TODO(), "xenodochial_blackburn", types.ContainerLogsOptions{
ShowStdout: true,
ShowStderr: true,
Follow: true,
})
return logs
}
方法 client.ContainerLogs(ctx context.Context, container string, options types.ContainerLogsOptions)回傳一個io.Reader和錯誤,第一個引數為背景關系,第二個引數為容器id或者容器名稱,第三個引數是容器日志選項結構體,
type ContainerLogsOptions struct {
ShowStdout bool // 是否回傳日志從stdout 默認false
ShowStderr bool // 是否回傳日志從stderr 默認false
Since string // 從這個時間回傳日志,時間型別為unix timestamp
Until string // 回傳這個時間前的日志,時間型別為unix timestamp
Timestamps bool // 是否在日志行前顯示時間戳,默認false
Follow bool // 是否回傳日志流,默認false
Tail string // 回傳日志行數,默認為all
Details bool
}
main.go
package main
import (
"bufio"
"github.com/gin-gonic/gin"
"kuludi-websocket/docker"
"log"
"net/http"
"nhooyr.io/websocket"
"nhooyr.io/websocket/wsjson"
)
func main() {
r := gin.Default()
r.LoadHTMLGlob("html/*")
r.GET("/", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", nil)
})
r.GET("/ws", func(c *gin.Context) {
//創建websocker連接
conn, err := websocket.Accept(c.Writer, c.Request, nil)
if err != nil {
log.Println("websocket accept error: ", err)
return
}
//獲取容器日志的io.Reader
reader := docker.Conn()
//bufio新建Reader
r := bufio.NewReader(reader)
for {
//回圈從reader中根據換行符讀取并轉換為string
s, err := r.ReadString('\n')
if err != nil {
log.Println("read err: ", err)
}
//發送資料
err = wsjson.Write(c.Request.Context(), conn, &s)
if err != nil {
log.Println("wsjson.writer err: ", err)
}
}
})
r.Run()
}
訪問測驗
訪問http://localhost:8080

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/385546.html
標籤:其他
上一篇:鯤鵬920流水線
下一篇:OSI 的七層模型
