services: allow binlog to blacklist methods (#4523)

The spec says users can specify a blacklist a method from binlogs by
saying "-package.service/method".
This commit is contained in:
zpencer 2018-06-04 14:11:55 -07:00 committed by GitHub
parent a0794d5a68
commit 29dba1e89f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 0 deletions

View File

@ -59,7 +59,9 @@ import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -364,6 +366,7 @@ final class BinlogHelper {
private final BinlogHelper globalLog; private final BinlogHelper globalLog;
private final Map<String, BinlogHelper> perServiceLogs; private final Map<String, BinlogHelper> perServiceLogs;
private final Map<String, BinlogHelper> perMethodLogs; private final Map<String, BinlogHelper> perMethodLogs;
private final Set<String> blacklistedMethods;
/** /**
* Accepts a string in the format specified by the binary log spec. * Accepts a string in the format specified by the binary log spec.
@ -374,6 +377,7 @@ final class BinlogHelper {
BinlogHelper globalLog = null; BinlogHelper globalLog = null;
Map<String, BinlogHelper> perServiceLogs = new HashMap<String, BinlogHelper>(); Map<String, BinlogHelper> perServiceLogs = new HashMap<String, BinlogHelper>();
Map<String, BinlogHelper> perMethodLogs = new HashMap<String, BinlogHelper>(); Map<String, BinlogHelper> perMethodLogs = new HashMap<String, BinlogHelper>();
Set<String> blacklistedMethods = new HashSet<String>();
if (configurationString != null && configurationString.length() > 0) { if (configurationString != null && configurationString.length() > 0) {
for (String configuration : Splitter.on(',').split(configurationString)) { for (String configuration : Splitter.on(',').split(configurationString)) {
Matcher configMatcher = configRe.matcher(configuration); Matcher configMatcher = configRe.matcher(configuration);
@ -404,6 +408,14 @@ final class BinlogHelper {
Level.INFO, Level.INFO,
"Service binlog: service={0} config={1}", "Service binlog: service={0} config={1}",
new Object[] {service, binlogOptionStr}); new Object[] {service, binlogOptionStr});
} else if (methodOrSvc.startsWith("-")) {
String blacklistedMethod = methodOrSvc.substring(1);
if (blacklistedMethod.length() == 0) {
continue;
}
if (!blacklistedMethods.add(blacklistedMethod)) {
logger.log(Level.SEVERE, "Ignoring duplicate entry: {0}", configuration);
}
} else { } else {
// assume fully qualified method name // assume fully qualified method name
if (perMethodLogs.containsKey(methodOrSvc)) { if (perMethodLogs.containsKey(methodOrSvc)) {
@ -421,6 +433,7 @@ final class BinlogHelper {
this.globalLog = globalLog; this.globalLog = globalLog;
this.perServiceLogs = Collections.unmodifiableMap(perServiceLogs); this.perServiceLogs = Collections.unmodifiableMap(perServiceLogs);
this.perMethodLogs = Collections.unmodifiableMap(perMethodLogs); this.perMethodLogs = Collections.unmodifiableMap(perMethodLogs);
this.blacklistedMethods = Collections.unmodifiableSet(blacklistedMethods);
} }
/** /**
@ -428,6 +441,9 @@ final class BinlogHelper {
*/ */
@Override @Override
public BinlogHelper getLog(String fullMethodName) { public BinlogHelper getLog(String fullMethodName) {
if (blacklistedMethods.contains(fullMethodName)) {
return null;
}
BinlogHelper methodLog = perMethodLogs.get(fullMethodName); BinlogHelper methodLog = perMethodLogs.get(fullMethodName);
if (methodLog != null) { if (methodLog != null) {
return methodLog; return methodLog;

View File

@ -20,6 +20,7 @@ import static io.grpc.services.BinaryLogProvider.BYTEARRAY_MARSHALLER;
import static io.grpc.services.BinlogHelper.DUMMY_SOCKET; import static io.grpc.services.BinlogHelper.DUMMY_SOCKET;
import static io.grpc.services.BinlogHelper.getPeerSocket; import static io.grpc.services.BinlogHelper.getPeerSocket;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame; import static org.junit.Assert.assertSame;
import static org.mockito.Matchers.eq; import static org.mockito.Matchers.eq;
@ -264,6 +265,17 @@ public final class BinlogHelperTest {
assertNull(makeLog(configStr, "package.service2/absent")); assertNull(makeLog(configStr, "package.service2/absent"));
} }
@Test
public void configBinLog_blacklist() {
assertNull(makeLog("*,-p.s/blacklisted", "p.s/blacklisted"));
assertNull(makeLog("-p.s/blacklisted,*", "p.s/blacklisted"));
assertNotNull(makeLog("-p.s/method,*", "p.s/allowed"));
assertNull(makeLog("p.s/*,-p.s/blacklisted", "p.s/blacklisted"));
assertNull(makeLog("-p.s/blacklisted,p.s/*", "p.s/blacklisted"));
assertNotNull(makeLog("-p.s/blacklisted,p.s/*", "p.s/allowed"));
}
@Test @Test
public void configBinLog_ignoreDuplicates_global() throws Exception { public void configBinLog_ignoreDuplicates_global() throws Exception {
String configStr = "*{h},p.s/m,*{h:256}"; String configStr = "*{h},p.s/m,*{h:256}";