package org.sef4j.callstack.handlers; import java.util.Iterator; import java.util.Map; import org.sef4j.callstack.CallStackElt; import org.sef4j.callstack.CallStackPushPopHandler; import org.sef4j.callstack.event.StackEvent.PopStackEvent; import org.sef4j.callstack.event.StackEvent.ProgressStepStackEvent; import org.sef4j.callstack.event.StackEvent.PushStackEvent; import org.sef4j.callstack.stats.ThreadTimeUtils; import org.slf4j.Logger; /** * adapter CallStackHandler push()/pop() -> Slf4j * * cf similar "copy&paste code" Slf4jLoggerAdapterStackEventListener * (CallStackHandler -> StackEventListener -> Slf4j) */ public class Slf4jLoggerAdapterCallStackHandler extends CallStackPushPopHandler { private Logger slf4jLogger; // ------------------------------------------------------------------------ public Slf4jLoggerAdapterCallStackHandler(Logger slf4jLogger) { this.slf4jLogger = slf4jLogger; } // ------------------------------------------------------------------------ @Override public void onPush(CallStackElt stackElt) { String name = stackElt.getName(); Map<String, Object> inheritedProps = stackElt.getInheritedProps(); Map<String, Object> params = stackElt.getParams(); int progressExpectedCount = stackElt.getProgressExpectedCount(); String msg = formatLogMessagePush(name, inheritedProps, params, progressExpectedCount); slf4jLogger.info(msg); // register self handler on pushed stack elt stackElt.onPushAddCallStackPushPopHandler(this); } @Override public void onPop(CallStackElt stackElt) { String name = stackElt.getName(); long elapsedTime = stackElt.getElapsedTime(); String msg = formatLogMessagePop(name, elapsedTime); slf4jLogger.info(msg); } @Override public void onProgressStep(CallStackElt stackElt) { int progressIndex = stackElt.getProgressIndex(); int progressExpectedCount = stackElt.getProgressExpectedCount(); String progressMessage = stackElt.getProgressMessage(); String msg = formatLogMessageProgress(progressIndex, progressExpectedCount, progressMessage); slf4jLogger.info(msg); } // ------------------------------------------------------------------------ public static String formatLogMessagePush(String name, Map<String, Object> inheritedProps, Map<String, Object> params, int progressExpectedCount) { StringBuilder sb = new StringBuilder(); sb.append("> "); sb.append(name); if (inheritedProps != null && !inheritedProps.isEmpty()) { sb.append(" ["); mapToString(sb, inheritedProps); sb.append("]"); } if (params != null && !params.isEmpty()) { sb.append(" ("); mapToString(sb, params); sb.append(")"); } if (progressExpectedCount != 0) { sb.append(" .. [0/"); sb.append(progressExpectedCount); sb.append("]"); } return sb.toString(); } public static String formatLogMessagePop(String name, long elapsedTimeNanos) { StringBuilder sb = new StringBuilder(); sb.append("< "); sb.append(name); sb.append(", took "); long millis = ThreadTimeUtils.nanosToMillis(elapsedTimeNanos); sb.append(millis); sb.append(" ms"); String msg = sb.toString(); return msg; } public static String formatLogMessageProgress(int progressIndex, int progressExpectedCount, String messageProgress) { StringBuilder sb = new StringBuilder(); sb.append(" .. ["); sb.append(progressIndex); sb.append("/"); sb.append(progressExpectedCount); if (messageProgress != null) { sb.append(": "); sb.append(messageProgress); } sb.append("]"); String msg = sb.toString(); return msg; } public static String formatLogMessageCompound( final PopStackEvent[] popEvents, final PushStackEvent[] pushEvents, final ProgressStepStackEvent[] progressSteps) { StringBuilder sb = new StringBuilder(); if (popEvents != null) { final int popEventsLength = popEvents.length; for (int i = 0; i < popEventsLength; i++) { sb.append("< "); sb.append(popEvents[i].getName()); sb.append(" "); } } if (pushEvents != null) { final int pushEventsLength = pushEvents.length; for (int i = 0; i < pushEventsLength; i++) { sb.append("> "); PushStackEvent pushEvent = pushEvents[i]; sb.append(pushEvent.getName()); if (progressSteps != null && progressSteps[i] != null ) { ProgressStepStackEvent progressStep = progressSteps[i]; sb.append(" ...["); sb.append(progressStep.getProgressIndex()); sb.append("/"); sb.append(progressStep.getProgressExpectedCount()); String progressMessage = progressStep.getProgressMessage(); if (progressMessage != null) { sb.append(": "); sb.append(progressMessage); } sb.append("]"); } sb.append(" "); } } String msg = sb.toString(); return msg; } private static void mapToString(StringBuilder sb, Map<String, Object> map) { for (Iterator<Map.Entry<String, Object>> iter = map.entrySet().iterator(); iter.hasNext();) { Map.Entry<String, Object> e = iter.next(); String key = e.getKey(); Object value = e.getValue(); sb.append(key); sb.append("="); sb.append(value); if (iter.hasNext()) { sb.append(", "); } } } }