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

feat: Add support for partialSuccess #908

Merged
merged 2 commits into from
Oct 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .readme-partials.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ custom_content: |
<!-- Optional: add custom labels to log entries using LoggingEnhancer classes -->
<enhancer>com.example.enhancers.TestLoggingEnhancer</enhancer>
<enhancer>com.example.enhancers.AnotherEnhancer</enhancer>

<!-- Optional: specifies if a batch's valid entries should be written even if some other entry failed due to an error. Defaults to true
See [partial_success](https://cloud.google.com/logging/docs/reference/v2/rest/v2/entries/write#body.request_body.FIELDS.partial_success) for more info -->
<partialSuccess>true</partialSuccess>
</appender>

<root level="info">
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ See [Logback filters](https://logback.qos.ch/manual/filters.html#thresholdFilter
<!-- Optional: add custom labels to log entries using LoggingEnhancer classes -->
<enhancer>com.example.enhancers.TestLoggingEnhancer</enhancer>
<enhancer>com.example.enhancers.AnotherEnhancer</enhancer>

<!-- Optional: specifies if a batch's valid entries should be written even if some other entry failed due to an error. Defaults to true
See [partial_success](https://cloud.google.com/logging/docs/reference/v2/rest/v2/entries/write#body.request_body.FIELDS.partial_success) for more info -->
<partialSuccess>true</partialSuccess>
</appender>

<root level="info">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@
* &lt;!-- Optional: add custom labels to log entries using {@link LoggingEnhancer} classes --&gt;
* &lt;enhancer&gt;com.example.enhancers.TestLoggingEnhancer&lt/enhancer&gt;
* &lt;enhancer&gt;com.example.enhancers.AnotherEnhancer&lt/enhancer&gt;
*
* &lt;!-- Optional: specifies if a batch's valid entries should be written even if some other entry failed due to an error. Defaults to {@code true} --&gt;
* &lt;partialSuccess&gt;true&lt;/partialSuccess&gt;
* &lt;/appender&gt;
* </pre>
*/
Expand Down Expand Up @@ -118,6 +121,7 @@ public class LoggingAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
private String logDestinationProjectId;
private boolean autoPopulateMetadata = true;
private boolean redirectToStdout = false;
private boolean partialSuccess = true;
private Synchronicity writeSyncFlag = Synchronicity.ASYNC;
private final Set<String> enhancerClassNames = new HashSet<>();
private final Set<String> loggingEventEnhancerClassNames = new HashSet<>();
Expand Down Expand Up @@ -214,6 +218,18 @@ public void setRedirectToStdout(boolean flag) {
redirectToStdout = flag;
}

/**
* Sets the flag indicating if a batch's valid entries should be written even if some other entry
* failed due to an error.
*
* <p>Default to {@code true}.
*
* @param flag the partialSuccess flag.
*/
public void setPartialSuccess(boolean flag) {
partialSuccess = flag;
}

/** Add extra labels using classes that implement {@link LoggingEnhancer}. */
public void addEnhancer(String enhancerClassName) {
this.enhancerClassNames.add(enhancerClassName);
Expand Down Expand Up @@ -298,7 +314,9 @@ public synchronized void start() {

defaultWriteOptions =
new WriteOption[] {
WriteOption.logName(getLogName()), WriteOption.resource(monitoredResource)
WriteOption.logName(getLogName()),
WriteOption.resource(monitoredResource),
WriteOption.partialSuccess(partialSuccess)
};
Level flushLevel = getFlushLevel();
if (flushLevel != Level.OFF) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,19 @@ public void setUp() {
new ImmutableMap.Builder<String, String>()
.put("project_id", PROJECT_ID)
.build())
.build())
.build()),
WriteOption.partialSuccess(true),
};

@Test
public void testFlushLevelConfigUpdatesLoggingFlushSeverity() {
logging.setFlushSeverity(Severity.WARNING);
Capture<Iterable<LogEntry>> capturedArgument = Capture.newInstance();
logging.write(
capture(capturedArgument), anyObject(WriteOption.class), anyObject(WriteOption.class));
capture(capturedArgument),
anyObject(WriteOption.class),
anyObject(WriteOption.class),
anyObject(WriteOption.class));
replay(logging);
Timestamp timestamp = Timestamp.ofTimeSecondsAndNanos(100000, 0);
LoggingEvent loggingEvent = createLoggingEvent(Level.WARN, timestamp.getSeconds());
Expand All @@ -194,7 +198,10 @@ public void testFilterLogsOnlyLogsAtOrAboveLogLevel() {
logging.setFlushSeverity(Severity.ERROR);
Capture<Iterable<LogEntry>> capturedArgument = Capture.newInstance();
logging.write(
capture(capturedArgument), anyObject(WriteOption.class), anyObject(WriteOption.class));
capture(capturedArgument),
anyObject(WriteOption.class),
anyObject(WriteOption.class),
anyObject(WriteOption.class));
expectLastCall().once();
replay(logging);
Timestamp timestamp = Timestamp.ofTimeSecondsAndNanos(100000, 0);
Expand All @@ -215,12 +222,16 @@ public void testFilterLogsOnlyLogsAtOrAboveLogLevel() {
}

@Test
public void testDefaultWriteOptionsHasExpectedDefaults() {
public void testPartialSuccessOverrideHasExpectedValue() {
logging.setFlushSeverity(Severity.ERROR);
Capture<WriteOption> logNameArg = Capture.newInstance();
Capture<WriteOption> resourceArg = Capture.newInstance();
Capture<WriteOption> partialSuccessArg = Capture.newInstance();
logging.write(
EasyMock.<Iterable<LogEntry>>anyObject(), capture(logNameArg), capture(resourceArg));
EasyMock.<Iterable<LogEntry>>anyObject(),
capture(logNameArg),
capture(resourceArg),
capture(partialSuccessArg));
expectLastCall().once();
replay(logging);
loggingAppender.start();
Expand All @@ -231,14 +242,37 @@ public void testDefaultWriteOptionsHasExpectedDefaults() {
assertThat(logNameArg.getValue()).isEqualTo(defaultWriteOptions[0]);
// TODO(chingor): Fix this test to work on GCE and locally
// assertThat(resourceArg.getValue()).isEqualTo(defaultWriteOptions[1]);
assertThat(partialSuccessArg.getValue()).isEqualTo(defaultWriteOptions[2]);
}

@Test
public void testDefaultWriteOptionsHasExpectedDefaults() {
logging.setFlushSeverity(Severity.ERROR);
Capture<WriteOption> partialSuccessArg = Capture.newInstance();
logging.write(
EasyMock.<Iterable<LogEntry>>anyObject(),
anyObject(WriteOption.class),
anyObject(WriteOption.class),
capture(partialSuccessArg));
expectLastCall().once();
replay(logging);
loggingAppender.setPartialSuccess(false);
loggingAppender.start();
Timestamp timestamp = Timestamp.ofTimeSecondsAndNanos(100000, 0);
LoggingEvent loggingEvent = createLoggingEvent(Level.ERROR, timestamp.getSeconds());
loggingAppender.doAppend(loggingEvent);
assertThat(partialSuccessArg.getValue()).isEqualTo(WriteOption.partialSuccess(false));
}

@Test
public void testMdcValuesAreConvertedToLabels() {
logging.setFlushSeverity(Severity.ERROR);
Capture<Iterable<LogEntry>> capturedArgument = Capture.newInstance();
logging.write(
capture(capturedArgument), anyObject(WriteOption.class), anyObject(WriteOption.class));
capture(capturedArgument),
anyObject(WriteOption.class),
anyObject(WriteOption.class),
anyObject(WriteOption.class));
expectLastCall().once();
replay(logging);
Timestamp timestamp = Timestamp.ofTimeSecondsAndNanos(100000, 0);
Expand Down Expand Up @@ -294,7 +328,10 @@ public void testMdcValuesAreConvertedToLabelsWithPassingNullValues() {
logging.setFlushSeverity(Severity.ERROR);
Capture<Iterable<LogEntry>> capturedArgument = Capture.newInstance();
logging.write(
capture(capturedArgument), anyObject(WriteOption.class), anyObject(WriteOption.class));
capture(capturedArgument),
anyObject(WriteOption.class),
anyObject(WriteOption.class),
anyObject(WriteOption.class));
expectLastCall().once();
replay(logging);
Timestamp timestamp = Timestamp.ofTimeSecondsAndNanos(100000, 0);
Expand All @@ -317,7 +354,10 @@ public void testAddCustomLoggingEventEnhancers() {
logging.setFlushSeverity(Severity.ERROR);
Capture<Iterable<LogEntry>> capturedArgument = Capture.newInstance();
logging.write(
capture(capturedArgument), anyObject(WriteOption.class), anyObject(WriteOption.class));
capture(capturedArgument),
anyObject(WriteOption.class),
anyObject(WriteOption.class),
anyObject(WriteOption.class));
expectLastCall().once();
replay(logging);
Timestamp timestamp = Timestamp.ofTimeSecondsAndNanos(100000, 0);
Expand All @@ -338,7 +378,10 @@ public void testAddCustomLoggingEnhancer() {
logging.setFlushSeverity(Severity.ERROR);
Capture<Iterable<LogEntry>> capturedArgument = Capture.newInstance();
logging.write(
capture(capturedArgument), anyObject(WriteOption.class), anyObject(WriteOption.class));
capture(capturedArgument),
anyObject(WriteOption.class),
anyObject(WriteOption.class),
anyObject(WriteOption.class));
expectLastCall().once();
replay(logging);
loggingAppender.addEnhancer(CustomLoggingEnhancer.class.getName());
Expand All @@ -359,6 +402,7 @@ public void testFlush() {
logging.write(
EasyMock.<Iterable<LogEntry>>anyObject(),
anyObject(WriteOption.class),
anyObject(WriteOption.class),
anyObject(WriteOption.class));
expectLastCall().times(2);
logging.flush();
Expand Down Expand Up @@ -395,6 +439,7 @@ public void testAutoPopulationEnabled() {
logging.write(
EasyMock.<Iterable<LogEntry>>anyObject(),
anyObject(WriteOption.class),
anyObject(WriteOption.class),
anyObject(WriteOption.class));
expectLastCall().once();
replay(logging);
Expand Down Expand Up @@ -460,7 +505,10 @@ public void testFDiagnosticInfoAdded() {
Capture<Iterable<LogEntry>> capturedArgument = Capture.newInstance();
logging.setFlushSeverity(Severity.ERROR);
logging.write(
capture(capturedArgument), anyObject(WriteOption.class), anyObject(WriteOption.class));
capture(capturedArgument),
anyObject(WriteOption.class),
anyObject(WriteOption.class),
anyObject(WriteOption.class));
replay(logging);
LoggingEvent loggingEvent =
createLoggingEvent(Level.ERROR, Timestamp.ofTimeSecondsAndNanos(100000, 0).getSeconds());
Expand Down Expand Up @@ -502,7 +550,10 @@ public void testFDiagnosticInfoNotAdded() {
logging.setFlushSeverity(Severity.ERROR);
Capture<Iterable<LogEntry>> capturedArgument = Capture.newInstance();
logging.write(
capture(capturedArgument), anyObject(WriteOption.class), anyObject(WriteOption.class));
capture(capturedArgument),
anyObject(WriteOption.class),
anyObject(WriteOption.class),
anyObject(WriteOption.class));
replay(logging);
LoggingEvent loggingEvent =
createLoggingEvent(Level.WARN, Timestamp.ofTimeSecondsAndNanos(100000, 0).getSeconds());
Expand Down