-
Notifications
You must be signed in to change notification settings - Fork 95
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 config to autoformat stackdriver trace #260
Conversation
@@ -393,6 +399,10 @@ module InternalConstants | |||
config_param :monitoring_type, :string, | |||
:default => Monitoring::PrometheusMonitoringRegistry.name | |||
|
|||
# Whether to autoformat value of "logging.googleapis.com/trace" to | |||
# LogEntry.Trace. | |||
config_param :enable_stackdriver_trace_autoformat, :bool, :default => true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use the imperative form: autoformat_stackdriver_trace
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense. updated.
trace = record.delete(@trace_key) | ||
entry.trace = trace if trace | ||
if trace | ||
if @enable_stackdriver_trace_autoformat && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's extract this into a compute_trace
method and leave this line as:
entry.trace = compute_trace(trace) if trace
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added
test/plugin/base_test.rb
Outdated
config: APPLICATION_DEFAULT_CONFIG | ||
}, | ||
{ | ||
config: 'enable_stackdriver_trace_autoformat true' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please extract this and the next config string into constants, and define them in terms of APPLICATION_DEFAULT_CONFIG
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added configs into constant.
test/plugin/base_test.rb
Outdated
|
||
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry| | ||
expected_trace = \ | ||
"projects/#{d.instance.project_id}" \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a change detector test (it replicates the code under test). Please use the literal value. Better yet, define two constants, one for the compliant trace, and one for the non-compliant trace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, instead of d.instance.project_id
, we could just use PROJECT
, which is defined in the constants.rb
file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was proposing the FULL_STACKDRIVER_TRACE
and NON_STACKDRIVER_TRACE
, same as you... If we define one in terms of the other, we can even use FULL_STACKDRIVER_TRACE
as the expected value here...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The full trace here depends on the project_id
of driver. If we change the whole trace into constant, It's unclear how that project_id
in full trace comes from. I think it's hiding details into constant.
I think this project_id
is local to this scope under the driver here. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point is that the tests should be checking complete expected values. If you expect the resulting trace to have a particular project id, the constant should have that. I was suggesting defining the FULL_STACKDRIVER_TRACE
as:
NON_STACKDRIVER_TRACE = "1234567890abcdef1234567890abcdef".freeze
FULL_STACKDRIVER_TRACE = "projects/#{PROJECT_ID}/traces/#{NON_STACKDRIVER_TRACE}".freeze
in constants.rb
.
test/plugin/base_test.rb
Outdated
config: APPLICATION_DEFAULT_CONFIG | ||
}, | ||
{ | ||
config: 'enable_stackdriver_trace_autoformat true' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test/plugin/base_test.rb
Outdated
@@ -338,6 +338,81 @@ def test_structured_payload_log | |||
end | |||
end | |||
|
|||
def test_stackdriver_trace_format_compliant_trace | |||
full_stackdriver_trace = \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Constant FULL_STACKDRIVER_TRACE
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto - I think the full trace is project-dependent, not constant value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The project we feed into the tests is a constant, though... So we could construct the full expected value as a constant.
test/plugin/base_test.rb
Outdated
end | ||
|
||
def test_autoformat_enabled_with_stackdriver_trace_format_noncompliant_trace | ||
non_stackdriver_trace_compliant_trace = '1234567890abcdef1234567890abcdef' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Constant NON_STACKDRIVER_TRACE
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change this value into constant, but use the name as NON_STACKDRIVER_TRACE_COMPLIANT_TRACE
as this value can be a "Stackdriver Trace", but it is just not compliant to enable cross reference between Stackdriver Logging & Trace.
test/plugin/base_test.rb
Outdated
d.run | ||
|
||
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry| | ||
assert_equal full_stackdriver_trace, entry['trace'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert_equal
can take a third parameter as the error message when the assertion fails. In order to help with debugging, we could something like:
assert_equal full_stackdriver_trace, entry['trace'],
"test_params #{test_params} failed with entry #{entry}."
Same for below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added more informative error messages.
test/plugin/base_test.rb
Outdated
end | ||
|
||
def test_autoformat_disabled_with_stackdriver_trace_format_noncompliant_trace | ||
config = 'enable_stackdriver_trace_autoformat false' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Constant AUTOFORMAT_STACKDRIVER_TRACE_DISABLED_CONFIG
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated.
test/plugin/base_test.rb
Outdated
|
||
def test_autoformat_disabled_with_stackdriver_trace_format_noncompliant_trace | ||
config = 'enable_stackdriver_trace_autoformat false' | ||
non_stackdriver_trace_compliant_trace = '1234567890abcdef1234567890abcdef' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Constant NON_STACKDRIVER_TRACE
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated - see comment above
trace = record.delete(@trace_key) | ||
entry.trace = trace if trace | ||
if trace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably wanna check against empty strings as well? I'm leaning towards not formatting the field if it comes as an empty string. WDYT?
BTW, Ruby will take if <empty_string> as true
.
$ irb
2.4.3 :001 > empty_string = ""
=> ""
2.4.3 :002 > if empty_string then true else false end
=> true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fun read. Oh Ruby... shoot me:
$ irb
2.4.3 :001 > if 0 then true else false end
=> true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will consider it with regexp topic https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud/pull/260/files#r220408736 as they are related.
test/plugin/base_test.rb
Outdated
@@ -338,6 +338,81 @@ def test_structured_payload_log | |||
end | |||
end | |||
|
|||
def test_stackdriver_trace_format_compliant_trace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic in these three tests are almost identical. They could be combined and use something like:
{
config: APPLICATION_DEFAULT_CONFIG,
input_trace: XXX,
expected_trace: XXX
},
This way, it's easier to maintain the shared logic and also execute all tests related to trace
with a single command. It also makes it easier to add more test cases.
BTW, we should also test cases like below in combination of different config values:
- There's no
logging.googleapis.com/trace
field in payload. logging.googleapis.com/trace
field in payload is an empty string.- A custom
trace_key
is used instead of the default trace key. (Reference:trace_key
is configurable: https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud/blob/master/lib/fluent/plugin/out_google_cloud.rb#L284)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to the first suggestion, I still maintain existing way to write test because the error message for each one is different - and the reason to make error message different is: 1) group similar testcases in a single unit and 2) provide more informative error message when the test fails.
Will add other 3 testcases, and consider reorganize testcases to whatever makes sense.
test/plugin/base_test.rb
Outdated
|
||
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry| | ||
expected_trace = \ | ||
"projects/#{d.instance.project_id}" \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, instead of d.instance.project_id
, we could just use PROJECT
, which is defined in the constants.rb
file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more comment.
trace = record.delete(@trace_key) | ||
entry.trace = trace if trace | ||
if trace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test/plugin/base_test.rb
Outdated
|
||
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry| | ||
expected_trace = \ | ||
"projects/#{d.instance.project_id}" \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was proposing the FULL_STACKDRIVER_TRACE
and NON_STACKDRIVER_TRACE
, same as you... If we define one in terms of the other, we can even use FULL_STACKDRIVER_TRACE
as the expected value here...
entry.trace = trace if trace | ||
if trace | ||
if @enable_stackdriver_trace_autoformat && | ||
!STACKDRIVER_TRACE_REGEXP.match(trace) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just realized that a trace value that isn't in the right format but does have a slash will probably produce a log entry that will fail validation. If we adjust it unconditionally, then the resulting error might not make sense to the customers (e.g., "too many slashes" instead of "too few slashes"). We should confirm this behavior and, if my hunch is right, change this to a positive regexp match instead (i.e., only adjust if it has a certain form). WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a valid concern. Agreed we should confirm the behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that trace-value fail validation seems like a deal breaker - agree that if the format is not correct, autoformat should not be conducted.
Even that said, it sounds hard to setup a rule on agent side. There is no official trace-ID format available in public document I can see - so it's hard for me to set a rule to match the [TRACE-ID]
part, and append prefix projects/[PROJECT-ID]/traces/
to it. Do you know who should I confirm with, and is there any service-client contract I can rely on @igorpeshansky ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found format of TraceID is documented and fully supported under Trace API v1 (REST), and Trace API (rpc) - google.devtools.cloudtrace - so I will rely on that to write the regexp matching.
trace = record.delete(@trace_key) | ||
entry.trace = trace if trace | ||
if trace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fun read. Oh Ruby... shoot me:
$ irb
2.4.3 :001 > if 0 then true else false end
=> true
entry.trace = trace if trace | ||
if trace | ||
if @enable_stackdriver_trace_autoformat && | ||
!STACKDRIVER_TRACE_REGEXP.match(trace) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a valid concern. Agreed we should confirm the behavior.
# will match the regexp is: | ||
# "projects/my-project/traces/1234567890abcdef1234567890abcdef" | ||
STACKDRIVER_TRACE_REGEXP = Regexp.new( | ||
'^projects\/[^\/]*\/traces\/[^\/]*$').freeze |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably wanna change the *
to +
in the Regexp, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed the way autoformat works, so we don't need to have complex regexp anymore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated couple things based on feedback, but not fully resolved yet.
Still need to:
- change implementation on regex matching part so it won't confuse user
- add more edge testcases @qingling128 mentioned.
@@ -393,6 +399,10 @@ module InternalConstants | |||
config_param :monitoring_type, :string, | |||
:default => Monitoring::PrometheusMonitoringRegistry.name | |||
|
|||
# Whether to autoformat value of "logging.googleapis.com/trace" to | |||
# LogEntry.Trace. | |||
config_param :enable_stackdriver_trace_autoformat, :bool, :default => true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense. updated.
test/plugin/base_test.rb
Outdated
config: APPLICATION_DEFAULT_CONFIG | ||
}, | ||
{ | ||
config: 'enable_stackdriver_trace_autoformat true' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added configs into constant.
test/plugin/base_test.rb
Outdated
|
||
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry| | ||
expected_trace = \ | ||
"projects/#{d.instance.project_id}" \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The full trace here depends on the project_id
of driver. If we change the whole trace into constant, It's unclear how that project_id
in full trace comes from. I think it's hiding details into constant.
I think this project_id
is local to this scope under the driver here. WDYT?
test/plugin/base_test.rb
Outdated
end | ||
|
||
def test_autoformat_disabled_with_stackdriver_trace_format_noncompliant_trace | ||
config = 'enable_stackdriver_trace_autoformat false' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated.
test/plugin/base_test.rb
Outdated
@@ -338,6 +338,81 @@ def test_structured_payload_log | |||
end | |||
end | |||
|
|||
def test_stackdriver_trace_format_compliant_trace | |||
full_stackdriver_trace = \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto - I think the full trace is project-dependent, not constant value.
test/plugin/base_test.rb
Outdated
d.run | ||
|
||
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry| | ||
assert_equal full_stackdriver_trace, entry['trace'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added more informative error messages.
test/plugin/base_test.rb
Outdated
@@ -338,6 +338,81 @@ def test_structured_payload_log | |||
end | |||
end | |||
|
|||
def test_stackdriver_trace_format_compliant_trace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to the first suggestion, I still maintain existing way to write test because the error message for each one is different - and the reason to make error message different is: 1) group similar testcases in a single unit and 2) provide more informative error message when the test fails.
Will add other 3 testcases, and consider reorganize testcases to whatever makes sense.
trace = record.delete(@trace_key) | ||
entry.trace = trace if trace | ||
if trace | ||
if @enable_stackdriver_trace_autoformat && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added
entry.trace = trace if trace | ||
if trace | ||
if @enable_stackdriver_trace_autoformat && | ||
!STACKDRIVER_TRACE_REGEXP.match(trace) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that trace-value fail validation seems like a deal breaker - agree that if the format is not correct, autoformat should not be conducted.
Even that said, it sounds hard to setup a rule on agent side. There is no official trace-ID format available in public document I can see - so it's hard for me to set a rule to match the [TRACE-ID]
part, and append prefix projects/[PROJECT-ID]/traces/
to it. Do you know who should I confirm with, and is there any service-client contract I can rely on @igorpeshansky ?
trace = record.delete(@trace_key) | ||
entry.trace = trace if trace | ||
if trace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will consider it with regexp topic https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud/pull/260/files#r220408736 as they are related.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
modified the regexp expression and added more testcases.
Didn't implement the customized trace_key
though, because the customized trace_key is already captured in https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud/blob/master/test/plugin/base_test.rb#L1223-L1226 .
# will match the regexp is: | ||
# "projects/my-project/traces/1234567890abcdef1234567890abcdef" | ||
STACKDRIVER_TRACE_REGEXP = Regexp.new( | ||
'^projects\/[^\/]*\/traces\/[^\/]*$').freeze |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed the way autoformat works, so we don't need to have complex regexp anymore
@@ -627,7 +637,8 @@ def write(chunk) | |||
ts_nanos) | |||
|
|||
trace = record.delete(@trace_key) | |||
entry.trace = trace if trace | |||
entry.trace = compute_trace(trace) if trace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as if trace
is existing behavior, I won't change the logic in this PR because it's out of the original scope.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think @qingling128 was suggesting that an empty trace should not match the regexp that causes it to be rewritten...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if trace
is fine now since we are using positive regex match
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ack.
@@ -393,6 +398,10 @@ module InternalConstants | |||
config_param :monitoring_type, :string, | |||
:default => Monitoring::PrometheusMonitoringRegistry.name | |||
|
|||
# Whether to autoformat value of "logging.googleapis.com/trace" to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to provide more informative description on what this configuration does to help guide users. How about:
Whether to autoformat value of "logging.googleapis.com/trace" to comply with Stackdriver Trace format ("projects/[PROJECT-ID]/traces/[TRACE-ID]") when setting the trace field of the LogEntry object.
BTW, once this is released, we can update the public documentation to add this new config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated the comment to clarify the config!
@@ -627,7 +637,8 @@ def write(chunk) | |||
ts_nanos) | |||
|
|||
trace = record.delete(@trace_key) | |||
entry.trace = trace if trace | |||
entry.trace = compute_trace(trace) if trace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if trace
is fine now since we are using positive regex match
test/plugin/base_test.rb
Outdated
NO_AUTOFORMAT_STACKDRIVER_TRACE_CONFIG | ||
] | ||
traces = [ | ||
'', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm... The empty string case seems to have failed the unit test for gRPC. Travis build.
It's probably due to https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud/blob/master/test/plugin/test_out_google_cloud_grpc.rb#L439.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use the function assert_equal_with_default
to be able to verify even it's an empty string ''
test/plugin/base_test.rb
Outdated
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry| | ||
expected_trace = \ | ||
"projects/#{d.instance.project_id}/traces/#{STACKDRIVER_TRACE_ID}" | ||
assert_equal expected_trace, entry['trace'], 'stackdriver trace ' \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great message!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This commit enables OpenCensus log correlation using opencensus-contrib-log-correlation-log4j2 (https://github.com/census-instrumentation/opencensus-java/tree/master/contrib/log_correlation/log4j2). The library inserts the trace ID, span ID, and sampling decision into every Log4j log event. This commit includes other changes to make the tracing data available in the logs, in a format that can be interpreted by the StackDriver Logging agent: - Convert all adservice log statements from java.util.logging to Log4j. - Specify a JSON format for Log4j output. This is related to issue GoogleCloudPlatform#47. - Add the trace ID, span ID, and sampling decision to the JSON format. Trace ID and span ID use special keys that the Stackdriver Logging agent uses to populate the tracing data fields in the LogEntry uploaded to Stackdriver (https://cloud.google.com/logging/docs/agent/configuration#special_fields_in_structured_payloads). However, Stackdriver won't be able to link the traces and log entries until fluent-plugin-google-cloud can automatically format the trace ID with the format expected by Stackdriver (GoogleCloudPlatform/fluent-plugin-google-cloud#239, GoogleCloudPlatform/fluent-plugin-google-cloud#260). This commit also upgrades OpenCensus to 0.16.1 in order to use opencensus-contrib-log-correlation-log4j2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few more.
@@ -393,6 +398,10 @@ module InternalConstants | |||
config_param :monitoring_type, :string, | |||
:default => Monitoring::PrometheusMonitoringRegistry.name | |||
|
|||
# Whether to autoformat value of "logging.googleapis.com/trace" to | |||
# LogEntry.Trace. | |||
config_param :autoformat_stackdriver_trace, :bool, :default => true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest moving this down, after adjust_invalid_timestamps
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
test/plugin/constants.rb
Outdated
@@ -265,6 +267,14 @@ module Constants | |||
enable_metadata_agent false | |||
).freeze | |||
|
|||
AUTOFORMAT_STACKDRIVER_TRACE_CONFIG = %( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ENABLE_TRACE_AUTOFORMAT_CONFIG
. We started this pattern with the metadata_agent configs — I think it's a bit more readable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought you recommended using imperative form for config - and my original config is called enable_stackdriver_trace_autoformat
, which matches what you suggested here.
I will modify this constant to ENABLE_AUTOFORMAT_STACKDRIVER_TRACE
as logging agent will format to stackdriver trace format specifically, not other trace format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry to be unclear. The names for the config constants don't necessarily have to include the full config option name — they just need to be identifiable with that option. We have this pattern elsewhere. I was suggesting that we change <FULL_NAME>_CONFIG
and NO_<FULL_NAME>_CONFIG
to ENABLE_<SHORT_NAME>_CONFIG
and DISABLE_<SHORT_NAME>_CONFIG
. Does this make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make seonse. still decide to use the ENABLE/DISABLE_FULL_NAME_CONFIG
.
test/plugin/constants.rb
Outdated
autoformat_stackdriver_trace true | ||
).freeze | ||
|
||
NO_AUTOFORMAT_STACKDRIVER_TRACE_CONFIG = %( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DISABLE_TRACE_AUTOFORMAT_CONFIG
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto as above
test/plugin/base_test.rb
Outdated
|
||
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry| | ||
expected_trace = \ | ||
"projects/#{d.instance.project_id}" \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point is that the tests should be checking complete expected values. If you expect the resulting trace to have a particular project id, the constant should have that. I was suggesting defining the FULL_STACKDRIVER_TRACE
as:
NON_STACKDRIVER_TRACE = "1234567890abcdef1234567890abcdef".freeze
FULL_STACKDRIVER_TRACE = "projects/#{PROJECT_ID}/traces/#{NON_STACKDRIVER_TRACE}".freeze
in constants.rb
.
test/plugin/base_test.rb
Outdated
"projects/#{PROJECT_ID}/traces/", | ||
"projects/#{PROJECT_ID}/traces/#{NON_STACKDRIVER_TRACE_ID}", | ||
"projects//traces/#{STACKDRIVER_TRACE_ID}", | ||
TRACE # full trace won't be modified either |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: missing trailing .
.
test/plugin/base_test.rb
Outdated
"projects//traces/#{STACKDRIVER_TRACE_ID}", | ||
TRACE # full trace won't be modified either | ||
] | ||
configs.product(traces).collect do |config, trace| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're throwing away the collect
result, so I'd use each
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree - thanks for catching it!
test/plugin/base_test.rb
Outdated
@@ -338,6 +338,98 @@ def test_structured_payload_log | |||
end | |||
end | |||
|
|||
def test_autoformat_enabled_with_stackdriver_trace_id_as_trace | |||
configs = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't bother with just the configs
local variable — just use the array literal. Also below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what do you mean? isn't []
literal constructor? https://docs.ruby-lang.org/en/2.4.0/Array.html#class-Array-label-Creating+Arrays
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant:
[
APPLICATION_DEFAULT_CONFIG,
AUTOFORMAT_STACKDRIVER_TRACE_CONFIG
ENABLE_AUTOFORMAT_STACKDRIVER_TRACE_CONFIG
].each do |config|
...
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated - to make it consistent with rest of the tests if there is only single list to iterate through.
test/plugin/base_test.rb
Outdated
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry| | ||
assert_equal trace, entry['trace'], 'trace as non stackdriver' \ | ||
'trace id should not be autoformatted with ' \ | ||
"config #{config}." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation.
test/plugin/base_test.rb
Outdated
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry| | ||
expected_trace = \ | ||
"projects/#{d.instance.project_id}/traces/#{STACKDRIVER_TRACE_ID}" | ||
assert_equal expected_trace, entry['trace'], 'stackdriver trace ' \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Want to start the message on the next line? That way it's obvious that it's a separate entity...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
modified!
test/plugin/base_test.rb
Outdated
"projects/#{d.instance.project_id}/traces/#{STACKDRIVER_TRACE_ID}" | ||
assert_equal expected_trace, entry['trace'], 'stackdriver trace ' \ | ||
'id should be autoformatted with config ' \ | ||
"#{test_config}." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would just say "should be autoformatted when autoformat_stackdriver_trace is enabled
", rather than print the config (which could at some point become larger than that). Also note that APPLICATION_DEFAULT_CONFIG
is empty, so it'd be confusing to see "with config .
" in the output.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ping?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated - sorry miss this part in the previous change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we do the same in test_non_stackdriver_trace_id_compliant_trace_with_any_autoformat_config
as well? I don't think we have any other tests that interpolate the full config in the message...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
This commit enables OpenCensus log correlation using opencensus-contrib-log-correlation-log4j2 (https://github.com/census-instrumentation/opencensus-java/tree/master/contrib/log_correlation/log4j2). The library inserts the trace ID, span ID, and sampling decision into every Log4j log event. This commit includes other changes to make the tracing data available in the logs, in a format that can be interpreted by the Stackdriver Logging agent: - Convert all adservice log statements from java.util.logging to Log4j. - Specify a JSON format for Log4j output. This is related to issue GoogleCloudPlatform#47. - Add the trace ID, span ID, and sampling decision to the JSON format. Trace ID and span ID use special keys that the Stackdriver Logging agent uses to populate the tracing data fields in the LogEntry uploaded to Stackdriver (https://cloud.google.com/logging/docs/agent/configuration#special_fields_in_structured_payloads). However, Stackdriver won't be able to link the traces and log entries until fluent-plugin-google-cloud can automatically format the trace ID with the format expected by Stackdriver (GoogleCloudPlatform/fluent-plugin-google-cloud#239, GoogleCloudPlatform/fluent-plugin-google-cloud#260). This commit also upgrades OpenCensus to 0.16.1 in order to use opencensus-contrib-log-correlation-log4j2.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly replying to your comments and pinging the ones you didn't respond to.
test/plugin/base_test.rb
Outdated
@@ -338,6 +338,98 @@ def test_structured_payload_log | |||
end | |||
end | |||
|
|||
def test_autoformat_enabled_with_stackdriver_trace_id_as_trace | |||
configs = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant:
[
APPLICATION_DEFAULT_CONFIG,
AUTOFORMAT_STACKDRIVER_TRACE_CONFIG
ENABLE_AUTOFORMAT_STACKDRIVER_TRACE_CONFIG
].each do |config|
...
end
test/plugin/constants.rb
Outdated
@@ -265,6 +267,14 @@ module Constants | |||
enable_metadata_agent false | |||
).freeze | |||
|
|||
AUTOFORMAT_STACKDRIVER_TRACE_CONFIG = %( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry to be unclear. The names for the config constants don't necessarily have to include the full config option name — they just need to be identifiable with that option. We have this pattern elsewhere. I was suggesting that we change <FULL_NAME>_CONFIG
and NO_<FULL_NAME>_CONFIG
to ENABLE_<SHORT_NAME>_CONFIG
and DISABLE_<SHORT_NAME>_CONFIG
. Does this make sense?
test/plugin/base_test.rb
Outdated
@@ -338,6 +338,81 @@ def test_structured_payload_log | |||
end | |||
end | |||
|
|||
def test_stackdriver_trace_format_compliant_trace | |||
full_stackdriver_trace = \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The project we feed into the tests is a constant, though... So we could construct the full expected value as a constant.
@@ -676,6 +686,14 @@ def write(chunk) | |||
|
|||
private | |||
|
|||
def compute_trace(trace) | |||
if @autoformat_stackdriver_trace && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point here is that the important bit is the early return, not the clause. A reader, seeing return trace unless [...]
will think: "Ah, this function will return one of two values — an untransformed one unless some condition holds true, and a transformed one otherwise". Then they can dig into the condition. In the code you're proposing, the logic goes the other way — the reader first has to get through a large condition to figure out how the value is transformed, and then look at the end of the function to see that it's returned.
Incidentally, even if we agree that your current structure is more readable, I think it's better to say return "projects/#{@project_id}/traces/#{trace}"
instead of assigning it back to a parameter trace
only to return it in the end.
test/plugin/base_test.rb
Outdated
d.run | ||
verify_log_entries(1, COMPUTE_PARAMS, 'jsonPayload') do |entry| | ||
expected_trace = \ | ||
"projects/#{d.instance.project_id}/traces/#{STACKDRIVER_TRACE_ID}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The interpolation happens before the freeze
, so the resulting string is a constant. Plus, this would be consistent with the rest of the testing code.
test/plugin/base_test.rb
Outdated
"projects/#{d.instance.project_id}/traces/#{STACKDRIVER_TRACE_ID}" | ||
assert_equal expected_trace, entry['trace'], 'stackdriver trace ' \ | ||
'id should be autoformatted with config ' \ | ||
"#{test_config}." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ping?
test/plugin/base_test.rb
Outdated
"projects/#{d.instance.project_id}/traces/#{STACKDRIVER_TRACE_ID}" | ||
assert_equal expected_trace, entry['trace'], 'stackdriver trace ' \ | ||
'id should be autoformatted with config ' \ | ||
"#{test_config}." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we do the same in test_non_stackdriver_trace_id_compliant_trace_with_any_autoformat_config
as well? I don't think we have any other tests that interpolate the full config in the message...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One comment.
"projects/#{PROJECT_ID}/traces/#{STACKDRIVER_TRACE_ID}".freeze | ||
|
||
# Invalid trace id for stackdriver. | ||
EMPTY_STRING = ''.freeze |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, I think this one is overkill, but I'll let @qingling128 make this call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha, i'm fine with defining an empty string constant. It could be shared by others as well though, not necessarily Invalid trace id for stackdriver
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
) This commit enables OpenCensus log correlation using opencensus-contrib-log-correlation-log4j2 (https://github.com/census-instrumentation/opencensus-java/tree/master/contrib/log_correlation/log4j2). The library inserts the trace ID, span ID, and sampling decision into every Log4j log event. This commit includes other changes to make the tracing data available in the logs, in a format that can be interpreted by the Stackdriver Logging agent: - Convert all adservice log statements from java.util.logging to Log4j. - Specify a JSON format for Log4j output. This is related to issue #47. - Add the trace ID, span ID, and sampling decision to the JSON format. Trace ID and span ID use special keys that the Stackdriver Logging agent uses to populate the tracing data fields in the LogEntry uploaded to Stackdriver (https://cloud.google.com/logging/docs/agent/configuration#special_fields_in_structured_payloads). However, Stackdriver won't be able to link the traces and log entries until fluent-plugin-google-cloud can automatically format the trace ID with the format expected by Stackdriver (GoogleCloudPlatform/fluent-plugin-google-cloud#239, GoogleCloudPlatform/fluent-plugin-google-cloud#260). This commit also upgrades OpenCensus to 0.16.1 in order to use opencensus-contrib-log-correlation-log4j2.
This change is necessary for log correlation to work before GoogleCloudPlatform/fluent-plugin-google-cloud#260 is available.
…nfig. Formatting the trace ID in the logging configuration is no longer necessary now that fluent-plugin-google-cloud formats the trace ID (GoogleCloudPlatform/fluent-plugin-google-cloud#260).
…nfig. (#68) Formatting the trace ID in the logging configuration is no longer necessary now that fluent-plugin-google-cloud formats the trace ID (GoogleCloudPlatform/fluent-plugin-google-cloud#260).
…nfig. (#68) Formatting the trace ID in the logging configuration is no longer necessary now that fluent-plugin-google-cloud formats the trace ID (GoogleCloudPlatform/fluent-plugin-google-cloud#260).
…#59) This commit enables OpenCensus log correlation using opencensus-contrib-log-correlation-log4j2 (https://github.com/census-instrumentation/opencensus-java/tree/master/contrib/log_correlation/log4j2). The library inserts the trace ID, span ID, and sampling decision into every Log4j log event. This commit includes other changes to make the tracing data available in the logs, in a format that can be interpreted by the Stackdriver Logging agent: - Convert all adservice log statements from java.util.logging to Log4j. - Specify a JSON format for Log4j output. This is related to issue #47. - Add the trace ID, span ID, and sampling decision to the JSON format. Trace ID and span ID use special keys that the Stackdriver Logging agent uses to populate the tracing data fields in the LogEntry uploaded to Stackdriver (https://cloud.google.com/logging/docs/agent/configuration#special_fields_in_structured_payloads). However, Stackdriver won't be able to link the traces and log entries until fluent-plugin-google-cloud can automatically format the trace ID with the format expected by Stackdriver (GoogleCloudPlatform/fluent-plugin-google-cloud#239, GoogleCloudPlatform/fluent-plugin-google-cloud#260). This commit also upgrades OpenCensus to 0.16.1 in order to use opencensus-contrib-log-correlation-log4j2.
…#59) This commit enables OpenCensus log correlation using opencensus-contrib-log-correlation-log4j2 (https://github.com/census-instrumentation/opencensus-java/tree/master/contrib/log_correlation/log4j2). The library inserts the trace ID, span ID, and sampling decision into every Log4j log event. This commit includes other changes to make the tracing data available in the logs, in a format that can be interpreted by the Stackdriver Logging agent: - Convert all adservice log statements from java.util.logging to Log4j. - Specify a JSON format for Log4j output. This is related to issue #47. - Add the trace ID, span ID, and sampling decision to the JSON format. Trace ID and span ID use special keys that the Stackdriver Logging agent uses to populate the tracing data fields in the LogEntry uploaded to Stackdriver (https://cloud.google.com/logging/docs/agent/configuration#special_fields_in_structured_payloads). However, Stackdriver won't be able to link the traces and log entries until fluent-plugin-google-cloud can automatically format the trace ID with the format expected by Stackdriver (GoogleCloudPlatform/fluent-plugin-google-cloud#239, GoogleCloudPlatform/fluent-plugin-google-cloud#260). This commit also upgrades OpenCensus to 0.16.1 in order to use opencensus-contrib-log-correlation-log4j2.
No description provided.