Skip to content

Alternative implementation of Stringer interface #3106

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

gnwgnw
Copy link

@gnwgnw gnwgnw commented Feb 20, 2025

JSON marshaling allows to log a value of optional fields instead of addresses.

  • Did you create an Apache Jira ticket? (Request account here, not required for trivial changes)
  • If a ticket exists: Does your pull request title follow the pattern "THRIFT-NNNN: describe my issue"?
  • Did you squash your changes to a single commit? (not required, but preferred)
  • Did you do your best to avoid breaking changes? If one was needed, did you label the Jira ticket with "Breaking-Change"?
  • If your change does not involve any code, include [skip ci] anywhere in the commit message to free up build resources.

JSON marshaling allows to log a value of optional fileds
instead of addresses.
@Jens-G Jens-G added the golang patches related to go language label Feb 20, 2025
@Jens-G Jens-G requested a review from fishy March 2, 2025 09:47
Copy link
Member

@fishy fishy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please also add some test for the generated code, and/or paste generated go code here?

out << indent() << "return fmt.Sprintf(\"" << escape_string(tstruct_name) << "(%+v)\", *p)"
<< '\n';
} else if (stringer_mode_ == STRINGER_MODE_JSON) {
out << indent() << "v, _ := json.Marshal(p)" << '\n';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in general, we don't want to drop error returns from generated go code. I would prefer to fallback to the old behavior if we hit an error when doing json marshaling here.

additionally, this is not the most efficient way to do json marshaling, especially when the struct is large, as it requires first grow the []byte used in json.Marshal until it can fit the whole string, then it need to be allocated again when you convert that to string. A more efficient way to do it would be using json.NewEncoder with strings.Builder, which will avoid the second allocation, but you need to strip the final \n it generates.

we actually already implemented it in SlogTStructWrapper, you can check https://github.com/apache/thrift/blob/v0.21.0/lib/go/thrift/slog.go#L46 for the implementation. that implementation will only do the json encoding when the struct is logged via slog. the consideration is that json encoding is much more heavier than just fmt.Sprintf, so we only do that when needed (e.g. when you need to log it), instead of everywhere the stringer implementation is used (an example is that for compiler generated code for an exception, its Error implementation also uses stringer implementation under the hood). we definitely do not want to change default stringer implementation to json as that would have large performance implications. your approach of adding a compiler arg is most likely a good compromise, but please take a look at SlogTStructWrapper, and maybe that's already enough for your use-case :)

@fishy
Copy link
Member

fishy commented Mar 3, 2025

also cc @dcelasun

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
golang patches related to go language
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants