mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-14 15:57:37 +08:00
feat: add flag --log-plugin to turn on plugin logging
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
Reference in New Issue
Block a user