Tracklytics implements AspectListener { private void log(Event event) { if (logger == null) return; @SuppressWarnings("StringBufferReplaceableByString") StringBuilder builder = new StringBuilder() .append(event.name) .append("-> ") .append(event.attributes.toString()) .append(", super attrs: ") .append(superAttributes.toString()) .append(", filters: ") .append(Arrays.toString(event.filters)); logger.log(builder.toString()); } private  Tracklytics(EventSubscriber eventSubscriber); static Tracklytics init(EventSubscriber eventSubscriber); void trackEvent(String eventName); void trackEvent(String eventName, Map<String, Object> attributes); void setEventLogListener(EventLogListener logger); void addSuperAttribute(String key, Object value); void removeSuperAttribute(String key); @Override void onAspectEventTriggered(TrackEvent trackEvent, Map<String, Object> attributes); @Override void onAspectSuperAttributeAdded(String key, Object value); @Override void onAspectSuperAttributeRemoved(String key);  }
@Test public void log() throws Throwable { EventLogListener logger = mock(EventLogListener.class); tracklytics.setEventLogListener(logger); Map<String, Object> attributes = new HashMap<>(); attributes.put("key", "value"); tracklytics.trackEvent("event", attributes); verify(logger).log("event-> {key=value}, super attrs: {}, filters: null"); }