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

Consider Helper() Function to Fix Log Entry @caller Information #29

Closed
bflad opened this issue Feb 4, 2022 · 4 comments · Fixed by #36
Closed

Consider Helper() Function to Fix Log Entry @caller Information #29

bflad opened this issue Feb 4, 2022 · 4 comments · Fixed by #36
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@bflad
Copy link
Contributor

bflad commented Feb 4, 2022

terraform-plugin-log version

v0.2.1

Use cases

When implementing subsystem loggers, it can be helpful to create a package and wrapper functions for the tflog.SubsystemX() (or for the SDKs, tfsdklog.SubsystemX()) calls to simplify and potentially clarify the code, e.g.

//
// NOTE: This is a SDK-specific example. Providers should always use the tflog package.
//
package logging

import (
	"context"

	"github.com/hashicorp/terraform-plugin-log/tfsdklog"
)

const (
	// SubsystemProto is the tfsdklog subsystem name for protocol logging.
	SubsystemProto = "proto"
)

// ProtocolError emits a protocol subsystem log at ERROR level.
func ProtocolError(ctx context.Context, msg string, args ...interface{}) {
	tfsdklog.SubsystemError(ctx, SubsystemProto, msg, args)
}

// ProtocolTrace emits a protocol subsystem log at TRACE level.
func ProtocolTrace(ctx context.Context, msg string, args ...interface{}) {
	tfsdklog.SubsystemTrace(ctx, SubsystemProto, msg, args)
}

Which makes calling code fairly concise:

logging.ProtocolTrace(ctx, "Received request")

When doing this, the log entries are then off by one frame in the @caller (pretty printed for clarity):

{
    "@caller": "/Users/bflad/go/pkg/mod/github.com/hashicorp/terraform-plugin-go@v0.7.0/internal/logging/protocol.go:21",
    "@level": "trace",
    "@message": "Received request",
    "@module": "sdk.proto",
    "@timestamp": "2022-02-04T16:28:52.602080-05:00",
    "EXTRA_VALUE_AT_END": null,
    "tf_proto_version": "5.2",
    "tf_provider_addr": "",
    "tf_req_id": "a24b8a29-628a-01c2-0516-08b260627109",
    "tf_rpc": "GetProviderSchema"
}

Which makes troubleshooting slightly harder.

Proposal

Similar to how the Go standard library testing package implements T.Helper(), which is defined as:

Helper marks the calling function as a test helper function. When printing file and line information, that function will be skipped. Helper may be called simultaneously from multiple goroutines.

It might be possible to do something similar with these packages so callers can signify that the final frame in the stack should be ignored for file and line information.

@bflad bflad added the enhancement New feature or request label Feb 4, 2022
@bflad
Copy link
Contributor Author

bflad commented Feb 5, 2022

This is more complex as hc-log supports LoggerOptions.AdditionalLocationOffset, but LoggerOptions are used when creating a Logger and there is no ability to update it later at the moment. As a workaround, we may be able to also save our logger options separately in the context so we can recreate the logger with the additional value, but ideally upstream would support the ability to update the location offset, similar to updating the log level.

@bflad
Copy link
Contributor Author

bflad commented Feb 7, 2022

A more trivial, but less flexible approach would be allowing callers to set the additional offset on subsystem creation via a new logger.Option. This is probably good enough for now.

@bflad bflad added this to the v0.3.0 milestone Feb 14, 2022
@bflad bflad self-assigned this Mar 4, 2022
bflad added a commit that referenced this issue Mar 8, 2022
Reference: #29

Allows implementations to fix the location offset of caller information when using helper functions. While typically expected for subsystem loggers, SDKs could also offer the configuration of the root provider logger as well.

Since each `hclog.Logger` is mainly immutable once its created (except for level and creating named sub-loggers), the `hclog.LoggerOptions` are saved to the context as well, allowing `NewSubsystem` to appropriately have all the root logger options available to create new sub-loggers. Maybe this can be changed upstream in the future, although that would technically be a breaking change since the interface would need to be modified.

This changeset also includes setting the name of the test root SDK/provider loggers, so that subsystem naming (and therefore the unit testing) matches real world usage.
bflad added a commit that referenced this issue Mar 8, 2022
Reference: #29

Allows implementations to fix the location offset of caller information when using helper functions. While typically expected for subsystem loggers, SDKs could also offer the configuration of the root provider logger as well.

Since each `hclog.Logger` is mainly immutable once its created (except for level and creating named sub-loggers), the `hclog.LoggerOptions` are saved to the context as well, allowing `NewSubsystem` to appropriately have all the root logger options available to create new sub-loggers. Maybe this can be changed upstream in the future, although that would technically be a breaking change since the interface would need to be modified.

This changeset also includes setting the name of the test root SDK/provider loggers, so that subsystem naming (and therefore the unit testing) matches real world usage.
@bflad bflad closed this as completed in #36 Mar 10, 2022
bflad added a commit that referenced this issue Mar 10, 2022
Reference: #29

Allows implementations to fix the location offset of caller information when using helper functions. While typically expected for subsystem loggers, SDKs could also offer the configuration of the root provider logger as well.

Since each `hclog.Logger` is mainly immutable once its created (except for level and creating named sub-loggers), the `hclog.LoggerOptions` are saved to the context as well, allowing `NewSubsystem` to appropriately have all the root logger options available to create new sub-loggers. Maybe this can be changed upstream in the future, although that would technically be a breaking change since the interface would need to be modified.

This changeset also includes setting the name of the test root SDK/provider loggers, so that subsystem naming (and therefore the unit testing) matches real world usage.
@bflad
Copy link
Contributor Author

bflad commented Mar 10, 2022

Went with a new WithAdditionalLocationOffset() function to be used with NewSubsystem() for now, which can be used to remove additional calls from the caller stack when using helpers. If desirable, the SDKs can also surface this functionality for the root provider logger.

@github-actions
Copy link

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 10, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant