golang通过websocket将Jenkins构建日志实时输出到浏览器

要在Vue.js页面上实时展示Jenkins构建日志,并使用Go语言作为后端,你可以按照以下步骤实现:

1. Jenkins API 调用

首先,Jenkins 提供了 REST API 来获取构建日志。你可以通过以下 API 获取构建日志:

http://<jenkins-server>/job/<job-name>/<build-number>/logText/progressiveText

这个 API 支持分块读取日志内容。我们可以通过 start 参数指定从哪个位置开始读取日志,并通过响应头 X-More-Data 和 X-Text-Size 判断是否还有更多数据。

2. Go 后端实现

在 Go 后端中,你需要实现一个代理服务,调用 Jenkins API 并将日志内容实时推送到前端。

2.1 安装依赖

首先,安装必要的 Go 依赖:

go get -u github.com/gin-gonic/gin
go get -u github.com/gorilla/websocket

2.2 实现 WebSocket 后端服务

创建一个 WebSocket 服务,用于将 Jenkins 日志推送到前端。

package main

import (
	"bufio"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"log"
	"net/http"
	"strconv"
	"time"
)

func handleWebSocket(c *gin.Context) {
	var upgrader = websocket.Upgrader{
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
		CheckOrigin: func(r *http.Request) bool {
			log.Println("升级协议", r.Header["User-Agent"])
			return true
		},
	}

	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)

	if err != nil {
		log.Println("WebSocket upgrade error:", err)
		return
	}
	defer conn.Close()

	start := 0

	for {
		// 调用 Jenkins API 获取日志
		resp, err := HttpGetJenkinsBuildLog(start)
		defer resp.Body.Close()
		if err != nil {
			log.Println("Jenkins API error:", err)
			return
		}
		//b, _ := io.ReadAll(resp.Body)
		//if err := conn.WriteMessage(websocket.TextMessage, b); err != nil {
		//	log.Println("WebSocket write error:", err)
		//	return
		//}

		// 逐行读取日志内容
		scanner := bufio.NewScanner(resp.Body)
		for scanner.Scan() {
			line := scanner.Text()
			// 逐行推送到前端
			if err := conn.WriteMessage(websocket.TextMessage, []byte(line+"\n")); err != nil {
				log.Println("WebSocket write error:", err)
				return
			}
		}

		// 更新 start 位置
		start, _ = strconv.Atoi(resp.Header.Get("X-Text-Size"))

		// 如果没有更多数据,退出循环
		if resp.Header.Get("X-More-Data") != "true" {
			break
		}

		// 等待一段时间再继续请求
		time.Sleep(1 * time.Second)
	}
}

func main() {

	router := gin.Default()
	router.GET("/", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "ok",
		})
	})
	router.GET("/ws", handleWebSocket)
	router.Run() // 监听并在 0.0.0.0:8080 上启动服务

}

func HttpGetJenkinsBuildLog(start int) (res *http.Response, err error) {
	jenkinsURL := "https://192.168.10.100/job/oms/717/logText/progressiveText"
	request, err := http.NewRequest("GET", jenkinsURL, nil)
	if err != nil {
		log.Fatalln(err)
		return nil, err
	}
	//echo -n "admin:your jenkins token" | base64
	request.Header.Set("Authorization", "Basic YWRtaW46MTE0N2JiYWNkZjAzNThiZjJkOTRiZWRhOTQ2NWQyNGI5MA==")
	//发送请求给服务端,实例化一个客户端
	client := &http.Client{}
	res, err = client.Do(request)
	return
}

3. Vue.js 前端实现

在 Vue.js 中,使用 WebSocket 连接后端服务,并实时展示日志。当然也可以使用在线websocket测试工具,作者这里使用的:https://www.qianbo.com.cn/Tool/WebSocket/

golang通过websocket将Jenkins构建日志实时输出到浏览器
golang通过websocket将Jenkins构建日志实时输出到浏览器

3.1 安装依赖

如果你还没有安装 vue-websocket,可以通过以下命令安装:

npm install vue-native-websocket

3.4 在 Vue 组件中使用 WebSocket

<template>
  <div>
    <h1>Jenkins Build Log</h1>
    <pre>{{ log }}</pre>
  </div>
</template>

<script>
export default {
  data() {
    return {
      log: '',
      ws: null
    }
  },
  mounted() {
    this.ws = new WebSocket('ws://localhost:8080/ws')

    this.ws.onmessage = (event) => {
      // 逐行追加日志
      this.log += event.data
    }

    this.ws.onopen = () => {
      console.log('WebSocket connected')
    }

    this.ws.onclose = () => {
      console.log('WebSocket disconnected')
    }
  },
  beforeDestroy() {
    this.ws.close()
  }
}
</script>

<style scoped>
pre {
  white-space: pre-wrap;
  word-wrap: break-word;
  background: #f4f4f4;
  padding: 10px;
  border-radius: 5px;
  max-height: 500px;
  overflow-y: auto;
}
</style>

4. 运行和测试

1.启动 Go 后端服务:

go run main.go

2.启动 Vue.js 前端:

npm run serve

技术关键点

分块读取:通过 start 参数和 X-Text-Size 响应头实现分块读取日志。

逐行推送:使用 bufio.Scanner 逐行读取日志内容,并通过 WebSocket 逐行推送到前端。

轮询机制:通过 X-More-Data 响应头判断是否还有更多日志数据,如果没有则退出循环。

声明: 本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

给TA打赏
共{{data.count}}人
人已打赏
Golang

gorm实现Scanner/Valuer接口存取数组类型和自定义类型数据

2025-2-10 11:25:17

Golang

Goland接入deepseek实现AI编程,太酷了!

2025-2-12 9:43:58

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索