Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: language plugin logs have named scope and are parsed as json #3229

Merged
merged 2 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frontend/cli/cmd_new.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func prepareNewCmd(ctx context.Context, k *kong.Kong, args []string) (optionalPl
return optionalPlugin, fmt.Errorf("could not create bind allocator: %w", err)
}

plugin, err := languageplugin.New(ctx, bindAllocator, language)
plugin, err := languageplugin.New(ctx, bindAllocator, language, "new")
if err != nil {
return optionalPlugin, fmt.Errorf("could not create plugin for %v: %w", language, err)
}
Expand Down
2 changes: 1 addition & 1 deletion internal/buildengine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -1028,7 +1028,7 @@ func (e *Engine) gatherSchemas(
}

func (e *Engine) newModuleMeta(ctx context.Context, config moduleconfig.UnvalidatedModuleConfig) (moduleMeta, error) {
plugin, err := languageplugin.New(ctx, e.bindAllocator, config.Language)
plugin, err := languageplugin.New(ctx, e.bindAllocator, config.Language, config.Module)
if err != nil {
return moduleMeta{}, fmt.Errorf("could not create plugin for %s: %w", config.Module, err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ func startPlugin() in.Action {

bindURL, err = bindAllocator.Next()
assert.NoError(t, err)
client, err = newExternalPluginImpl(ic.Context, bindURL, ic.Language)
client, err = newExternalPluginImpl(ic.Context, bindURL, ic.Language, "test")
assert.NoError(t, err)
}
}
Expand Down
4 changes: 2 additions & 2 deletions internal/buildengine/languageplugin/external_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ type externalPlugin struct {

var _ LanguagePlugin = &externalPlugin{}

func newExternalPlugin(ctx context.Context, bind *url.URL, language string) (*externalPlugin, error) {
impl, err := newExternalPluginImpl(ctx, bind, language)
func newExternalPlugin(ctx context.Context, bind *url.URL, language, name string) (*externalPlugin, error) {
impl, err := newExternalPluginImpl(ctx, bind, language, name)
if err != nil {
return nil, err
}
Expand Down
25 changes: 20 additions & 5 deletions internal/buildengine/languageplugin/external_plugin_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,35 +45,50 @@ type externalPluginImpl struct {
cmdError chan error
}

func newExternalPluginImpl(ctx context.Context, bind *url.URL, language string) (*externalPluginImpl, error) {
func newExternalPluginImpl(ctx context.Context, bind *url.URL, language, name string) (*externalPluginImpl, error) {
impl := &externalPluginImpl{
client: rpc.Dial(langconnect.NewLanguageServiceClient, bind.String(), log.Error),
}
err := impl.start(ctx, bind, language)
err := impl.start(ctx, bind, language, name)
if err != nil {
return nil, err
}
return impl, nil
}

// Start launches the plugin and blocks until the plugin is ready.
func (p *externalPluginImpl) start(ctx context.Context, bind *url.URL, language string) error {
func (p *externalPluginImpl) start(ctx context.Context, bind *url.URL, language, name string) error {
logger := log.FromContext(ctx).Scope(name)

cmdName := "ftl-language-" + language
p.cmd = exec.Command(ctx, log.Debug, ".", cmdName, "--bind", bind.String())
p.cmd.Env = append(p.cmd.Env, "FTL_NAME="+name)
_, err := exec.LookPath(cmdName)
if err != nil {
return fmt.Errorf("failed to find plugin for %s: %w", language, err)
}

// Send the plugin's stderr to the logger.
p.cmd.Stderr = nil
pipe, err := p.cmd.StderrPipe()
if err != nil {
return fmt.Errorf("could not create stderr pipe for %s: %w", name, err)
}
go func() {
err := log.JSONStreamer(pipe, logger, log.Error)
if err != nil {
logger.Errorf(err, "Error streaming plugin logs.")
}
}()

runCtx, cancel := context.WithCancel(ctx)

p.cmdError = make(chan error)
pingErr := make(chan error)

// run the plugin and wait for it to finish executing
go func() {
err := p.cmd.RunBuffered(runCtx)
fmt.Printf("ended!")
err := p.cmd.Run()
if err != nil {
p.cmdError <- fmt.Errorf("language plugin failed: %w", err)
} else {
Expand Down
4 changes: 2 additions & 2 deletions internal/buildengine/languageplugin/go_plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestExtractModuleDepsGo(t *testing.T) {
uncheckedConfig, err := moduleconfig.LoadConfig(dir)
assert.NoError(t, err)

plugin, err := New(ctx, nil, uncheckedConfig.Language)
plugin, err := New(ctx, nil, uncheckedConfig.Language, "test")
assert.NoError(t, err)

customDefaults, err := plugin.ModuleConfigDefaults(ctx, uncheckedConfig.Dir)
Expand Down Expand Up @@ -85,7 +85,7 @@ func TestGoConfigDefaults(t *testing.T) {
dir, err := filepath.Abs(tt.dir)
assert.NoError(t, err)

plugin, err := New(ctx, nil, "go")
plugin, err := New(ctx, nil, "go", "test")
assert.NoError(t, err)

defaults, err := plugin.ModuleConfigDefaults(ctx, dir)
Expand Down
2 changes: 1 addition & 1 deletion internal/buildengine/languageplugin/java_plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func TestJavaConfigDefaults(t *testing.T) {
dir, err := filepath.Abs(tt.dir)
assert.NoError(t, err)

plugin, err := New(ctx, nil, "java")
plugin, err := New(ctx, nil, "java", "test")
assert.NoError(t, err)

defaults, err := plugin.ModuleConfigDefaults(ctx, dir)
Expand Down
4 changes: 2 additions & 2 deletions internal/buildengine/languageplugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ type LanguagePlugin interface {
}

// PluginFromConfig creates a new language plugin from the given config.
func New(ctx context.Context, bindAllocator *bind.BindAllocator, language string) (p LanguagePlugin, err error) {
func New(ctx context.Context, bindAllocator *bind.BindAllocator, language, name string) (p LanguagePlugin, err error) {
switch language {
case "go":
return newGoPlugin(ctx), nil
Expand All @@ -145,7 +145,7 @@ func New(ctx context.Context, bindAllocator *bind.BindAllocator, language string
if err != nil {
return nil, fmt.Errorf("failed to allocate port for external plugin: %w", err)
}
return newExternalPlugin(ctx, port, language)
return newExternalPlugin(ctx, port, language, name)
}
}

Expand Down
3 changes: 2 additions & 1 deletion python-runtime/cmd/ftl-language-python/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"context"
"os"

"github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1/language/languagepbconnect"
"github.com/TBD54566975/ftl/common/plugin"
Expand All @@ -11,7 +12,7 @@ import (
func main() {
plugin.Start(
context.Background(),
"ftl-language-python",
os.Getenv("FTL_NAME"),
createService,
languagepbconnect.LanguageServiceName,
languagepbconnect.NewLanguageServiceHandler,
Expand Down