99import com .google .common .collect .ImmutableMap ;
1010import com .google .common .collect .Maps ;
1111import com .google .common .io .Closer ;
12+ import com .google .protobuf .InvalidProtocolBufferException ;
13+ import com .google .protobuf .util .JsonFormat ;
1214import com .spotify .confidence .ConfidenceUtils .FlagPath ;
1315import com .spotify .confidence .Exceptions .IllegalValuePath ;
1416import com .spotify .confidence .Exceptions .IllegalValueType ;
1517import com .spotify .confidence .Exceptions .IncompatibleValueType ;
1618import com .spotify .confidence .Exceptions .ValueNotFound ;
1719import com .spotify .confidence .shaded .flags .resolver .v1 .ResolveFlagsResponse ;
1820import com .spotify .confidence .shaded .flags .resolver .v1 .ResolvedFlag ;
21+ import com .spotify .internal .v1 .ResolveTesterLogging ;
1922import io .grpc .ManagedChannel ;
2023import io .grpc .ManagedChannelBuilder ;
2124import io .grpc .StatusRuntimeException ;
2225import java .io .Closeable ;
2326import java .io .IOException ;
24- import java .net .URLEncoder ;
25- import java .nio .charset .StandardCharsets ;
2627import java .time .Duration ;
2728import java .time .Instant ;
29+ import java .util .Base64 ;
2830import java .util .Map ;
2931import java .util .Optional ;
3032import java .util .Set ;
@@ -41,6 +43,7 @@ public abstract class Confidence implements FlagEvaluator, EventSender, Closeabl
4143
4244 protected Map <String , ConfidenceValue > context = Maps .newHashMap ();
4345 private static final Logger log = org .slf4j .LoggerFactory .getLogger (Confidence .class );
46+ private static final JsonFormat .Printer jsonPrinter = JsonFormat .printer ();
4447
4548 protected Confidence () {
4649 // Protected constructor to allow subclassing
@@ -137,15 +140,7 @@ public <T> FlagEvaluation<T> getEvaluation(String key, T defaultValue) {
137140 }
138141
139142 final ResolvedFlag resolvedFlag = response .getResolvedFlags (0 );
140- final String clientKey = client ().clientSecret ;
141- final String flag = resolvedFlag .getFlag ();
142- final String context = URLEncoder .encode (getContext ().toString (), StandardCharsets .UTF_8 );
143- final String logMessage =
144- String .format (
145- "See resolves for '%s' in Confidence: "
146- + "https://app.confidence.spotify.com/flags/resolver-test?client-key=%s&flag=flags/%s&context=%s" ,
147- flag , clientKey , flag , context );
148- log .debug (logMessage );
143+ logResolveTesterHint (resolvedFlag );
149144 if (!requestFlagName .equals (resolvedFlag .getFlag ())) {
150145 final String errorMessage =
151146 String .format (
@@ -201,6 +196,30 @@ public <T> FlagEvaluation<T> getEvaluation(String key, T defaultValue) {
201196 }
202197 }
203198
199+ @ VisibleForTesting
200+ public void logResolveTesterHint (ResolvedFlag resolvedFlag ) {
201+ final String clientKey = client ().clientSecret ;
202+ final String flag = resolvedFlag .getFlag ();
203+ try {
204+ final ResolveTesterLogging resolveTesterLogging =
205+ ResolveTesterLogging .newBuilder ()
206+ .setClientKey (clientKey )
207+ .setFlag (flag )
208+ .setContext (getContext ().toProto ())
209+ .build ();
210+ final String base64 =
211+ Base64 .getEncoder ().encodeToString (jsonPrinter .print (resolveTesterLogging ).getBytes ());
212+ final String logMessage =
213+ String .format (
214+ "Check your flag evaluation for '%s' by copy pasting the payload to the Resolve tester '%s'" ,
215+ flag , base64 );
216+ log .debug (logMessage );
217+ } catch (InvalidProtocolBufferException e ) {
218+ log .warn ("Failed to produce correct resolve tester content" , e );
219+ // warn and ignore is enough
220+ }
221+ }
222+
204223 CompletableFuture <ResolveFlagsResponse > resolveFlags (String flagName ) {
205224 return client ().resolveFlags (flagName , getContext ());
206225 }
0 commit comments