feat: add flag --log-plugin to turn on plugin logging

This commit is contained in:
debugtalk
2022-02-25 17:26:02 +08:00
parent d7be9c938e
commit 026384bbdb
14 changed files with 92 additions and 98 deletions

View File

@@ -70,7 +70,7 @@ func TestCallPluginFunction(t *testing.T) {
buildGoPlugin()
defer removeGoPlugin()
plugin, err := Init("debugtalk.so")
plugin, err := Init("debugtalk.so", false)
if err != nil {
t.Fatal(err)
}

View File

@@ -1,25 +1,62 @@
package common
import (
pluginHost "github.com/httprunner/hrp/plugin/host"
"os"
"os/exec"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-plugin"
"github.com/httprunner/hrp/plugin/shared"
pluginShared "github.com/httprunner/hrp/plugin/shared"
"github.com/rs/zerolog/log"
)
var client *plugin.Client
// HashicorpPlugin implements hashicorp/go-plugin
type HashicorpPlugin struct {
logOn bool // turn on plugin log
pluginShared.FuncCaller
cachedFunctions map[string]bool // cache loaded functions to improve performance
}
func (p *HashicorpPlugin) Init(path string) error {
loggerOptions := &hclog.LoggerOptions{
Name: shared.Name,
Output: os.Stdout,
}
if p.logOn {
loggerOptions.Level = hclog.Debug
} else {
loggerOptions.Level = hclog.Info
}
// launch the plugin process
client = plugin.NewClient(&plugin.ClientConfig{
HandshakeConfig: shared.HandshakeConfig,
Plugins: map[string]plugin.Plugin{
shared.Name: &shared.HashicorpPlugin{},
},
Cmd: exec.Command(path),
Logger: hclog.New(loggerOptions),
})
f, err := pluginHost.Init(path)
// Connect via RPC
rpcClient, err := client.Client()
if err != nil {
log.Error().Err(err).Str("path", path).Msg("load go hashicorp plugin failed")
log.Error().Err(err).Msg("connect plugin via RPC failed")
return err
}
p.FuncCaller = f
// Request the plugin
raw, err := rpcClient.Dispense(shared.Name)
if err != nil {
log.Error().Err(err).Msg("request plugin failed")
return err
}
// We should have a Function now! This feels like a normal interface
// implementation but is in fact over an RPC connection.
p.FuncCaller = raw.(shared.FuncCaller)
p.cachedFunctions = make(map[string]bool)
log.Info().Str("path", path).Msg("load hashicorp go plugin success")
@@ -55,6 +92,6 @@ func (p *HashicorpPlugin) Call(funcName string, args ...interface{}) (interface{
func (p *HashicorpPlugin) Quit() error {
// kill hashicorp plugin process
log.Info().Msg("quit hashicorp plugin process")
pluginHost.Quit()
client.Kill()
return nil
}

View File

@@ -28,7 +28,7 @@ func TestInitHashicorpPlugin(t *testing.T) {
buildHashicorpPlugin()
defer removeHashicorpPlugin()
plugin, err := Init("../../examples/debugtalk.bin")
plugin, err := Init("../../examples/debugtalk.bin", false)
if err != nil {
t.Fatal(err)
}

View File

@@ -23,7 +23,7 @@ type Plugin interface {
Quit() error // quit plugin
}
func Init(path string) (Plugin, error) {
func Init(path string, logOn bool) (Plugin, error) {
if path == "" {
return nil, nil
}
@@ -34,7 +34,9 @@ func Init(path string) (Plugin, error) {
pluginPath, err := locateFile(path, hashicorpGoPluginFile)
if err == nil {
// found hashicorp go plugin file
plugin = &HashicorpPlugin{}
plugin = &HashicorpPlugin{
logOn: logOn,
}
err = plugin.Init(pluginPath)
return plugin, err
}

View File

@@ -1,50 +0,0 @@
package host
import (
"os"
"os/exec"
hclog "github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-plugin"
"github.com/httprunner/hrp/plugin/shared"
)
var client *plugin.Client
func Init(path string) (shared.FuncCaller, error) {
// launch the plugin process
client = plugin.NewClient(&plugin.ClientConfig{
HandshakeConfig: shared.HandshakeConfig,
Plugins: map[string]plugin.Plugin{
shared.Name: &shared.HashicorpPlugin{},
},
Cmd: exec.Command(path),
Logger: hclog.New(&hclog.LoggerOptions{
Name: shared.Name,
Output: os.Stdout,
Level: hclog.Info,
}),
})
// Connect via RPC
rpcClient, err := client.Client()
if err != nil {
return nil, err
}
// Request the plugin
raw, err := rpcClient.Dispense(shared.Name)
if err != nil {
return nil, err
}
// We should have a Function now! This feels like a normal interface
// implementation but is in fact over an RPC connection.
function := raw.(shared.FuncCaller)
return function, nil
}
func Quit() {
client.Kill()
}