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

logtestutils: generalize structured logging spy #124301

Merged
merged 1 commit into from
May 21, 2024

Conversation

xinhaoz
Copy link
Member

@xinhaoz xinhaoz commented May 16, 2024

This commit generalizes the structured logging spy previously being used for datadriven telemetry tests so that it can repurposed for other structured logging channels.

Epic: none

Release note: None

@xinhaoz xinhaoz requested a review from a team as a code owner May 16, 2024 20:35
@xinhaoz xinhaoz requested review from nkodali and removed request for a team May 16, 2024 20:35
@cockroach-teamcity
Copy link
Member

This change is Reviewable

@xinhaoz xinhaoz force-pushed the generalize-log-spy branch 6 times, most recently from 22fd881 to 26ca692 Compare May 20, 2024 14:45
Copy link
Member

@abarganier abarganier left a comment

Choose a reason for hiding this comment

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

Nice job identifying a need here. I ended up needing something similar the other day in a PR, so I'm sure others will benefit from this work.

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @kyle-a-wong, @nkodali, and @xinhaoz)


pkg/util/log/logtestutils/structured_log_spy.go line 106 at r1 (raw file):

}

type StructuredLogSpy[T any] struct {

nit: docstring for the exported type explaining it's use/function.

Code quote:

type StructuredLogSpy[T any] struct {

pkg/util/log/logtestutils/structured_log_spy.go line 110 at r1 (raw file):

	// map of channels to pointer
	channels map[logpb.Channel]interface{}

nit: can this just be map[logpb.Channel]struct{}{}?

Code quote:

map[logpb.Channel]interface{}

pkg/util/log/logtestutils/structured_log_spy.go line 133 at r1 (raw file):

	format func(entry logpb.Entry) (T, error),
	filters ...func(entry logpb.Entry, formattedEntry T) bool,
) *StructuredLogSpy[T] {

nit: comments/docs explaining how things like format, filters, etc. work

Code quote:

func NewStructuredLogSpy[T any](
	testState *testing.T,
	channels []logpb.Channel,
	eventTypes []string,
	format func(entry logpb.Entry) (T, error),
	filters ...func(entry logpb.Entry, formattedEntry T) bool,
) *StructuredLogSpy[T] {

pkg/util/log/logtestutils/structured_log_spy.go line 164 at r1 (raw file):

	defer s.mu.Unlock()
	s.mu.filters = nil
}

Do we have examples of tests needing to modify filters post-construction? If a test needs different filters, should we just create a new StructuredLogSpy?

Code quote:

func (s *StructuredLogSpy[T]) AddFilters(f ...func(entry logpb.Entry, formattedEntry T) bool) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.mu.filters = append(s.mu.filters, f...)
}

func (s *StructuredLogSpy[T]) ClearFilters() {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.mu.filters = nil
}

pkg/util/log/logtestutils/structured_log_spy.go line 193 at r1 (raw file):

	if n > len(s.mu.logs[ch]) {
		n = len(s.mu.logs[ch])
	}

Here and in other functions, should we add some existence checks for the various s.mu.logs[ch] map accesses?

Code quote:

	if n > len(s.mu.logs[ch]) {
		n = len(s.mu.logs[ch])
	}

Copy link
Collaborator

@dhartunian dhartunian left a comment

Choose a reason for hiding this comment

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

Reviewed 3 of 5 files at r1, all commit messages.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @abarganier, @kyle-a-wong, @nkodali, and @xinhaoz)


pkg/util/log/logtestutils/structured_log_spy.go line 130 at r1 (raw file):

	testState *testing.T,
	channels []logpb.Channel,
	eventTypes []string,

I don't see usage with multiple channels/events. Is it necessary to support? Same with format + filters, can we get away with a single filter function that combines formatting? Not sure the interface really needs both since in the simplest case someone might just want to manipulate the entry directly.


pkg/util/log/logtestutils/structured_log_spy.go line 133 at r1 (raw file):

Previously, abarganier (Alex Barganier) wrote…

nit: comments/docs explaining how things like format, filters, etc. work

+1


pkg/util/log/logtestutils/structured_log_spy.go line 164 at r1 (raw file):

Previously, abarganier (Alex Barganier) wrote…

Do we have examples of tests needing to modify filters post-construction? If a test needs different filters, should we just create a new StructuredLogSpy?

298f0dd#diff-2b876a20003068a4ddca879d6c283764b01434281d2015c00037d5e084012436R117-R119

Copy link
Contributor

@kyle-a-wong kyle-a-wong left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @abarganier, @nkodali, and @xinhaoz)


pkg/util/log/logtestutils/structured_log_spy.go line 208 at r1 (raw file):

}

func (s *StructuredLogSpy[T]) Intercept(entry []byte) {

Is there a reason why the funcs above have doc strings but this one and the ones below don't?


pkg/util/log/logtestutils/structured_log_spy.go line 227 at r1 (raw file):

			}
			return false
		}()

