title: How to log the caller of a method instead of the method which is calling the Logger
body: <p>Given a logging utility class, how to log everything through that class instead of creating a <code>Logger</code> object per class?</p>
  <p>For example, instead of:</p>
  <pre><code>import org.apache.logging.log4j.LogManager;
  import org.apache.logging.log4j.Logger;
  
  public class Main {
  
      private static final Logger LOG = LogManager.getLogger(Main.class);
  
      public static void main(String[] args) {
          LOG.info(&quot;Application started!&quot;);
      }
  }
  </code></pre>
  <p>I would like to do something like this:</p>
  <pre><code>import my.utils.LogUtils;
  
  public class Main {
  
      public static void main(String[] args) {
          LogUtils.info(&quot;Application started!&quot;);
      }
  }
  </code></pre>
  <p>My <code>LogUtils</code> class looks like this:</p>
  <pre><code>package my.utils;
  
  import org.apache.logging.log4j.LogManager;
  import org.apache.logging.log4j.Logger;
  import java.util.HashMap;
  import java.util.Map;
  
  public final class LogUtils {
  
      private LogUtils() {
          throw new AssertionError(&quot;private constructor: &quot; + LogUtils.class.getName());
      }
  
      private static final Map&lt;Class&lt;?&gt;, Logger&gt; LOGGERS = new HashMap&lt;&gt;();
  
      static {
          Class&lt;?&gt; current = LogUtils.class;
          LOGGERS.put(current, LogManager.getLogger(current));
      }
  
      public static void info(Object msg) {
          Logger logger = getFor(getCallerClass());
          // logger.info()... Here's where I am stuck! What I want to log in the stack trace is the *caller* of the &quot;info&quot; method, not the &quot;info&quot; method.
      }
  
      private static Logger getFor(Class&lt;?&gt; clazz) { return LOGGERS.computeIfAbsent(clazz, key -&gt; LogManager.getLogger(key)); }
  
      private static Class&lt;?&gt; getCallerClass() {
          try {
              return Class.forName(getCaller(3).getClassName());
          } catch (ClassNotFoundException e) {
              return LogUtils.class;
          }
      }
  
      // This method should return &quot;main&quot; method name, but it's not being used because I don't know what should I do now
      private static String getCallerMethod() { return getCaller(3).getMethodName(); }
  
      private static StackTraceElement getCaller(int level) { return Thread.currentThread().getStackTrace()[level]; }
  }
  </code></pre>
  <p>I have read <a href="https://logging.apache.org/log4j/2.x/" rel="nofollow noreferrer">several log4j2 documentation pages</a>, but I found nothing regarding my question, and I also checked <a href="https://stackoverflow.com/questions/29258024/different-logger-based-on-caller">several</a> <a href="https://stackoverflow.com/questions/1486233/java-logging-show-the-source-line-number-of-the-caller-not-the-logging-helper">stack overflow</a> <a href="https://stackoverflow.com/questions/23880055/calling-log4js-log-methods-indirectly-from-a-helper-method">questions</a>, but it seems like, <a href="https://www.google.com/search?q=log4j+logging+another+caller" rel="nofollow noreferrer">whatever I try to search</a>, results in a <a href="https://logging.apache.org/log4j/2.x/manual/customloglevels.html#CustomLoggers" rel="nofollow noreferrer">completely different question</a>.</p>
  <p>Is this even possible to do? Because I am starting to doubt it. Denote that I am trying to avoid the usage of a Logger per class... I wouldn't ask the question otherwise. It is, at least, possible to create a custom logger which logs a custom stack trace level?</p>
  <p>As a side note, my Maven dependencies are <a href="https://logging.apache.org/log4j/2.x/maven-artifacts.html#" rel="nofollow noreferrer">the ones given on the log4j2 page</a>:</p>
  <pre class="lang-xml prettyprint-override"><code>&lt;dependencies&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.apache.logging.log4j&lt;/groupId&gt;
          &lt;artifactId&gt;log4j-api&lt;/artifactId&gt;
          &lt;version&gt;2.14.1&lt;/version&gt;
      &lt;/dependency&gt;
      &lt;dependency&gt;
          &lt;groupId&gt;org.apache.logging.log4j&lt;/groupId&gt;
          &lt;artifactId&gt;log4j-core&lt;/artifactId&gt;
          &lt;version&gt;2.14.1&lt;/version&gt;
      &lt;/dependency&gt;
  &lt;/dependencies&gt;
  </code></pre>
  <p>I also must mention that, on an answer, there's this call:</p>
  <pre><code>LOG.log(LoggingHelper.class.getCanonicalName(), Level.INFO, message, null);
  </code></pre>
  <p>I can't find a method in <code>org.apache.logging.log4j.Logger</code> which (Javadoc like) refers like this:</p>
  <pre><code>Logger#log(String, Level, Object, Throwable);
  </code></pre>
  <p>It <em>simply</em> doesn't exist.</p>