/** * Copyright (c) Dell Inc., or its subsidiaries. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 */ package io.pravega.common; import java.util.function.Function; import java.util.function.Supplier; import org.slf4j.Logger; /** * Extension methods for Logger class. */ public final class LoggerHelpers { /** * Used to generate TraceEnter Ids. To properly calculate elapsed time, this returns the current System.nanoTime(). */ private static final Supplier<Long> CURRENT_TIME = System::nanoTime; /** * Calculates the elapsed time (in microseconds), given a properly generated TraceEnterId. */ private static final Function<Long, Long> ELAPSED_MICRO = startTime -> (CURRENT_TIME.get() - startTime) / 1000; /** * Traces the fact that a method entry has occurred. * * @param log The Logger to log to. * @param method The name of the method. * @param args The arguments to the method. * @return A generated identifier that can be used to correlate this traceEnter with its corresponding traceLeave. * This is usually generated from the current System time, and when used with traceLeave it can be used to log * elapsed call times. */ public static long traceEnter(Logger log, String method, Object... args) { if (!log.isTraceEnabled()) { return 0; } long time = CURRENT_TIME.get(); log.trace("ENTER {}@{} {}.", method, time, args); return time; } /** * Traces the fact that a method entry has occurred. * * @param log The Logger to log to. * @param context Identifying context for the operation. For example, this can be used to differentiate between * different instances of the same object. * @param method The name of the method. * @param args The arguments to the method. * @return A generated identifier that can be used to correlate this traceEnter with its corresponding traceLeave. * This is usually generated from the current System time, and when used with traceLeave it can be used to log * elapsed call times. */ public static long traceEnterWithContext(Logger log, String context, String method, Object... args) { if (!log.isTraceEnabled()) { return 0; } long time = CURRENT_TIME.get(); log.trace("ENTER {}::{}@{} {}.", context, method, time, args); return time; } /** * Traces the fact that a method has exited normally. * * @param log The Logger to log to. * @param method The name of the method. * @param traceEnterId The correlation Id obtained from a traceEnter call. * @param args Additional arguments to log. */ public static void traceLeave(Logger log, String method, long traceEnterId, Object... args) { if (!log.isTraceEnabled()) { return; } if (args.length == 0) { log.trace("LEAVE {}@{} (elapsed={}us).", method, traceEnterId, ELAPSED_MICRO.apply(traceEnterId)); } else { log.trace("LEAVE {}@{} {} (elapsed={}us).", method, traceEnterId, args, ELAPSED_MICRO.apply(traceEnterId)); } } /** * Traces the fact that a method has exited normally. * * @param log The Logger to log to. * @param context Identifying context for the operation. For example, this can be used to differentiate between * different instances of the same object. * @param method The name of the method. * @param traceEnterId The correlation Id obtained from a traceEnter call. * @param args Additional arguments to log. */ public static void traceLeave(Logger log, String context, String method, long traceEnterId, Object... args) { if (!log.isTraceEnabled()) { return; } if (args.length == 0) { log.trace("LEAVE {}::{}@{} (elapsed={}us).", context, method, traceEnterId, ELAPSED_MICRO.apply(traceEnterId)); } else { log.trace("LEAVE {}::{}@{} {} (elapsed={}us).", context, method, traceEnterId, args, ELAPSED_MICRO.apply(traceEnterId)); } } /** * Returns either the given {@link Throwable} or its message, depending on the current logging context. * * @param log The {@link Logger} to query. * @param e The {@link Throwable} to return or process. * @return The given {@link Throwable}, if {@link Logger#isDebugEnabled()} is true for log, or {@link Throwable#toString()} * otherwise (which should output only the name of the exception). */ public static Object exceptionSummary(Logger log, Throwable e) { if (log.isDebugEnabled()) { return e; } else { return e.toString(); } } }