What is the purpose of this being an IFFE?

Code quote:

		found := func() bool {
			for _, re := range s.eventTypeRe {
				if re.MatchString(logEntry.Message) {
					return true
				}
			}
			return false
		}()

This commit generalizes the structured logging spy previously
being used for datadriven telemetry tests so that it can be
repurposed for other structured logging channels.

The log spy used `sql_exec_log_test` is converted to use the
StructuredLogSpy as an example.

Epic: none

Release note: None
Copy link
Member Author

@xinhaoz xinhaoz left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @abarganier, @dhartunian, @kyle-a-wong, @nkodali, and @xinhaoz)


pkg/util/log/logtestutils/structured_log_spy.go line 106 at r1 (raw file):

Previously, abarganier (Alex Barganier) wrote…

nit: docstring for the exported type explaining it's use/function.

Done.


pkg/util/log/logtestutils/structured_log_spy.go line 110 at r1 (raw file):

Previously, abarganier (Alex Barganier) wrote…

nit: can this just be map[logpb.Channel]struct{}{}?

Done.


pkg/util/log/logtestutils/structured_log_spy.go line 130 at r1 (raw file):

Previously, dhartunian (David Hartunian) wrote…

I don't see usage with multiple channels/events. Is it necessary to support? Same with format + filters, can we get away with a single filter function that combines formatting? Not sure the interface really needs both since in the simplest case someone might just want to manipulate the entry directly.

I don't see any harm with extending it to multiple channels. One motivation for this many-to-one case: I was hoping to use this for some datadriven testing for sql exec / perf channels similar to what we have for telemetry and it would be nice to have one log spy for all of them, since they'd all use the same string format function. Appending a channel name to the log spy in that case will save us from having to create and manage separate log spies for all of them.

Similarly for the format / filter functions, I've found some utility in separating those two ops for reuse. Esp if we might have different tests being setup with their own log spies for the same events, it's nice not having to write the same format function multiple times, but allow those spies to have different filtering behaviours. LMK though and I can convert it to a single channel / function if desired.


pkg/util/log/logtestutils/structured_log_spy.go line 133 at r1 (raw file):

Previously, dhartunian (David Hartunian) wrote…

+1

Done.


pkg/util/log/logtestutils/structured_log_spy.go line 164 at r1 (raw file):

Previously, dhartunian (David Hartunian) wrote…

298f0dd#diff-2b876a20003068a4ddca879d6c283764b01434281d2015c00037d5e084012436R117-R119

Yes, we do always have the option of creating a separate log spy. I find these functions just add some shortcuts so that we don't always need to.


pkg/util/log/logtestutils/structured_log_spy.go line 193 at r1 (raw file):

Previously, abarganier (Alex Barganier) wrote…

Here and in other functions, should we add some existence checks for the various s.mu.logs[ch] map accesses?

Working with a nil slice is actually pretty ergonomic in golang. The bottom will just append no entries if we get a nil entry.


pkg/util/log/logtestutils/structured_log_spy.go line 208 at r1 (raw file):

Previously, kyle-a-wong (Kyle Wong) wrote…

Is there a reason why the funcs above have doc strings but this one and the ones below don't?

Added!


pkg/util/log/logtestutils/structured_log_spy.go line 227 at r1 (raw file):

Previously, kyle-a-wong (Kyle Wong) wrote…

What is the purpose of this being an IFFE?

Was just trying to avoid having to do a loop with a break to accomplish array.some. Can convert it to that or something else if you have suggestions to make it more readable.

Copy link
Contributor

@kyle-a-wong kyle-a-wong left a comment

Choose a reason for hiding this comment

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

Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @abarganier, @dhartunian, @nkodali, and @xinhaoz)


pkg/util/log/logtestutils/structured_log_spy.go line 208 at r1 (raw file):

Previously, xinhaoz (Xin Hao Zhang) wrote…

Added!

lgtm


pkg/util/log/logtestutils/structured_log_spy.go line 227 at r1 (raw file):

Previously, xinhaoz (Xin Hao Zhang) wrote…

Was just trying to avoid having to do a loop with a break to accomplish array.some. Can convert it to that or something else if you have suggestions to make it more readable.

Ahhh, thanks for the info. I don't have a particular opinion or suggestion about what is most readable. I was mostly just wondering if this was an idiosyncrasy of golang or just an implementation decision.

Copy link
Member

@abarganier abarganier left a comment

Choose a reason for hiding this comment

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

:lgtm:

Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @dhartunian, @nkodali, and @xinhaoz)


pkg/util/log/logtestutils/structured_log_spy.go line 164 at r1 (raw file):

Previously, xinhaoz (Xin Hao Zhang) wrote…

