From 88b0244d699ddbd8653e794c2d9b5f8fa385a6d2 Mon Sep 17 00:00:00 2001 From: Carolyn Van Slyck Date: Mon, 27 Feb 2023 10:56:47 -0600 Subject: [PATCH] Trace azure plugin to open telemetry as separate service When we emit traces to open telemetry from the azure plugin, change the service name to "porter.plugins.azure" and under its own root span (for distributed tracing). Right now we see the traces from the plugin, but it's not easy to isolate just stuff from a particular plugin since it's being grouped with the porter service. Signed-off-by: Carolyn Van Slyck --- cmd/azure/main.go | 52 +++++++++++++++++++++++++++++++++------- pkg/azure/helpers.go | 3 ++- pkg/azure/plugin.go | 14 +++++++---- pkg/azure/plugin_test.go | 13 ++++++++++ 4 files changed, 68 insertions(+), 14 deletions(-) create mode 100644 pkg/azure/plugin_test.go diff --git a/cmd/azure/main.go b/cmd/azure/main.go index 18e37af..35b0455 100644 --- a/cmd/azure/main.go +++ b/cmd/azure/main.go @@ -2,28 +2,63 @@ package main import ( "bytes" + "context" + "fmt" "io" "os" + "runtime/debug" "get.porter.sh/plugin/azure/pkg/azure" + "get.porter.sh/porter/pkg/cli" "github.com/spf13/cobra" + "go.opentelemetry.io/otel/attribute" ) func main() { - in := getInput() - cmd := buildRootCommand(in) - if err := cmd.Execute(); err != nil { - os.Exit(1) + run := func() int { + ctx := context.Background() + m := azure.New() + ctx, err := m.ConfigureLogging(ctx) + if err != nil { + fmt.Println(err) + os.Exit(cli.ExitCodeErr) + } + cmd := buildRootCommand(m, getInput()) + + ctx, log := m.StartRootSpan(ctx, "azure") + defer func() { + // Capture panics and trace them + if panicErr := recover(); panicErr != nil { + log.Error(fmt.Errorf("%s", panicErr), + attribute.Bool("panic", true), + attribute.String("stackTrace", string(debug.Stack()))) + log.EndSpan() + m.Close() + os.Exit(cli.ExitCodeErr) + } else { + log.Close() + m.Close() + } + }() + + if err := cmd.ExecuteContext(ctx); err != nil { + return cli.ExitCodeErr + } + return cli.ExitCodeSuccess } + os.Exit(run()) } -func buildRootCommand(in io.Reader) *cobra.Command { - m := azure.New() - m.In = in - +func buildRootCommand(m *azure.Plugin, in io.Reader) *cobra.Command { cmd := &cobra.Command{ Use: "azure", Short: "Azure plugin for Porter", + PersistentPreRun: func(cmd *cobra.Command, args []string) { + // Enable swapping out stdout/stderr for testing + m.In = in + m.Out = cmd.OutOrStdout() + m.Err = cmd.OutOrStderr() + }, } cmd.AddCommand(buildVersionCommand(m)) @@ -31,7 +66,6 @@ func buildRootCommand(in io.Reader) *cobra.Command { return cmd } - func getInput() io.Reader { s, _ := os.Stdin.Stat() if (s.Mode() & os.ModeCharDevice) == 0 { diff --git a/pkg/azure/helpers.go b/pkg/azure/helpers.go index 7ae39a1..4cb1065 100644 --- a/pkg/azure/helpers.go +++ b/pkg/azure/helpers.go @@ -4,6 +4,7 @@ import ( "testing" "get.porter.sh/porter/pkg/portercontext" + "get.porter.sh/porter/pkg/runtime" ) type TestPlugin struct { @@ -16,7 +17,7 @@ func NewTestPlugin(t *testing.T) *TestPlugin { c := portercontext.NewTestContext(t) m := &TestPlugin{ Plugin: &Plugin{ - Context: c.Context, + RuntimeConfig: runtime.NewConfigFor(c.Context), }, TestContext: c, } diff --git a/pkg/azure/plugin.go b/pkg/azure/plugin.go index ce9ea9d..0a2ecef 100644 --- a/pkg/azure/plugin.go +++ b/pkg/azure/plugin.go @@ -6,20 +6,26 @@ import ( "io/ioutil" "get.porter.sh/plugin/azure/pkg/azure/azureconfig" - "get.porter.sh/porter/pkg/portercontext" + "get.porter.sh/porter/pkg/runtime" "github.com/pkg/errors" ) type Plugin struct { - *portercontext.Context + runtime.RuntimeConfig azureconfig.Config } // New azure plugin client, initialized with useful defaults. func New() *Plugin { - return &Plugin{ - Context: portercontext.New(), + p := &Plugin{ + RuntimeConfig: runtime.NewConfig(), } + + // Tell porter that we are running inside a plugin + p.IsInternalPlugin = true + p.InternalPluginKey = "porter.plugins.azure" + + return p } func (p *Plugin) LoadConfig() error { diff --git a/pkg/azure/plugin_test.go b/pkg/azure/plugin_test.go new file mode 100644 index 0000000..cede6c8 --- /dev/null +++ b/pkg/azure/plugin_test.go @@ -0,0 +1,13 @@ +package azure + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNew(t *testing.T) { + p := New() + assert.True(t, p.IsInternalPlugin, "expected tracing to be configured as a plugin") + assert.Equal(t, "porter.plugins.azure", p.InternalPluginKey, "expected the plugin to have its on tracing service name") +}