diff --git a/pkg/cmd/grafana-server/server.go b/pkg/cmd/grafana-server/server.go index b74046e542f..949d324ec50 100644 --- a/pkg/cmd/grafana-server/server.go +++ b/pkg/cmd/grafana-server/server.go @@ -68,13 +68,12 @@ func (g *GrafanaServerImpl) Start() { login.Init() social.NewOAuthService() plugins.Init() - client, err := tsdbplugins.Init() - defer client.Kill() - + pluginClient, err := tsdbplugins.Init() if err != nil { g.log.Error("failed to start plugins", "error", err) g.Shutdown(1, "Startup failed") } + defer pluginClient.Kill() if err := provisioning.Init(g.context, setting.HomePath, setting.Cfg); err != nil { logger.Error("Failed to provision Grafana from config", "error", err) diff --git a/pkg/tsdb/plugins/log-wrapper.go b/pkg/tsdb/plugins/log-wrapper.go new file mode 100644 index 00000000000..8a046f118a7 --- /dev/null +++ b/pkg/tsdb/plugins/log-wrapper.go @@ -0,0 +1,38 @@ +package plugins + +import ( + "log" + + glog "github.com/grafana/grafana/pkg/log" + hclog "github.com/hashicorp/go-hclog" +) + +type logWrapper struct { + logger glog.Logger +} + +func (lw logWrapper) Trace(msg string, args ...interface{}) {} +func (lw logWrapper) Debug(msg string, args ...interface{}) {} +func (lw logWrapper) Info(msg string, args ...interface{}) {} +func (lw logWrapper) Warn(msg string, args ...interface{}) {} +func (lw logWrapper) Error(msg string, args ...interface{}) {} + +func (lw logWrapper) IsTrace() bool { return true } +func (lw logWrapper) IsDebug() bool { return true } +func (lw logWrapper) IsInfo() bool { return true } +func (lw logWrapper) IsWarn() bool { return true } +func (lw logWrapper) IsError() bool { return true } + +func (lw logWrapper) With(args ...interface{}) hclog.Logger { + return logWrapper{logger: glog.New("logger", args)} +} +func (lw logWrapper) Named(name string) hclog.Logger { + return logWrapper{logger: glog.New(name)} +} +func (lw logWrapper) ResetNamed(name string) hclog.Logger { + return logWrapper{logger: glog.New(name)} +} + +func (lw logWrapper) StandardLogger(ops *hclog.StandardLoggerOptions) *log.Logger { + return nil +} diff --git a/pkg/tsdb/plugins/mock_tsdb_plugin/Makefile b/pkg/tsdb/plugins/mock_tsdb_plugin/Makefile new file mode 100644 index 00000000000..b288077e604 --- /dev/null +++ b/pkg/tsdb/plugins/mock_tsdb_plugin/Makefile @@ -0,0 +1,4 @@ +all: build + +build: + go build -o simple-plugin . \ No newline at end of file diff --git a/pkg/tsdb/plugins/mock_tsdb_plugin/plugin.go b/pkg/tsdb/plugins/mock_tsdb_plugin/plugin.go new file mode 100644 index 00000000000..78337d0225d --- /dev/null +++ b/pkg/tsdb/plugins/mock_tsdb_plugin/plugin.go @@ -0,0 +1,39 @@ +package main + +import ( + "golang.org/x/net/context" + + "log" + + "github.com/grafana/grafana/pkg/tsdb/plugins/proto" + shared "github.com/grafana/grafana/pkg/tsdb/plugins/shared" + plugin "github.com/hashicorp/go-plugin" +) + +type Tsdb struct { + plugin.NetRPCUnsupportedPlugin +} + +func (Tsdb) Get(ctx context.Context, req *proto.TsdbRequest) (*proto.TsdbResponse, error) { + log.Print("Tsdb.Get() from plugin") + + return &proto.TsdbResponse{ + MetaJson: "from plugins! meta meta", + }, nil +} + +func main() { + plugin.Serve(&plugin.ServeConfig{ + HandshakeConfig: plugin.HandshakeConfig{ + ProtocolVersion: 1, + MagicCookieKey: "BASIC_PLUGIN", + MagicCookieValue: "hello", + }, + Plugins: map[string]plugin.Plugin{ + "tsdb_mock": &shared.TsdbPluginImpl{Plugin: &Tsdb{}}, + }, + + // A non-nil value here enables gRPC serving for this plugin... + GRPCServer: plugin.DefaultGRPCServer, + }) +} diff --git a/pkg/tsdb/plugins/mock_tsdb_plugin/simple-plugin b/pkg/tsdb/plugins/mock_tsdb_plugin/simple-plugin new file mode 100755 index 00000000000..7ad8b437777 Binary files /dev/null and b/pkg/tsdb/plugins/mock_tsdb_plugin/simple-plugin differ diff --git a/pkg/tsdb/plugins/plugins.go b/pkg/tsdb/plugins/plugins.go index 50bb6dc21a8..e8db53610a1 100644 --- a/pkg/tsdb/plugins/plugins.go +++ b/pkg/tsdb/plugins/plugins.go @@ -1,8 +1,6 @@ package plugins import ( - "fmt" - "os" "os/exec" "golang.org/x/net/context" @@ -20,47 +18,44 @@ func Init() (*plugin.Client, error) { go get -u google.golang.org/grpc \ go get -u github.com/golang/protobuf/{proto,protoc-gen-go} \ go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway \ - */ /* - Generate - - sudo protoc --go_out=. *.proto protoc --go_out=plugins=grpc:. *.proto */ - // initial goal: pass a string object back and forth over grpc. - // simplify tsdb req/res message/service - - //lets be silly - //plugin path + logger := log.New("grafana.plugins") client := plugin.NewClient(&plugin.ClientConfig{ - HandshakeConfig: shared.Handshake, + HandshakeConfig: plugin.HandshakeConfig{ + ProtocolVersion: 1, + MagicCookieKey: "BASIC_PLUGIN", + MagicCookieValue: "hello", + }, Plugins: shared.PluginMap, - Cmd: exec.Command("sh", "-c", "/home/carl/go/src/github.com/grafana/simple-plugin/simple-plugin"), + Cmd: exec.Command("sh", "-c", "/home/carl/go/src/github.com/grafana/grafana/pkg/tsdb/plugins/mock_tsdb_plugin/simple-plugin"), AllowedProtocols: []plugin.Protocol{plugin.ProtocolGRPC}, + Logger: logWrapper{logger: logger}, }) // Connect via RPC rpcClient, err := client.Client() if err != nil { - fmt.Println("Error:", err.Error()) - os.Exit(1) + return nil, err } // Request the plugin - raw, err := rpcClient.Dispense("kv") + raw, err := rpcClient.Dispense("tsdb_mock") if err != nil { - fmt.Println("Error:", err.Error()) - //os.Exit(1) - //client.Kill() return nil, err } plugin := raw.(shared.TsdbPlugin) response, err := plugin.Get(context.Background(), &proto.TsdbRequest{}) - log.Error2("got response from plugin. ", "response", response) + if err != nil { + logger.Error("Response from plugin. ", "response", response) + } else { + logger.Info("Response from plugin. ", "response", response) + } return client, nil } diff --git a/pkg/tsdb/plugins/shared/interface.go b/pkg/tsdb/plugins/shared/interface.go index 128bf9a38a8..2e5f5260c27 100644 --- a/pkg/tsdb/plugins/shared/interface.go +++ b/pkg/tsdb/plugins/shared/interface.go @@ -12,12 +12,6 @@ var PluginMap = map[string]plugin.Plugin{ "tsdb_mock": &TsdbPluginImpl{}, } -var Handshake = plugin.HandshakeConfig{ - ProtocolVersion: 1, - MagicCookieKey: "BASIC_PLUGIN", - MagicCookieValue: "hello", -} - type TsdbPlugin interface { Get(ctx context.Context, req *proto.TsdbRequest) (*proto.TsdbResponse, error) }