adjust cover project structure

This commit is contained in:
lyyyuna 2021-06-17 19:53:00 +08:00
parent b3647fd9d9
commit 4ae7fa3d31
9 changed files with 70 additions and 15 deletions

View File

@ -1,7 +1,7 @@
package cmd package cmd
import ( import (
"github.com/qiniu/goc/v2/pkg/build" "github.com/qiniu/goc/v2/pkg/server"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@ -22,6 +22,5 @@ func init() {
} }
func serve(cmd *cobra.Command, args []string) { func serve(cmd *cobra.Command, args []string) {
b := build.NewBuild(cmd, args) server.RunGocServerUntilExit(8080)
b.Build()
} }

View File

@ -1,6 +1,7 @@
package build package build
import ( import (
"github.com/qiniu/goc/v2/pkg/cover"
"github.com/qiniu/goc/v2/pkg/flag" "github.com/qiniu/goc/v2/pkg/flag"
"github.com/qiniu/goc/v2/pkg/log" "github.com/qiniu/goc/v2/pkg/log"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -31,6 +32,9 @@ func NewBuild(cmd *cobra.Command, args []string) *Build {
// 3. build the project in temp. // 3. build the project in temp.
func (b *Build) Build() { func (b *Build) Build() {
b.copyProjectToTmp() b.copyProjectToTmp()
defer b.clean() // defer b.clean()
log.Donef("project copied to temporary directory") log.Donef("project copied to temporary directory")
// inject cover vars
cover.Inject()
} }

View File

@ -6,6 +6,7 @@ import (
"io" "io"
"os" "os"
"os/exec" "os/exec"
"path"
"path/filepath" "path/filepath"
"strings" "strings"
@ -40,7 +41,7 @@ func (b *Build) readProjectMetaInfo() {
// get cur pkg dir in the corresponding tmp dir // get cur pkg dir in the corresponding tmp dir
config.GocConfig.TmpPkgDir = filepath.Join(config.GocConfig.TmpModProjectDir, config.GocConfig.CurPkgDir[len(config.GocConfig.CurModProjectDir):]) config.GocConfig.TmpPkgDir = filepath.Join(config.GocConfig.TmpModProjectDir, config.GocConfig.CurPkgDir[len(config.GocConfig.CurModProjectDir):])
// get GlobalCoverVarImportPath // get GlobalCoverVarImportPath
config.GocConfig.GlobalCoverVarImportPath = tmpFolderName(config.GocConfig.CurModProjectDir) config.GocConfig.GlobalCoverVarImportPath = path.Join(config.GocConfig.ImportPath, tmpFolderName(config.GocConfig.CurModProjectDir))
log.Donef("project meta information parsed") log.Donef("project meta information parsed")
} }

View File

@ -2,6 +2,7 @@ package cover
import ( import (
"os" "os"
"path"
"path/filepath" "path/filepath"
"github.com/qiniu/goc/v2/pkg/config" "github.com/qiniu/goc/v2/pkg/config"
@ -104,15 +105,15 @@ func getPkgTmpDir(pkgDir string) string {
// - xxx.go // - xxx.go
// - yyy_package // - yyy_package
// - main.go // - main.go
// - goc_http_cover_apis_auto_generated_11111_22222_bridge.go // - goc-http-cover-apis-auto-generated-11111-22222-bridge.go
// - goc_http_cover_apis_auto_generated_11111_22222_package // - goc-http-cover-apis-auto-generated-11111-22222-package
// | // |
// -- init.go // -- init.go
// //
// 11111_22222_bridge.go just import 11111_22222_package, where package contains ws handlers. // 11111_22222_bridge.go just import 11111_22222_package, where package contains ws handlers.
// 使用 bridge.go 文件是为了避免插桩逻辑中的变量名污染 main 包 // 使用 bridge.go 文件是为了避免插桩逻辑中的变量名污染 main 包
func injectCoverHandler(where string, covers []*config.PackageCover) { func injectCoverHandler(where string, covers []*config.PackageCover) {
injectPkgName := "goc_http_cover_apis_auto_generated_11111_22222_package" injectPkgName := "goc-http-cover-apis-auto-generated-11111-22222-package"
wherePkg := filepath.Join(where, injectPkgName) wherePkg := filepath.Join(where, injectPkgName)
err := os.MkdirAll(wherePkg, os.ModePerm) err := os.MkdirAll(wherePkg, os.ModePerm)
if err != nil { if err != nil {
@ -120,7 +121,7 @@ func injectCoverHandler(where string, covers []*config.PackageCover) {
} }
// create bridge file // create bridge file
whereBridge := filepath.Join(where, "goc_http_cover_apis_auto_generated_11111_22222_bridge.go") whereBridge := filepath.Join(where, "goc-http-cover-apis-auto-generated-11111-22222-bridge.go")
f, err := os.Create(whereBridge) f, err := os.Create(whereBridge)
if err != nil { if err != nil {
log.Fatalf("fail to create cover bridge file in temporary project: %v", err) log.Fatalf("fail to create cover bridge file in temporary project: %v", err)
@ -144,6 +145,7 @@ func injectCoverHandler(where string, covers []*config.PackageCover) {
if err != nil { if err != nil {
log.Fatalf("fail to create cover handlers in temporary project: %v", err) log.Fatalf("fail to create cover handlers in temporary project: %v", err)
} }
defer f.Close()
tmplData := struct { tmplData := struct {
Covers []*config.PackageCover Covers []*config.PackageCover
@ -160,6 +162,25 @@ func injectCoverHandler(where string, covers []*config.PackageCover) {
} }
} }
// injectGlobalCoverVarFile 写入所有插桩变量的全局定义至单独一个文件
func injectGlobalCoverVarFile(decl string) { func injectGlobalCoverVarFile(decl string) {
globalCoverVarPackage := path.Base(config.GocConfig.GlobalCoverVarImportPath)
globalCoverDef := filepath.Join(config.GocConfig.TmpModProjectDir, globalCoverVarPackage)
err := os.MkdirAll(globalCoverDef, os.ModePerm)
if err != nil {
log.Fatalf("fail to create global cover definition package dir: %v", err)
}
coverFile, err := os.Create(filepath.Join(globalCoverDef, "cover.go"))
if err != nil {
log.Fatalf("fail to create global cover definition file: %v", err)
}
defer coverFile.Close()
packageName := "package coverdef\n\n"
_, err = coverFile.WriteString(packageName + decl)
if err != nil {
log.Fatalf("fail to write to global cover definition file: %v", err)
}
} }

View File

@ -9,7 +9,7 @@ const coverBridge = `
package main package main
import _ {{.CoverImportPath | printf "%q"}} import _ "{{.CoverImportPath}}"
` `
var coverMainTmpl = template.Must(template.New("coverMain").Parse(coverMain)) var coverMainTmpl = template.Must(template.New("coverMain").Parse(coverMain))
@ -17,12 +17,12 @@ var coverMainTmpl = template.Must(template.New("coverMain").Parse(coverMain))
const coverMain = ` const coverMain = `
// Code generated by goc system. DO NOT EDIT. // Code generated by goc system. DO NOT EDIT.
package {{.Package | printf ".%q"}} package cover
import ( import (
"log" "log"
_cover {{.GlobalCoverVarImportPath | printf "%q"}} _cover "{{.GlobalCoverVarImportPath}}"
) )
func init() { func init() {

View File

@ -4,6 +4,7 @@ import (
"net/http" "net/http"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/qiniu/goc/v2/pkg/log"
) )
// listServices return all service informations // listServices return all service informations
@ -23,3 +24,24 @@ func (gs *gocServer) listServices(c *gin.Context) {
"items": services, "items": services,
}) })
} }
// getProfiles get and merge all services' informations
func (gs *gocServer) getProfiles(c *gin.Context) {
gs.rpcClients.Range(func(key, value interface{}) bool {
service, ok := value.(gocCoveredClient)
if !ok {
return false
}
var req GetProfileReq = "getprofile"
var res GetProfileRes
err := service.rpc.Call("GocAgent.GetProfile", req, &res)
if err != nil {
log.Errorf("fail to get profile from: %v, reasson: %v", service.Id, err)
return true
}
log.Infof("res: %v", res)
return true
})
}

View File

@ -8,10 +8,14 @@ import (
) )
const ( const (
PongWait = 60 * time.Second PongWait = 20 * time.Second
PingWait = 30 * time.Second PingWait = 10 * time.Second
) )
type GetProfileReq string
type GetProfileRes string
type ReadWriteCloser struct { type ReadWriteCloser struct {
ws *websocket.Conn ws *websocket.Conn
r io.Reader r io.Reader

View File

@ -88,9 +88,13 @@ func (gs *gocServer) serveRpcStream(c *gin.Context) {
break break
} }
} }
// 从维护的 websocket 链接中移除
gs.rpcClients.Delete(clientId)
gs.wsclose(ws, 1) gs.wsclose(ws, 1)
}() }()
log.Infof("one client established, %v, cmdline: %v, pid: %v, hostname: %v", ws.RemoteAddr(), cmdline, pid, hostname)
// new rpc client // new rpc client
// 在这里 websocket server 作为 rpc 的客户端, // 在这里 websocket server 作为 rpc 的客户端,
// 发送 rpc 请求, // 发送 rpc 请求,

View File

@ -47,7 +47,7 @@ func RunGocServerUntilExit(port int) {
r := gin.Default() r := gin.Default()
v2 := r.Group("/v2") v2 := r.Group("/v2")
{ {
v2.GET("/cover/profile", nil) v2.GET("/cover/profile", gs.getProfiles)
v2.DELETE("/cover/profile", nil) v2.DELETE("/cover/profile", nil)
v2.GET("/services", gs.listServices) v2.GET("/services", gs.listServices)