/** * Tracer that is applied before a function is called, printing the arguments * * @param tag tag to start the debug printout string * @param paramStart param index to start outputting from * @param args arguments to the function */ static void traceArgs(final DebugLogger logger, final String tag, final int paramStart, final Object... args) { final StringBuilder sb = new StringBuilder(); sb.append(tag); for (int i = paramStart; i < args.length; i++) { if (i == paramStart) { sb.append(" => args: "); } sb.append('\''). append(stripName(argString(args[i]))). append('\''). append(' '). append('['). append("type="). append(args[i] == null ? "null" : stripName(args[i].getClass())). append(']'); if (i + 1 < args.length) { sb.append(", "); } } assert logger != null; logger.log(TRACE_LEVEL, sb); stacktrace(logger); }
private static void stacktrace(final DebugLogger logger) { if (!PRINT_STACKTRACE) { return; } final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final PrintStream ps = new PrintStream(baos); new Throwable().printStackTrace(ps); logger.log(TRACE_LEVEL, baos.toString()); }
/** * Add a debug printout to a method handle, tracing parameters and return values * * @param logger a specific logger to which to write the output * @param mh method handle to trace * @param paramStart first param to print/trace * @param printReturnValue should we print/trace return value if available? * @param tag start of trace message * @return traced method handle */ public static MethodHandle addDebugPrintout(final DebugLogger logger, final MethodHandle mh, final int paramStart, final boolean printReturnValue, final Object tag) { final MethodType type = mh.type(); if (logger != null && logger.levelAbove(TRACE_LEVEL)) { return mh; } assert logger != null; assert TRACE != null; MethodHandle trace = MethodHandles.insertArguments(TRACE, 0, logger, tag, paramStart); trace = MethodHandles.foldArguments( mh, trace.asCollector( Object[].class, type.parameterCount()). asType(type.changeReturnType(void.class))); final Class<?> retType = type.returnType(); if (retType != void.class && printReturnValue) { final MethodHandle traceReturn = MethodHandles.insertArguments(TRACE_RETURN, 0, logger); trace = MethodHandles.filterReturnValue(trace, traceReturn.asType( traceReturn.type().changeParameterType(0, retType).changeReturnType(retType))); } return trace; }
TraceFunctionality(final DebugLogger log) { super(log); }
/** * Tracer that is applied before a value is returned from the traced function. It will output the return * value and its class * * @param value return value for filter * @return return value unmodified */ static Object traceReturn(final DebugLogger logger, final Object value) { final String str = "\treturn: " + stripName(value) + " [type=" + (value == null ? "null" : stripName(value.getClass()) + ']'); logger.log(TRACE_LEVEL, str); return value; }
/** * Add a debug printout to a method handle, tracing parameters and return values * * @param logger a specific logger to which to write the output * @param mh method handle to trace * @param tag start of trace message * @return traced method handle */ public static MethodHandle addDebugPrintout(final DebugLogger logger, final MethodHandle mh, final Object tag) { return addDebugPrintout(logger, mh, 0, true, tag); }
/** * Constructor * @param log logger */ public Functionality(final DebugLogger log) { this.log = log; }