Skip to content

Commit

Permalink
Add a with(MetadataKey<Boolean>) method to set a boolean metadata f…
Browse files Browse the repository at this point in the history
…lag.

I've been meaning to look at this for a while and there are hundreds of uses of just this key which would be improved visually:

  `logger.atWarning().with(PERSISTENT, true).log("...");`
would become:
  `logger.atWarning().with(PERSISTENT).log("...");`

RELNOTES=Added `with(MetadataKey<Boolean>)` method for setting metadata "flags".

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=310508434
  • Loading branch information
hagbard authored and cpovirk committed May 26, 2020
1 parent e0067d3 commit 2f1243e
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 0 deletions.
5 changes: 5 additions & 0 deletions api/src/main/java/com/google/common/flogger/LogContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,11 @@ public final <T> API with(MetadataKey<T> key, @NullableDecl T value) {
return api();
}

@Override
public final <T> API with(MetadataKey<Boolean> key) {
return with(key, Boolean.TRUE);
}

@Override
public final API withCause(Throwable cause) {
if (cause != null) {
Expand Down
28 changes: 28 additions & 0 deletions api/src/main/java/com/google/common/flogger/LoggingApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,27 @@ public interface LoggingApi<API extends LoggingApi<API>> {
*/
<T> API with(MetadataKey<T> key, @NullableDecl T value);

/**
* Sets a boolean metadata key constant to {@code true} for this log statement in a structured way
* that is accessible to logger backends.
*
* <p>This method is not a replacement for general parameter passing in the {@link #log()} method
* and should be reserved for keys/values with specific semantics. Examples include:
*
* <ul>
* <li>Keys that are recognised by specific logger backends (typically to control logging
* behaviour in some way).
* <li>Key value pairs which are explicitly extracted from logs by tools.
* </ul>
*
* <p>This method is just an alias for {@code with(key, true)} to improve readability.
*
* @param key the boolean metadata key (expected to be a static constant)
* @throws NullPointerException if the given key is null
* @see MetadataKey
*/
<T> API with(MetadataKey<Boolean> key);

/**
* Sets the log site for the current log statement. Explicit log site injection is very rarely
* necessary, since either the log site is injected automatically, or it is determined at runtime
Expand Down Expand Up @@ -651,6 +672,13 @@ public final <T> API with(MetadataKey<T> key, @NullableDecl T value) {
return noOp();
}

@Override
public final <T> API with(MetadataKey<Boolean> key) {
// Do this inline rather than calling with(key, true) to keep no-op minimal.
checkNotNull(key, "metadata key");
return noOp();
}

@Override
public final API withCause(@NullableDecl Throwable cause) {
return noOp();
Expand Down
22 changes: 22 additions & 0 deletions api/src/test/java/com/google/common/flogger/LogContextTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ public class LogContextTest {
private static final char CHAR_ARG = 'X';
private static final Object OBJECT_ARG = new Object();

private static final MetadataKey<String> REPEATED_KEY = MetadataKey.repeated("str", String.class);
private static final MetadataKey<Boolean> FLAG_KEY = MetadataKey.repeated("flag", Boolean.class);

@Test
public void testIsEnabled() {
FakeLoggerBackend backend = new FakeLoggerBackend();
Expand Down Expand Up @@ -143,6 +146,25 @@ public void testMultipleMetadata() {
backend.assertLogged(0).metadata().containsUniqueEntry(Key.LOG_CAUSE, cause);
}

@Test
public void testMetadataKeys() {
FakeLoggerBackend backend = new FakeLoggerBackend();
FluentLogger logger = new FluentLogger(backend);

logger.atInfo().with(REPEATED_KEY, "foo").with(REPEATED_KEY, "bar").log("Several values");
logger.atInfo().with(FLAG_KEY).log("Set Flag");
logger.atInfo().with(FLAG_KEY, false).log("No flag");
logger.atInfo().with(REPEATED_KEY, "foo").with(FLAG_KEY).with(REPEATED_KEY, "bar").log("...");

assertThat(backend.getLoggedCount()).isEqualTo(4);
backend.assertLogged(0).metadata().containsEntries(REPEATED_KEY, "foo", "bar");
backend.assertLogged(1).metadata().containsUniqueEntry(FLAG_KEY, true);
backend.assertLogged(2).metadata().containsUniqueEntry(FLAG_KEY, false);
// Just check nothing weird happens when the metadata is interleaved in the log statement.
backend.assertLogged(3).metadata().containsEntries(REPEATED_KEY, "foo", "bar");
backend.assertLogged(3).metadata().containsUniqueEntry(FLAG_KEY, true);
}

@Test
public void testAtMostEvery() {
FakeLoggerBackend backend = new FakeLoggerBackend();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@ private List<Object> valueList() {
return values;
}

private <T> List<T> valuesOf(MetadataKey<T> key) {
Metadata metadata = actual;
List<T> values = new ArrayList<>();
for (int n = 0; n < metadata.size(); n++) {
if (metadata.getKey(n).equals(key)) {
values.add(key.cast(metadata.getValue(n)));
}
}
return values;
}

public void hasSize(int expectedSize) {
checkArgument(expectedSize >= 0, "expectedSize(%s) must be >= 0", expectedSize);
check("size()").that(actual.size()).isEqualTo(expectedSize);
Expand All @@ -88,6 +99,11 @@ public <T> void containsUniqueEntry(MetadataKey<T> key, T value) {
}
}

public <T> void containsEntries(MetadataKey<T> key, T... values) {
checkNotNull(key, "key must not be null");
check("<values of>(%s)", key).that(valuesOf(key)).containsExactlyElementsIn(values).inOrder();
}

public IterableSubject keys() {
return check("keys()").that(keyList());
}
Expand Down

0 comments on commit 2f1243e

Please sign in to comment.