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

Add a ZapMapLogger for logging without duplicate entries #94

Merged
merged 32 commits into from
Jul 9, 2020

Conversation

smoorpal
Copy link
Contributor

@smoorpal smoorpal commented Jun 25, 2020

Before this PR

The default ZapLogger was capable of printing duplicate fields which would break certain json decoders downstream.

After this PR

==COMMIT_MSG==
wlog-zap and wlog-zerolog updated to prevent printing duplicate Params.
==COMMIT_MSG==

Possible downsides?

The expense of storing in a map may result in slightly difference performance since allocation is not as straight forward.


This change is Reviewable

@changelog-app
Copy link

changelog-app bot commented Jun 25, 2020

Generate changelog in changelog/@unreleased

Type

  • Feature
  • Improvement
  • Fix
  • Break
  • Deprecation
  • Manual task
  • Migration

Description

ZapMapLogger added as a demonstration of a logger which will store Params in a map in order to avoid storing the same Param twice.

Check the box to generate changelog(s)

  • Generate changelog entry

@nmiyake
Copy link
Contributor

nmiyake commented Jun 25, 2020

The PR states that this provider is added as a demonstration. Can you expand a bit on the goal of getting this merged? If this is for doing some experimentation/benchmarking, then would prefer for that to be done on a fork if possible. If this is going to be merged, then would like to understand how it's being thought of as a first-class implementation (and to get context on why this is being implemented on zap versus zerolog etc.)

@smoorpal
Copy link
Contributor Author

@nmiyake I have an RFC going into detail on why we should make this change. I initially started this as a demonstration and wanted to use the PR to easily demonstrate the changes required. I already tagged Brad but I will also tag you in the RFC so you can take a look. I would like to get comments from you and other maintainers here and we can decide whether this is the right approach and whether this fork can be modified to accommodate any comments from the maintainers.

Copy link
Contributor

@bmoylan bmoylan left a comment

Choose a reason for hiding this comment

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

Reviewed 93 of 96 files at r1, 2 of 2 files at r3, 1 of 1 files at r4.
Reviewable status: all files reviewed, 5 unresolved discussions (waiting on @smoorpal)


go.mod, line 1 at r4 (raw file):

module github.com/smoorpal/witchcraft-go-logging

revert changes to this file before merging


