Skip to content

Commit

Permalink
Call NewTerraformLogRedirector for PF (#2686)
Browse files Browse the repository at this point in the history
Will fix (probably) pulumi/pulumi-ise#9

Related to #2489

---

By not calling the redirect, all logs were shown directly to the user
(as INFO logs). This gets PF to respect TF_LOG, similar to /pkg.
  • Loading branch information
iwahbe authored Dec 5, 2024
1 parent 1c9c3e0 commit 8696ada
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 7 deletions.
63 changes: 63 additions & 0 deletions pkg/pf/tests/logging_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package tfbridgetests

import (
"context"
"log"
"testing"

"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tests/internal/providerbuilder"
"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tests/pulcheck"
"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/pf/tfbridge"
"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfbridge/info"
"github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfbridge/tokens"
)

func TestLogCaputure(t *testing.T) {
t.Setenv("TF_LOG", "WARN")

provider := info.Provider{
Name: "test",
Version: "0.0.1",
P: tfbridge.ShimProvider(providerbuilder.NewProvider(providerbuilder.NewProviderArgs{
TypeName: "test",
AllResources: []providerbuilder.Resource{{
Name: "res",
ResourceSchema: schema.Schema{
Attributes: map[string]schema.Attribute{
"id": schema.StringAttribute{
Computed: true,
},
},
},
CreateFunc: func(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
require.Empty(t, resp.State.SetAttribute(ctx, path.Root("id"), "1234"))
log.Println("[INFO] This is info")
log.Println("[WARN] You have been warned")
},
}},
})),
MetadataInfo: info.NewProviderMetadata(nil),
}

provider.MustComputeTokens(tokens.SingleModule("test", "index", tokens.MakeStandard("test")))

pt, err := pulcheck.PulCheck(t, provider, `
name: test
runtime: yaml
resources:
mainRes:
type: test:Res
`)

require.NoError(t, err)
result := pt.Up(t)

assert.NotContains(t, result.StdOut, "This is info")
assert.Contains(t, result.StdOut, "You have been warned")
}
20 changes: 20 additions & 0 deletions pkg/pf/tfbridge/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package tfbridge

import (
"context"
"log"

"github.com/pulumi/pulumi/sdk/v3/go/common/resource"

Expand All @@ -29,6 +30,25 @@ import (
func (p *provider) initLogging(ctx context.Context, sink logging.Sink, urn resource.URN) context.Context {
// add the resource URN to the context
ctx = tfbridge.XWithUrn(ctx, urn)

// There is no host in a testing context.
if sink == nil {
// For tests that did not call InitLogging yet, we should call it here so that
// GetLogger does not panic.
if ctx.Value(logging.CtxKey) == nil {
return logging.InitLogging(ctx, logging.LogOptions{
URN: urn,
ProviderName: p.info.Name,
ProviderVersion: p.info.Version,
})
}

// Otherwise keep the context as-is.
return ctx
}

log.SetOutput(tfbridge.NewTerraformLogRedirector(ctx, sink))

return logging.InitLogging(ctx, logging.LogOptions{
LogSink: sink,
URN: urn,
Expand Down
23 changes: 16 additions & 7 deletions pkg/tfbridge/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,23 @@ import (
"os"
"strings"

"github.com/pulumi/pulumi/pkg/v3/resource/provider"
"github.com/pulumi/pulumi/sdk/v3/go/common/diag"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"

"github.com/pulumi/pulumi-terraform-bridge/v3/internal/logging"
)

// LogRedirector creates a new redirection writer that takes as input plugin stderr output, and routes it to the
// correct Pulumi stream based on the standard Terraform logging output prefixes.
// LogRedirector creates a new redirection writer that takes [log] messages as input, and
// routes it to the Pulumi correct structured logging.
//
// It looks for lines that contain log level information and routes them to their Pulumi
// equivalent. A line is considered to have log level information when it contains one of:
//
// - "[TRACE]"
// - "[DEBUG]"
// - "[INFO]"
// - "[WARN]"
// - "[ERROR]"
type LogRedirector struct {
ctx context.Context
level level // log level requested by TF_LOG
Expand Down Expand Up @@ -74,11 +82,12 @@ const (
tfErrorPrefix = "[ERROR]"
)

func NewTerraformLogRedirector(ctx context.Context, hostClient *provider.HostClient) *LogRedirector {
lr := &LogRedirector{ctx: ctx, sink: hostClient}
// NewTerraformLogRedirector creates a [LogRedirector] that responds to the TF_LOG
// environmental variable.
func NewTerraformLogRedirector(ctx context.Context, sink logging.Sink) *LogRedirector {
lr := &LogRedirector{ctx: ctx, sink: sink}

tfLog, ok := os.LookupEnv("TF_LOG")
if ok {
if tfLog, ok := os.LookupEnv("TF_LOG"); ok {
switch strings.ToLower(tfLog) {
case "trace":
lr.level = traceLevel
Expand Down

0 comments on commit 8696ada

Please sign in to comment.