Yes, we do always have the option of creating a separate log spy. I find these functions just add some shortcuts so that we don't always need to.

Ack, thanks for the example usage.

Copy link
Collaborator

@dhartunian dhartunian left a comment

Choose a reason for hiding this comment

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

:lgtm:

Reviewable status: :shipit: complete! 2 of 0 LGTMs obtained (waiting on @nkodali and @xinhaoz)


pkg/util/log/logtestutils/structured_log_spy.go line 130 at r1 (raw file):

Previously, xinhaoz (Xin Hao Zhang) wrote…

I don't see any harm with extending it to multiple channels. One motivation for this many-to-one case: I was hoping to use this for some datadriven testing for sql exec / perf channels similar to what we have for telemetry and it would be nice to have one log spy for all of them, since they'd all use the same string format function. Appending a channel name to the log spy in that case will save us from having to create and manage separate log spies for all of them.

Similarly for the format / filter functions, I've found some utility in separating those two ops for reuse. Esp if we might have different tests being setup with their own log spies for the same events, it's nice not having to write the same format function multiple times, but allow those spies to have different filtering behaviours. LMK though and I can convert it to a single channel / function if desired.

👍 thanks for the note

@xinhaoz xinhaoz added backport-24.1.x Flags PRs that need to be backported to 24.1. backport-23.2.x Flags PRs that need to be backported to 23.2. labels May 21, 2024
@xinhaoz
Copy link
Member Author

xinhaoz commented May 21, 2024

TFTR!
bors r+

craig bot pushed a commit that referenced this pull request May 21, 2024
123120: ui: Highlight unavailable ranges in red on the summary bar with nonzero r=abarganier a=theloneexplorerquest

Modify the summary bar to change the color of unavailable ranges. When the unavailable range is greater than zero, it will be displayed in red; if it is zero, it will be green.

Fix: #122014

Release note (ui): Changed the color of unavailable ranges on the summary bar to red when nonzero; ranges are green when zero.

124301: logtestutils: generalize structured logging spy r=xinhaoz a=xinhaoz

This commit generalizes the structured logging spy previously being used for datadriven telemetry tests so that it can repurposed for other structured logging channels.

Epic: none

Release note: None

124403: roachtest: use first transient error when checking for flakes r=srosenberg a=renatolabs

Previously, roachtest would only look at the outermost error in a chain that matched a `TransientError` (or `ErrorWithOwnership`) when checking for flakes. However, that is in most cases *not* what we want: if a transient error wraps another transient error, the actual reason for the failure is the original (wrapped) error.

Informs: #123887

Release note: None

124425: pkg/server/structlogging: support hot ranges stats with diagnostic reporting disabled r=kyle-a-wong a=kyle-a-wong

Previously, enable hot ranges stats also required the enabling of diagnostic reporting. Hot ranges stats doesn't need to be dependent on diagnostic reporting and someone might want to enable hot ranges stats without enabling diagnostic reporting.

Now, server.telemetry.hot_ranges_stats.enabled can be set to true while without setting diagnostics.reporting.enabled

Epic: none
Fixes: #122977
Part of: https://cockroachlabs.atlassian.net/browse/CRDB-38152

Release note: None

124459: builtins: fix st_geojson when max_decimal_digits is specified r=yuzefovich a=yuzefovich

This commit fixes a regression in `st_geojson` builtin when `max_decimal_digits` argument is specified which was introduced in 6009141 (during 24.1 cycle). In particular, this overload specifies the precision (rather than using the default number of digits), and that commit made it so that we ignore the precision argument. This is now fixed.

Fixes: #124368.

Release note (bug fix): CockroachDB previously would ignore `max_decimal_digits` argument of `st_geojson` builtin function and would use the default instead. The bug is only present in 24.1.0 releases.

124491: raft: remove RawNode.TickQuiesced r=pav-kv a=nvanbenschoten

This commit removes the `(*RawNode).TickQuiesced` method. The method was deprecated back in etcd-io/raft#62 and has not been in use since 2018.

Epic: None
Release note: None

Co-authored-by: theloneexplorerquest <theloneexplorerquest@gmail.com>
Co-authored-by: Xin Hao Zhang <xzhang@cockroachlabs.com>
Co-authored-by: Renato Costa <renato@cockroachlabs.com>
Co-authored-by: Kyle Wong <kyle.wong@cockroachlabs.com>
Co-authored-by: Yahor Yuzefovich <yahor@cockroachlabs.com>
Co-authored-by: Nathan VanBenschoten <nvanbenschoten@gmail.com>
@craig
Copy link
Contributor

craig bot commented May 21, 2024

Build failed (retrying...):

@craig craig bot merged commit 3685bb0 into cockroachdb:master May 21, 2024
21 of 22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport-23.2.x Flags PRs that need to be backported to 23.2. backport-24.1.x Flags PRs that need to be backported to 24.1.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants