This repository has been archived by the owner on Dec 23, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 201
Start adding log correlation for Stackdriver Logging. #1212
Merged
sebright
merged 10 commits into
census-instrumentation:master
from
sebright:stackdriver-log-correlation
Jun 12, 2018
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
d34e4b2
Start adding log correlation for Stackdriver Logging.
sebright 9a5deb0
Mention that the log correlation feature is experimental in the Javadoc.
sebright 36ad77a
Remove TODO about ignoring blank spans.
sebright 9d4b3e5
Upgrade google-cloud-logging and set new LogEntry spanId field.
sebright 4f801e3
Update TODO about caching the project ID.
sebright 9fbd97e
Add a TODO about overriding the project ID.
sebright 941361b
Temporarily remove opencensus-exporter-trace-logging from released ar…
sebright 73c0787
Remove opencensus-contrib-log-correlation-stackdriver-demo.
sebright 23faa1e
Add a TODO for configuring the LoggingEnhancer with Java properties.
sebright 6ce8f89
Add a link to the Stackdriver LoggingEnhancer.
sebright File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# OpenCensus Stackdriver Log Correlation | ||
|
||
This subproject is currently experimental. It provides a Stackdriver Logging | ||
[LoggingEnhancer](http://googlecloudplatform.github.io/google-cloud-java/google-cloud-clients/apidocs/com/google/cloud/logging/LoggingEnhancer.html) | ||
that automatically adds tracing data to log entries. The LoggingEnhancer adds the trace ID, which | ||
allows Stackdriver to display log entries associated with each trace or filter logs based on trace | ||
ID. It currently also adds the span ID and sampling decision. | ||
|
||
TODO(sebright): Add a demo to https://github.com/census-ecosystem/opencensus-experiments and link to | ||
it. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
description = 'OpenCensus Stackdriver Log Correlation' | ||
|
||
apply plugin: 'java' | ||
|
||
dependencies { | ||
compile project(':opencensus-api'), | ||
libraries.google_cloud_logging | ||
|
||
signature "org.codehaus.mojo.signature:java16:+@signature" | ||
} |
64 changes: 64 additions & 0 deletions
64
...java/io/opencensus/contrib/logcorrelation/stackdriver/OpenCensusTraceLoggingEnhancer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* | ||
* Copyright 2018, OpenCensus Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.opencensus.contrib.logcorrelation.stackdriver; | ||
|
||
import com.google.cloud.ServiceOptions; | ||
import com.google.cloud.logging.LogEntry; | ||
import com.google.cloud.logging.LoggingEnhancer; | ||
import io.opencensus.common.ExperimentalApi; | ||
import io.opencensus.trace.SpanContext; | ||
import io.opencensus.trace.TraceId; | ||
import io.opencensus.trace.Tracer; | ||
import io.opencensus.trace.Tracing; | ||
|
||
/** | ||
* Stackdriver {@link LoggingEnhancer} that adds OpenCensus tracing data to log entries. | ||
* | ||
* <p>This feature is currently experimental. | ||
*/ | ||
|
||
// TODO(sebright): Allow configuring the LoggingEnhancer with Java properties. One property should | ||
// control the types of spans to correlate, with these three choices: | ||
// - off | ||
// - only add tracing data for sampled spans | ||
// - add tracing data for all spans | ||
@ExperimentalApi | ||
public final class OpenCensusTraceLoggingEnhancer implements LoggingEnhancer { | ||
private static final String SAMPLED_KEY = "sampled"; | ||
|
||
private static final Tracer tracer = Tracing.getTracer(); | ||
|
||
/** Constructor to be called by Stackdriver logging. */ | ||
public OpenCensusTraceLoggingEnhancer() {} | ||
|
||
@Override | ||
public void enhanceLogEntry(LogEntry.Builder builder) { | ||
SpanContext span = tracer.getCurrentSpan().getContext(); | ||
builder.setTrace(formatTraceId(span.getTraceId())); | ||
builder.setSpanId(span.getSpanId().toLowerBase16()); | ||
|
||
// TODO(sebright): Find the correct way to add the sampling decision. | ||
builder.addLabel(SAMPLED_KEY, Boolean.toString(span.getTraceOptions().isSampled())); | ||
} | ||
|
||
private static String formatTraceId(TraceId traceId) { | ||
// TODO(sebright): Cache the project ID. | ||
// TODO(sebright): Add a way to override the project ID in the logging configuration. | ||
String projectId = ServiceOptions.getDefaultProjectId(); | ||
return "projects/" + projectId + "/traces/" + traceId.toLowerBase16(); | ||
} | ||
} |
133 changes: 133 additions & 0 deletions
133
.../io/opencensus/contrib/logcorrelation/stackdriver/OpenCensusTraceLoggingEnhancerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
/* | ||
* Copyright 2018, OpenCensus Authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.opencensus.contrib.logcorrelation.stackdriver; | ||
|
||
import static com.google.common.truth.Truth.assertThat; | ||
|
||
import com.google.cloud.logging.LogEntry; | ||
import io.opencensus.common.Scope; | ||
import io.opencensus.trace.Annotation; | ||
import io.opencensus.trace.AttributeValue; | ||
import io.opencensus.trace.BlankSpan; | ||
import io.opencensus.trace.EndSpanOptions; | ||
import io.opencensus.trace.Link; | ||
import io.opencensus.trace.Span; | ||
import io.opencensus.trace.SpanContext; | ||
import io.opencensus.trace.SpanId; | ||
import io.opencensus.trace.TraceId; | ||
import io.opencensus.trace.TraceOptions; | ||
import io.opencensus.trace.Tracer; | ||
import io.opencensus.trace.Tracing; | ||
import java.util.EnumSet; | ||
import java.util.Map; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
import org.junit.runners.JUnit4; | ||
|
||
/** Test for {@link OpenCensusTraceLoggingEnhancer}. */ | ||
// TODO(sebright): Find a way to test that OpenCensusTraceLoggingEnhancer is called from Stackdriver | ||
// logging. See | ||
// https://github.com/GoogleCloudPlatform/google-cloud-java/blob/master/TESTING.md#testing-code-that-uses-logging. | ||
@RunWith(JUnit4.class) | ||
public class OpenCensusTraceLoggingEnhancerTest { | ||
private static final String GOOGLE_CLOUD_PROJECT = "GOOGLE_CLOUD_PROJECT"; | ||
|
||
private static Tracer tracer = Tracing.getTracer(); | ||
|
||
@Test | ||
public void enhanceLogEntry_Sampled() { | ||
String projectId = "my-test-project-1"; | ||
String traceId = "4c9874d0b41224cce77ff74ee10f5ee6"; | ||
String spanId = "592ae363e92cb3dd"; | ||
boolean isSampled = true; | ||
testLoggingEnhancer(projectId, traceId, spanId, isSampled); | ||
} | ||
|
||
@Test | ||
public void enhanceLogEntry_NotSampled() { | ||
String projectId = "my-test-project-2"; | ||
String traceId = "7f4703d9bb02f4f2e67fb840103cdd34"; | ||
String spanId = "2d7d95a555557434"; | ||
boolean isSampled = false; | ||
testLoggingEnhancer(projectId, traceId, spanId, isSampled); | ||
} | ||
|
||
private static void testLoggingEnhancer( | ||
String projectId, String traceId, String spanId, boolean isSampled) { | ||
System.setProperty(GOOGLE_CLOUD_PROJECT, projectId); | ||
try { | ||
Scope scope = | ||
tracer.withSpan( | ||
new TestSpan( | ||
SpanContext.create( | ||
TraceId.fromLowerBase16(traceId), | ||
SpanId.fromLowerBase16(spanId), | ||
TraceOptions.builder().setIsSampled(isSampled).build()))); | ||
try { | ||
LogEntry.Builder builder = LogEntry.newBuilder(null); | ||
new OpenCensusTraceLoggingEnhancer().enhanceLogEntry(builder); | ||
LogEntry logEntry = builder.build(); | ||
assertThat(logEntry.getLabels().get("sampled")).isEqualTo(isSampled ? "true" : "false"); | ||
assertThat(logEntry.getTrace()).isEqualTo("projects/" + projectId + "/traces/" + traceId); | ||
assertThat(logEntry.getSpanId()).isEqualTo(spanId); | ||
} finally { | ||
scope.close(); | ||
} | ||
} finally { | ||
System.clearProperty(GOOGLE_CLOUD_PROJECT); | ||
} | ||
} | ||
|
||
@Test | ||
public void enhanceLogEntry_BlankSpan() { | ||
System.setProperty(GOOGLE_CLOUD_PROJECT, "my-test-project-3"); | ||
try { | ||
Scope scope = tracer.withSpan(BlankSpan.INSTANCE); | ||
try { | ||
LogEntry.Builder builder = LogEntry.newBuilder(null); | ||
new OpenCensusTraceLoggingEnhancer().enhanceLogEntry(builder); | ||
LogEntry logEntry = builder.build(); | ||
assertThat(logEntry.getLabels().get("sampled")).isEqualTo("false"); | ||
assertThat(logEntry.getTrace()) | ||
.isEqualTo("projects/my-test-project-3/traces/00000000000000000000000000000000"); | ||
assertThat(logEntry.getSpanId()).isEqualTo("0000000000000000"); | ||
} finally { | ||
scope.close(); | ||
} | ||
} finally { | ||
System.clearProperty(GOOGLE_CLOUD_PROJECT); | ||
} | ||
} | ||
|
||
private static final class TestSpan extends Span { | ||
TestSpan(SpanContext context) { | ||
super(context, EnumSet.of(Options.RECORD_EVENTS)); | ||
} | ||
|
||
@Override | ||
public void end(EndSpanOptions options) {} | ||
|
||
@Override | ||
public void addLink(Link link) {} | ||
|
||
@Override | ||
public void addAnnotation(Annotation annotation) {} | ||
|
||
@Override | ||
public void addAnnotation(String description, Map<String, AttributeValue> attributes) {} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Is there any possibility to access the args of a log message within an enhancer and take the span from there (if present)? This would allow people who do not use scoped spans to use this as well.
In Scala we can't use scoped spans in most of the cases since the Future based code is executed on arbitrary threads.
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.
@Sebruck Thanks for the feedback!
I don't see any getters on the builder, so I think that would require building the LogEntry within enhanceLogEntry to call the LogEntry's getters. How would the span be set on the log message before it is passed to enhanceLogEntry?
What library runs the Futures? The opencensus-java agent (https://github.com/census-instrumentation/opencensus-java/tree/master/contrib/agent) propagates the context to threads or executors, though I don't know whether it could be extended to work with other libraries.