wlog/svclog/svc1log/svc1logtests/tests.go, line 403 at r4 (raw file):

	benchmarkCases := make([]TestCase,0,len(testCases))
	for _, testCase := range testCases {
		if testCase.Name!="duplicate origin" && testCase.Name!="parameter that is set manually overrides base value" {

why can't we benchmark these?


wlog/svclog/svc1log/svc1logtests/tests.go, line 460 at r4 (raw file):

			require.NoError(t, err, "Case %d: %s\nService log line is not a valid map: %v", i, tc.Name, string(logEntry))
			logEntryRewrite, err := safejson.Marshal(gotServiceLog)
			assert.Equal(t, len(strings.TrimRight(string(logEntry),"\n")), len(string(logEntryRewrite)), "log line is not stable. Differing length on remarshal")

some of these are failing, do we know why?


wlog/svclog/svc1log/svc1logtests/tests.go, line 557 at r4 (raw file):

			b.ResetTimer()
			for i := 0; i<b.N; i++ {
				buf.Truncate(0)

use buf.Reset()


wlog-zap/internal/logger.go, line 29 at r4 (raw file):

)

type zapMapLogEntry struct {

We'll probably (also) want a zerolog implemenation - did you look into ways to implement this in wlog so it can be used by all logger implementations?

Copy link
Contributor Author

@smoorpal smoorpal 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: all files reviewed, 5 unresolved discussions (waiting on @bmoylan and @smoorpal)


wlog/svclog/svc1log/svc1logtests/tests.go, line 403 at r4 (raw file):

Previously, bmoylan (Brad Moylan) wrote…

why can't we benchmark these?

These tests currently produce errors for the new implementation of the logger and I don't believe the benchmarks will register if there is a failed test. We need to fix these tests in the course of submitting this PR now that we know the issue with parsing duplicate fields.


wlog/svclog/svc1log/svc1logtests/tests.go, line 460 at r4 (raw file):

Previously, bmoylan (Brad Moylan) wrote…

some of these are failing, do we know why?

I use this to check if the logger will print duplicate lines. This fails when the existing logger is used and the log entry has duplicate parameters.


wlog/svclog/svc1log/svc1logtests/tests.go, line 557 at r4 (raw file):

Previously, bmoylan (Brad Moylan) wrote…

use buf.Reset()

Done.

@smoorpal
Copy link
Contributor Author

smoorpal commented Jul 7, 2020

@bmoylan I only see zerolog used in one application the logproxy owned by devtools. We could request them to switch to wlog-zap and deprecate wlog-zerlog.

https://github.palantir.build/search?q=wlog-zerolog&type=Code

@smoorpal
Copy link
Contributor Author

smoorpal commented Jul 7, 2020

I looked at this more. Its going to be difficult to deduplicate zerolog at the moment without losing the performance and memory improvements associated with it. I think we should consider releasing the change to wlog-zap which a great majority of applications are using and either deprecate or remove zerolog until we have a solution which will allow us to keep the improvements in caelumd and rubixbeat.

@smoorpal
Copy link
Contributor Author

smoorpal commented Jul 8, 2020

One option I can explore for deduplicating zero-log would be to reverse the array of params before they are applied to the zeroLogEntry. Then on each application of a <key,value> to the zeroLogEntry store the key in a set. If the key has been seen then do not apply the parameter to this entry. If we use string pointers for the set then we should only increase memory by the amount of pointers in the set. This would also have the effect of reversing the fields in the json byte string written to disk but zero-log I believe already is printing keys in a different order. Nonetheless, the arrangement of the keys in a map of a json string should have no functional effect on any services parsing the string.

…to avoid printing zerolog info level. All levels for zerolog are printed at the beginning of the message and use a lowercase enum. This lowercase is inconsistent with sls defined uppercase enums. Each field key should only appear once so we must print the correctly capitalized level names at the time that we apply params
regexp.QuoteMeta(`[WARNING] github.com/palantir/witchcraft-go-logging/wlog_test.TestOutputFromContextEmptyContext`) + ".+" + regexp.QuoteMeta(`/github.com/palantir/witchcraft-go-logging/wlog/context_default_test.go:`) + "[0-9]+" + regexp.QuoteMeta(`]: usage of `+loggerTestCaseInfo.loggerPkg+`.Logger from FromContext that did not have that logger set: `))
firstPortionRegexp, err := regexp.Compile(
regexp.QuoteMeta(`[WARNING]`) + ".*" + regexp.QuoteMeta(`github.com/`) + ".+" + regexp.QuoteMeta(`/witchcraft-go-logging/wlog_test.TestOutputFromContextEmptyContext`) + ".+" + regexp.QuoteMeta(`/github.com/`) + ".+" + regexp.QuoteMeta(`/witchcraft-go-logging/wlog/context_default_test.go:`) + "[0-9]+" + regexp.QuoteMeta(`]: usage of `+loggerTestCaseInfo.loggerPkg+`.Logger from FromContext that did not have that logger set: `))
require.NoError(t, err, "Unexpected error compiling regex")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was modified so that people testing on a fork do not look for the specific path that depends on not being a fork. i.e. github.com/[^/]+/witchcraft-go-logging is valid.

@@ -310,7 +311,61 @@ something/something:123`,
}),
}),
},
{
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I removed the duplicate safe param test because we are considering this a user error. This is the policy decided for Java. If a user adds duplicate safe params then their line will eventually not be parsed or result in a performance hit when falling back. Zerolog is difficult to enforce this and probably not worth it since you have to reverse all parameters being applied to it to catch the few bad actors.

@@ -362,6 +417,9 @@ func jsonOutputTests(t *testing.T, loggerProvider func(w io.Writer, level wlog.L
logEntry := buf.Bytes()
err := safejson.Unmarshal(logEntry, &gotServiceLog)
require.NoError(t, err, "Case %d: %s\nService log line is not a valid map: %v", i, tc.Name, string(logEntry))
logEntryRewrite, err := safejson.Marshal(gotServiceLog)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This set of assertions parses the printed service log and rewrites it. If the bytes are not the same length then duplicate fields must have been printed.

Copy link
Contributor Author

@smoorpal smoorpal 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: 0 of 7 files reviewed, 8 unresolved discussions (waiting on @bmoylan)


go.mod, line 1 at r4 (raw file):

Previously, bmoylan (Brad Moylan) wrote…

revert changes to this file before merging

Done.


wlog-zap/internal/logger.go, line 29 at r4 (raw file):

Previously, bmoylan (Brad Moylan) wrote…

We'll probably (also) want a zerolog implemenation - did you look into ways to implement this in wlog so it can be used by all logger implementations?

Done.

@smoorpal
Copy link
Contributor Author

smoorpal commented Jul 8, 2020

name old time/op (ns/op) ± new time/op (ns/op) ± delta ±
Audit2Log/basic_audit_log_entry/zap-16 4.48570E+03 6% 5.46186E+03 1% +21.76% (p=0.000 n=10+7)
Diag1Log/generic_diagnostic_log_entry/zap-16 3.72560E+03 9% 3.86700E+03 8% ~ (p=0.089 n=10+10)
Diag1Log/thread_dump_diagnostic_log_entry/zap-16 5.27020E+03 7% 5.48550E+03 10% ~ (p=0.052 n=10+10)
Evt2Log/basic_event_log_entry/zap-16 4.04838E+03 2% 4.60440E+03 14% +13.73% (p=0.000 n=8+10)
Metric1Log/basic_metric_log_entry/zap-16 5.74640E+03 6% 5.83744E+03 7% ~ (p=0.720 n=10+9)
Req2Log/request.2_log_entry_with_no_whitelisted_content/zap-16 1.19155E+04 6% 1.32058E+04 15% +10.83% (p=0.001 n=10+10)
Req2Log/request.2_log_entry_with_forbidden_header/zap-16 1.17601E+04 10% 1.29468E+04 14% +10.09% (p=0.003 n=10+10)
Req2Log/request.2_log_entry_with_whitelisted_header/zap-16 1.16099E+04 9% 1.28911E+04 14% +11.04% (p=0.001 n=10+10)
Req2Log/request.2_log_entry_with_one_whitelisted_query_parameter/zap-16 1.17958E+04 15% 1.28904E+04 9% +9.28% (p=0.004 n=10+10)
Req2Log/request.2_log_entry_with_multi-value_parameters/zap-16 1.53660E+04 8% 1.61482E+04 9% ~ (p=0.052 n=10+10)
Req2Log/request.2_log_entry_with_default_safe_header_User-Agent/zap-16 1.27559E+04 7% 1.41352E+04 16% +10.81% (p=0.001 n=10+10)
Svc1Log/basic_service_log_entry/zap-16 4.51490E+03 7% 4.68170E+03 5% ~ (p=0.089 n=10+10)
Svc1Log/service_log_entry_with_non-primitive_objects_in_params_map/zap-16 6.76330E+03 6% 6.86220E+03 9% ~ (p=0.247 n=10+10)
Svc1Log/service_log_entry_with_origin_set_on_base_logger/zap-16 3.05690E+03 5% 3.15310E+03 6% +3.15% (p=0.041 n=10+10)
Svc1Log/parameter_that_is_set_manually_overrides_base_value/zap-16 1.45060E+03 10% 1.72500E+03 8% +18.92% (p=0.000 n=10+10)
Svc1Log/stacktrace_includes_error_parameters/zap-16 3.94350E+03 7% 4.20900E+03 11% +6.73% (p=0.011 n=10+10)
Svc1Log/parameters_included_from_ParamStorer_parameter/zap-16 3.15050E+03 11% 3.23860E+03 7% ~ (p=0.073 n=10+10)
Svc1Log/param_isn't_overwritten_by_params/zap-16 2.27970E+03 7% 2.52940E+03 8% +10.95% (p=0.000 n=10+10)
Trc1Log/trace.1_log_entry/zap-16 3.81420E+03 14% 4.10270E+03 9% +7.56% (p=0.015 n=10+10)
Trc1Log/trace.1_log_entry_with_server_mode_annotations/zap-16 3.67500E+03 3% 4.11330E+03 7% +11.93% (p=0.000 n=8+10)
name old alloc/op (B/op) ± new alloc/op (B/op) ± delta ±
Audit2Log/basic_audit_log_entry/zap-16 3.65600E+03 0% 3.60800E+03 0% -1.31% (p=0.000 n=10+10)
Diag1Log/generic_diagnostic_log_entry/zap-16 1.82900E+03 0% 1.94100E+03 0% +6.12% (p=0.000 n=10+10)
Diag1Log/thread_dump_diagnostic_log_entry/zap-16 2.26200E+03 0% 2.37400E+03 0% +4.95% (p=0.000 n=10+10)
Evt2Log/basic_event_log_entry/zap-16 3.14230E+03 0% 3.25500E+03 0% +3.59% (p=0.000 n=10+10)
Metric1Log/basic_metric_log_entry/zap-16 4.28100E+03 0% 3.49500E+03 0% -18.36% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_no_whitelisted_content/zap-16 6.91900E+03 0% 7.07700E+03 0% +2.28% (p=0.000 n=10+9)
Req2Log/request.2_log_entry_with_forbidden_header/zap-16 6.91900E+03 0% 7.07700E+03 0% +2.28% (p=0.000 n=9+10)
Req2Log/request.2_log_entry_with_whitelisted_header/zap-16 6.91900E+03 0% 7.07700E+03 0% +2.28% (p=0.000 n=10+9)
Req2Log/request.2_log_entry_with_one_whitelisted_query_parameter/zap-16 6.91900E+03 0% 7.07700E+03 0% +2.28% (p=0.000 n=10+8)
Req2Log/request.2_log_entry_with_multi-value_parameters/zap-16 7.34150E+03 0% 7.49960E+03 0% +2.15% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_default_safe_header_User-Agent/zap-16 7.64100E+03 0% 7.92730E+03 0% +3.75% (p=0.000 n=10+10)
Svc1Log/basic_service_log_entry/zap-16 3.19100E+03 0% 3.17500E+03 0% -0.50% (p=0.000 n=10+10)
Svc1Log/service_log_entry_with_non-primitive_objects_in_params_map/zap-16 3.16100E+03 0% 3.08100E+03 0% -2.53% (p=0.000 n=10+9)
Svc1Log/service_log_entry_with_origin_set_on_base_logger/zap-16 1.74700E+03 0% 1.79600E+03 0% +2.80% (p=0.000 n=9+10)
Svc1Log/parameter_that_is_set_manually_overrides_base_value/zap-16 3.52000E+02 0% 6.57000E+02 0% +86.65% (p=0.000 n=10+10)
Svc1Log/stacktrace_includes_error_parameters/zap-16 2.43900E+03 0% 2.61600E+03 0% +7.26% (p=0.000 n=10+10)
Svc1Log/parameters_included_from_ParamStorer_parameter/zap-16 1.69900E+03 0% 1.74770E+03 0% +2.87% (p=0.000 n=10+10)
Svc1Log/param_isn't_overwritten_by_params/zap-16 1.09000E+03 0% 1.33100E+03 0% +22.11% (p=0.000 n=10+10)
Trc1Log/trace.1_log_entry/zap-16 1.45200E+03 0% 1.75700E+03 0% +21.01% (p=0.000 n=10+10)
Trc1Log/trace.1_log_entry_with_server_mode_annotations/zap-16 1.45200E+03 0% 1.75700E+03 0% +21.01% (p=0.000 n=10+10)
  • parameter_that_is_set_manually_overrides_base_value this test adds nothing but an origin override. Since it has no other parameters the extra memory allocated for the map is pronounced.
  • **param_isn't_overwritten_by_params also only replaces a single parameter.
name old allocs/op (allocs/op) ± new allocs/op (allocs/op) ± delta ±
Audit2Log/basic_audit_log_entry/zap-16 3.10000E+01 0% 3.90000E+01 0% +25.81% (p=0.000 n=10+10)
Diag1Log/generic_diagnostic_log_entry/zap-16 2.90000E+01 0% 3.10000E+01 0% +6.90% (p=0.000 n=10+10)
Diag1Log/thread_dump_diagnostic_log_entry/zap-16 3.90000E+01 0% 4.10000E+01 0% +5.13% (p=0.000 n=10+10)
Evt2Log/basic_event_log_entry/zap-16 3.40000E+01 0% 3.80000E+01 0% +11.76% (p=0.000 n=10+10)
Metric1Log/basic_metric_log_entry/zap-16 3.50000E+01 0% 3.90000E+01 0% +11.43% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_no_whitelisted_content/zap-16 8.20000E+01 0% 9.20000E+01 0% +12.20% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_forbidden_header/zap-16 8.20000E+01 0% 9.20000E+01 0% +12.20% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_whitelisted_header/zap-16 8.20000E+01 0% 9.20000E+01 0% +12.20% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_one_whitelisted_query_parameter/zap-16 8.20000E+01 0% 9.20000E+01 0% +12.20% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_multi-value_parameters/zap-16 9.70000E+01 0% 1.07000E+02 0% +10.31% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_default_safe_header_User-Agent/zap-16 9.00000E+01 0% 1.00000E+02 0% +11.11% (p=0.000 n=10+10)
Svc1Log/basic_service_log_entry/zap-16 3.30000E+01 0% 3.60000E+01 0% +9.09% (p=0.000 n=10+10)
Svc1Log/service_log_entry_with_non-primitive_objects_in_params_map/zap-16 4.00000E+01 0% 4.30000E+01 0% +7.50% (p=0.000 n=10+10)
Svc1Log/service_log_entry_with_origin_set_on_base_logger/zap-16 2.10000E+01 0% 2.20000E+01 0% +4.76% (p=0.000 n=10+10)
Svc1Log/parameter_that_is_set_manually_overrides_base_value/zap-16 7.00000E+00 0% 1.00000E+01 0% +42.86% (p=0.000 n=10+10)
Svc1Log/stacktrace_includes_error_parameters/zap-16 2.80000E+01 0% 3.00000E+01 0% +7.14% (p=0.000 n=10+10)
Svc1Log/parameters_included_from_ParamStorer_parameter/zap-16 2.20000E+01 0% 2.30000E+01 0% +4.55% (p=0.000 n=10+10)
Svc1Log/param_isn't_overwritten_by_params/zap-16 1.50000E+01 0% 1.70000E+01 0% +13.33% (p=0.000 n=10+10)
Trc1Log/trace.1_log_entry/zap-16 3.30000E+01 0% 3.60000E+01 0% +9.09% (p=0.000 n=10+10)
Trc1Log/trace.1_log_entry_with_server_mode_annotations/zap-16 3.30000E+01 0% 3.60000E+01 0% +9.09% (p=0.000 n=10+10)

@smoorpal
Copy link
Contributor Author

smoorpal commented Jul 8, 2020

name old time/op (ns/op) ± new time/op (ns/op) ± delta ±
Audit2Log/basic_audit_log_entry/zerolog-16 2.55540E+03 8% 3.46680E+03 8% +35.67% (p=0.000 n=10+10)
Diag1Log/generic_diagnostic_log_entry/zerolog-16 2.58320E+03 8% 2.82210E+03 6% +9.25% (p=0.004 n=10+10)
Diag1Log/thread_dump_diagnostic_log_entry/zerolog-16 4.02490E+03 8% 4.24070E+03 13% ~ (p=0.089 n=10+10)
Evt2Log/basic_event_log_entry/zerolog-16 2.86940E+03 10% 3.25930E+03 16% +13.59% (p=0.001 n=10+10)
Metric1Log/basic_metric_log_entry/zerolog-16 4.07640E+03 6% 4.52444E+03 14% +10.99% (p=0.002 n=10+9)
Req2Log/request.2_log_entry_with_no_whitelisted_content/zerolog-16 9.18910E+03 8% 1.06810E+04 13% +16.24% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_forbidden_header/zerolog-16 9.39250E+03 8% 1.06919E+04 11% +13.83% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_whitelisted_header/zerolog-16 8.89050E+03 1% 1.07180E+04 12% +20.56% (p=0.000 n=8+10)
Req2Log/request.2_log_entry_with_one_whitelisted_query_parameter/zerolog-16 9.36590E+03 9% 1.05169E+04 8% +12.29% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_multi-value_parameters/zerolog-16 1.18166E+04 9% 1.28406E+04 6% +8.67% (p=0.009 n=10+10)
Req2Log/request.2_log_entry_with_default_safe_header_User-Agent/zerolog-16 1.04786E+04 6% 1.12551E+04 7% +7.41% (p=0.000 n=10+9)
Svc1Log/basic_service_log_entry/zerolog-16 3.20010E+03 6% 3.43750E+03 7% +7.42% (p=0.023 n=10+10)
Svc1Log/service_log_entry_with_non-primitive_objects_in_params_map/zerolog-16 5.21260E+03 7% 5.31790E+03 9% ~ (p=0.342 n=10+10)
Svc1Log/service_log_entry_with_origin_set_on_base_logger/zerolog-16 2.27950E+03 8% 2.45910E+03 6% +7.88% (p=0.003 n=10+10)
Svc1Log/parameter_that_is_set_manually_overrides_base_value/zerolog-16 8.34300E+02 10% 1.01760E+03 8% +21.97% (p=0.000 n=10+10)
Svc1Log/stacktrace_includes_error_parameters/zerolog-16 2.98900E+03 1% 3.29290E+03 13% +10.17% (p=0.000 n=9+10)
Svc1Log/parameters_included_from_ParamStorer_parameter/zerolog-16 2.19520E+03 11% 2.35320E+03 7% +7.20% (p=0.023 n=10+10)
Svc1Log/param_isn't_overwritten_by_params/zerolog-16 1.80380E+03 7% 2.03810E+03 7% +12.99% (p=0.000 n=10+10)
Trc1Log/trace.1_log_entry/zerolog-16 2.90430E+03 9% 3.16270E+03 10% +8.90% (p=0.011 n=10+10)
Trc1Log/trace.1_log_entry_with_server_mode_annotations/zerolog-16 2.86260E+03 12% 3.20600E+03 12% +12.00% (p=0.002 n=10+10)
name old alloc/op (B/op) ± new alloc/op (B/op) ± delta ±
Audit2Log/basic_audit_log_entry/zerolog-16 1.52200E+03 0% 2.19600E+03 0% +44.28% (p=0.000 n=10+8)
Diag1Log/generic_diagnostic_log_entry/zerolog-16 1.25700E+03 0% 1.51400E+03 0% +20.45% (p=0.000 n=10+10)
Diag1Log/thread_dump_diagnostic_log_entry/zerolog-16 1.72400E+03 0% 1.98000E+03 0% +14.85% (p=0.000 n=10+10)
Evt2Log/basic_event_log_entry/zerolog-16 2.01900E+03 0% 2.27500E+03 0% +12.68% (p=0.000 n=10+10)
Metric1Log/basic_metric_log_entry/zerolog-16 2.05900E+03 0% 2.31500E+03 0% +12.43% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_no_whitelisted_content/zerolog-16 4.87900E+03 0% 5.56600E+03 0% +14.08% (p=0.000 n=10+9)
Req2Log/request.2_log_entry_with_forbidden_header/zerolog-16 4.87900E+03 0% 5.56600E+03 0% +14.08% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_whitelisted_header/zerolog-16 4.87900E+03 0% 5.56600E+03 0% +14.08% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_one_whitelisted_query_parameter/zerolog-16 4.87900E+03 0% 5.56600E+03 0% +14.08% (p=0.000 n=10+9)
Req2Log/request.2_log_entry_with_multi-value_parameters/zerolog-16 5.29700E+03 0% 5.98340E+03 0% +12.96% (p=0.000 n=9+10)
Req2Log/request.2_log_entry_with_default_safe_header_User-Agent/zerolog-16 5.55200E+03 0% 6.23900E+03 0% +12.37% (p=0.000 n=10+9)
Svc1Log/basic_service_log_entry/zerolog-16 2.01900E+03 0% 2.27500E+03 0% +12.68% (p=0.000 n=10+10)
Svc1Log/service_log_entry_with_non-primitive_objects_in_params_map/zerolog-16 2.06700E+03 0% 2.32300E+03 0% +12.39% (p=0.000 n=10+10)
Svc1Log/service_log_entry_with_origin_set_on_base_logger/zerolog-16 1.16900E+03 0% 1.42600E+03 0% +21.98% (p=0.000 n=10+10)
Svc1Log/parameter_that_is_set_manually_overrides_base_value/zerolog-16 1.44000E+02 0% 4.00000E+02 0% +177.78% (p=0.000 n=10+10)
Svc1Log/stacktrace_includes_error_parameters/zerolog-16 1.87600E+03 0% 2.13270E+03 0% +13.68% (p=0.000 n=10+10)
Svc1Log/parameters_included_from_ParamStorer_parameter/zerolog-16 1.16900E+03 0% 1.42600E+03 0% +21.98% (p=0.000 n=10+10)
Svc1Log/param_isn't_overwritten_by_params/zerolog-16 8.17000E+02 0% 1.07300E+03 0% +31.33% (p=0.000 n=10+10)
Trc1Log/trace.1_log_entry/zerolog-16 1.24100E+03 0% 1.49800E+03 0% +20.71% (p=0.000 n=10+10)
Trc1Log/trace.1_log_entry_with_server_mode_annotations/zerolog-16 1.24100E+03 0% 1.49800E+03 0% +20.71% (p=0.000 n=10+10)
name old allocs/op (allocs/op) ± new allocs/op (allocs/op) ± delta ±
Audit2Log/basic_audit_log_entry/zerolog-16 2.10000E+01 0% 2.40000E+01 0% +14.29% (p=0.000 n=10+10)
Diag1Log/generic_diagnostic_log_entry/zerolog-16 2.40000E+01 0% 2.60000E+01 0% +8.33% (p=0.000 n=10+10)
Diag1Log/thread_dump_diagnostic_log_entry/zerolog-16 3.50000E+01 0% 3.70000E+01 0% +5.71% (p=0.000 n=10+10)
Evt2Log/basic_event_log_entry/zerolog-16 2.30000E+01 0% 2.50000E+01 0% +8.70% (p=0.000 n=10+10)
Metric1Log/basic_metric_log_entry/zerolog-16 2.90000E+01 0% 3.10000E+01 0% +6.90% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_no_whitelisted_content/zerolog-16 7.70000E+01 0% 8.00000E+01 0% +3.90% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_forbidden_header/zerolog-16 7.70000E+01 0% 8.00000E+01 0% +3.90% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_whitelisted_header/zerolog-16 7.70000E+01 0% 8.00000E+01 0% +3.90% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_one_whitelisted_query_parameter/zerolog-16 7.70000E+01 0% 8.00000E+01 0% +3.90% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_multi-value_parameters/zerolog-16 9.20000E+01 0% 9.50000E+01 0% +3.26% (p=0.000 n=10+10)
Req2Log/request.2_log_entry_with_default_safe_header_User-Agent/zerolog-16 8.30000E+01 0% 8.60000E+01 0% +3.61% (p=0.000 n=10+10)
Svc1Log/basic_service_log_entry/zerolog-16 2.30000E+01 0% 2.50000E+01 0% +8.70% (p=0.000 n=10+10)
Svc1Log/service_log_entry_with_non-primitive_objects_in_params_map/zerolog-16 3.50000E+01 0% 3.70000E+01 0% +5.71% (p=0.000 n=10+10)
Svc1Log/service_log_entry_with_origin_set_on_base_logger/zerolog-16 1.50000E+01 0% 1.70000E+01 0% +13.33% (p=0.000 n=10+10)
Svc1Log/parameter_that_is_set_manually_overrides_base_value/zerolog-16 5.00000E+00 0% 7.00000E+00 0% +40.00% (p=0.000 n=10+10)
Svc1Log/stacktrace_includes_error_parameters/zerolog-16 2.10000E+01 0% 2.30000E+01 0% +9.52% (p=0.000 n=10+10)
Svc1Log/parameters_included_from_ParamStorer_parameter/zerolog-16 1.50000E+01 0% 1.70000E+01 0% +13.33% (p=0.000 n=10+10)
Svc1Log/param_isn't_overwritten_by_params/zerolog-16 1.20000E+01 0% 1.40000E+01 0% +16.67% (p=0.000 n=10+10)
Trc1Log/trace.1_log_entry/zerolog-16 3.10000E+01 0% 3.30000E+01 0% +6.45% (p=0.000 n=10+10)
Trc1Log/trace.1_log_entry_with_server_mode_annotations/zerolog-16 3.10000E+01 0% 3.30000E+01 0% +6.45% (p=0.000 n=10+10)

Copy link
Contributor

@bmoylan bmoylan left a comment

Choose a reason for hiding this comment

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

Reviewed 4 of 97 files at r6, 1 of 2 files at r7, 3 of 5 files at r8, 1 of 1 files at r9, 1 of 1 files at r10.
Reviewable status: all files reviewed, 7 unresolved discussions (waiting on @smoorpal)


wlog/context_default_test.go, line 177 at r8 (raw file):

Previously, smoorpal wrote…

This was modified so that people testing on a fork do not look for the specific path that depends on not being a fork. i.e. github.com/[^/]+/witchcraft-go-logging is valid.

In general we'd recommend using git remotes for working on forks instead of a different module name/location. If we have to go this route I'd replace .* with [^/]+ just to be a little more specific.


wlog/svclog/svc1log/svc1logtests/tests.go, line 403 at r4 (raw file):

Previously, smoorpal wrote…

These tests currently produce errors for the new implementation of the logger and I don't believe the benchmarks will register if there is a failed test. We need to fix these tests in the course of submitting this PR now that we know the issue with parsing duplicate fields.

do these still need to be ignored?


wlog/svclog/svc1log/svc1logtests/tests.go, line 314 at r8 (raw file):

Previously, smoorpal wrote…

I removed the duplicate safe param test because we are considering this a user error. This is the policy decided for Java. If a user adds duplicate safe params then their line will eventually not be parsed or result in a performance hit when falling back. Zerolog is difficult to enforce this and probably not worth it since you have to reverse all parameters being applied to it to catch the few bad actors.

Doesn't this happen in practice if I have a param set on a context and then override that param at the log site? E.g.

ctx := wparams.ContextWithSafeParam(ctx, "key", "value1")
svc1log.FromContext(ctx).Info("msg", svc1log.SafeParam("key", "value2")

I think this is common enough that we should handle it, but because params are stored in a map we should get it for free, no?


wlog/svclog/svc1log/svc1logtests/tests.go, line 420 at r8 (raw file):

Previously, smoorpal wrote…

This set of assertions parses the printed service log and rewrites it. If the bytes are not the same length then duplicate fields must have been printed.

Could you add this context to the assert message below? Something like Differing length on remarshal, possibly due to duplicate keys in the original payload


wlog/svclog/svc1log/svc1logtests/tests.go, line 508 at r10 (raw file):

}

func JSONBenchmarkSuite(b *testing.B, loggerProvider func(w io.Writer, level wlog.LogLevel, origin string) svc1log.Logger) {

How are these different than https://github.com/palantir/witchcraft-go-logging/blob/develop/benchmarks/benchmark_test.go?


wlog-zerolog/internal/logger.go, line 35 at r10 (raw file):

func (e *zeroLogEntry) keyExists(key string) bool {
	if i, exists := e.keys[key]; exists {
		e.keys[key] = i + 1

Are these int values used anywhere? I see us counting the occurrences but never using those counts. Could this map be replaced by a simpler map[string]struct{}?


wlog-zerolog/internal/logger.go, line 163 at r10 (raw file):

}

func reverseParams(params []wlog.Param) []wlog.Param {

nit: maybe better to not have a return value to make it clearer that this is happening in-place

Copy link
Contributor Author

@smoorpal smoorpal 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: 3 of 7 files reviewed, 5 unresolved discussions (waiting on @bmoylan)


wlog/context_default_test.go, line 177 at r8 (raw file):

Previously, bmoylan (Brad Moylan) wrote…

In general we'd recommend using git remotes for working on forks instead of a different module name/location. If we have to go this route I'd replace .* with [^/]+ just to be a little more specific.

Added more specific regex.


wlog/svclog/svc1log/svc1logtests/tests.go, line 403 at r4 (raw file):

Previously, bmoylan (Brad Moylan) wrote…

do these still need to be ignored?

I removed the benchmarks I have added to this file. Everything I was trying to do is encapsulated in the top level benchmarks directory. This directory benchmarks all test suites and includes the referenced tests without problem.


wlog/svclog/svc1log/svc1logtests/tests.go, line 314 at r8 (raw file):

ContextWithSafeParam
Interesting. I wasn't aware that params were stored when the logger was created like this. I expanded wlog/svc1log/context_test.go in order to test each type of logger when parameters are added to the context and when they overwrite the context params. In order to do this I had to take out the AnyMap implementation in zerolog and replace it with something specific. Now that parameters are passed in reverse we want to avoid setting a safe/unsafe param if it is already set.


wlog/svclog/svc1log/svc1logtests/tests.go, line 508 at r10 (raw file):

Previously, bmoylan (Brad Moylan) wrote…

How are these different than https://github.com/palantir/witchcraft-go-logging/blob/develop/benchmarks/benchmark_test.go?

They are not. I wrote something special to compare the map implementation and have now removed it.


wlog-zerolog/internal/logger.go, line 35 at r10 (raw file):

Previously, bmoylan (Brad Moylan) wrote…

Are these int values used anywhere? I see us counting the occurrences but never using those counts. Could this map be replaced by a simpler map[string]struct{}?

Yep makes sense. Done.

Copy link
Contributor Author

@smoorpal smoorpal 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: 3 of 7 files reviewed, 3 unresolved discussions (waiting on @bmoylan)


wlog/svclog/svc1log/svc1logtests/tests.go, line 403 at r4 (raw file):

Previously, smoorpal wrote…

I removed the benchmarks I have added to this file. Everything I was trying to do is encapsulated in the top level benchmarks directory. This directory benchmarks all test suites and includes the referenced tests without problem.

Done.


wlog/svclog/svc1log/svc1logtests/tests.go, line 508 at r10 (raw file):

Previously, smoorpal wrote…

They are not. I wrote something special to compare the map implementation and have now removed it.

Done.


wlog-zerolog/internal/logger.go, line 35 at r10 (raw file):

Previously, smoorpal wrote…

Yep makes sense. Done.

Done.

Copy link
Contributor

@bmoylan bmoylan left a comment

Choose a reason for hiding this comment

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

Reviewed 4 of 5 files at r11.
Reviewable status: all files reviewed, 3 unresolved discussions (waiting on @smoorpal)


wlog/svclog/svc1log/svc1logtests/tests.go, line 360 at r11 (raw file):

}

func BenchmarkCases() []TestCase {

looks like this is no longer used


wlog-zerolog/internal/logger.go, line 107 at r11 (raw file):

}

func (e *zeroLogEntry) AnyMapValue(key string, values map[string]interface{}) {

Can you add a comment to these explaining how they differ from the wlog implementation?


wlog-zerolog/internal/logger.go, line 111 at r11 (raw file):

		return
	}
	if len(values) == 0 {

isn't this exactly the same as the block above?

Copy link
Contributor Author

@smoorpal smoorpal 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: 5 of 7 files reviewed, 3 unresolved discussions (waiting on @bmoylan)


wlog/svclog/svc1log/svc1logtests/tests.go, line 360 at r11 (raw file):

Previously, bmoylan (Brad Moylan) wrote…

looks like this is no longer used

Indeed. I missed removing this when I cleared out my custom benchmarks.


wlog-zerolog/internal/logger.go, line 107 at r11 (raw file):

Previously, bmoylan (Brad Moylan) wrote…

Can you add a comment to these explaining how they differ from the wlog implementation?

Sure thing. Added. Let me know if you think its a satisfactory explanation.


wlog-zerolog/internal/logger.go, line 111 at r11 (raw file):

Previously, bmoylan (Brad Moylan) wrote…

isn't this exactly the same as the block above?

Yes. Good catch. I must have messed something up when copying the code.

Copy link
Contributor Author

@smoorpal smoorpal 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: 5 of 7 files reviewed, 3 unresolved discussions (waiting on @bmoylan)


wlog/svclog/svc1log/svc1logtests/tests.go, line 360 at r11 (raw file):

Previously, smoorpal wrote…

Indeed. I missed removing this when I cleared out my custom benchmarks.

Done.


wlog-zerolog/internal/logger.go, line 107 at r11 (raw file):

Previously, smoorpal wrote…

Sure thing. Added. Let me know if you think its a satisfactory explanation.

Done.


wlog-zerolog/internal/logger.go, line 111 at r11 (raw file):

Previously, smoorpal wrote…

Yes. Good catch. I must have messed something up when copying the code.

Done.

Copy link
Contributor

@bmoylan bmoylan left a comment

Choose a reason for hiding this comment

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

:lgtm: thanks for putting up with the long review!

Reviewed 2 of 2 files at r12.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved

@bmoylan
Copy link
Contributor

bmoylan commented Jul 9, 2020

// holding off on merge until we've finalized the rollout plan 👎

@bmoylan
Copy link
Contributor

bmoylan commented Jul 9, 2020

👍

@bmoylan bmoylan merged commit 29f978b into palantir:develop Jul 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants