<pre><code>public static Logger getLogger() {
    final Throwable t = new Throwable();
    final StackTraceElement methodCaller = t.getStackTrace()[1];
    final Logger logger = Logger.getLogger(methodCaller.getClassName());
    logger.setLevel(ResourceManager.LOGLEVEL);
    return logger;
}
</code></pre>

<p>This method would return a logger that knows the class it's logging for.
Any ideas against it?</p>

<p>Many years later: <a href="https://github.com/yanchenko/droidparts/blob/master/droidparts/src/org/droidparts/util/L.java" rel="noreferrer">https://github.com/yanchenko/droidparts/blob/master/droidparts/src/org/droidparts/util/L.java</a></p>

[{'answer_id': 80754, 'author': 'Ian', 'author_id': 4396, 'author_profile': 'https://Stackoverflow.com/users/4396', 'pm_score': 2, 'selected': False, 'text': '<p>You could of course just use Log4J with the appropriate pattern layout:</p>\n\n<blockquote>\n  <p>For example, for the class name "org.apache.xyz.SomeClass", the pattern %C{1} will output "SomeClass". </p>\n</blockquote>\n\n<p><a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html" rel="nofollow noreferrer">http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html</a></p>\n'}, {'answer_id': 80762, 'author': 'Daan', 'author_id': 197, 'author_profile': 'https://Stackoverflow.com/users/197', 'pm_score': 5, 'selected': True, 'text': "<p>I guess it adds a lot of overhead for every class. Every class has to be 'looked up'. You create new Throwable objects to do that... These throwables don't come for free.</p>\n"}, {'answer_id': 80851, 'author': 'Mario Ortegón', 'author_id': 2309, 'author_profile': 'https://Stackoverflow.com/users/2309', 'pm_score': 0, 'selected': False, 'text': '<p>Why not?</p>\n\n<pre><code>public static Logger getLogger(Object o) {\n  final Logger logger = Logger.getLogger(o.getClass());\n  logger.setLevel(ResourceManager.LOGLEVEL);\n  return logger;\n}\n</code></pre>\n\n<p>And then when you need a logger for a class:</p>\n\n<pre><code>getLogger(this).debug("Some log message")\n</code></pre>\n'}, {'answer_id': 80898, 'author': 'Philip Helger', 'author_id': 15254, 'author_profile': 'https://Stackoverflow.com/users/15254', 'pm_score': 2, 'selected': False, 'text': "<p>I prefer creating a (static) Logger for each class (with it's explicit class name). I than use the logger as is.</p>\n"}, {'answer_id': 81494, 'author': 'Bill Michell', 'author_id': 7938, 'author_profile': 'https://Stackoverflow.com/users/7938', 'pm_score': 0, 'selected': False, 'text': '<p>This mechanism puts in a lot of extra effort at runtime.</p>\n\n<p>If you use Eclipse as your IDE, consider using <a href="http://log4e.jayefem.de/" rel="nofollow noreferrer">Log4e</a>. This handy plugin will generate logger declarations for you using your favourite logging framework. A fraction more effort at coding time, but <strong>much</strong> less work at runtime.</p>\n'}, {'answer_id': 83847, 'author': '18Rabbit', 'author_id': 12662, 'author_profile': 'https://Stackoverflow.com/users/12662', 'pm_score': 3, 'selected': False, 'text': "<p>For every class that you use this with, you're going to have to look up the Logger anyway, so you might as well just use a static Logger in those classes.</p>\n\n<pre><code>private static final Logger logger = Logger.getLogger(MyClass.class.getName());\n</code></pre>\n\n<p>Then you just reference that logger when you need to do your log messages.  Your method does the same thing that the static Log4J Logger does already so why reinvent the wheel?</p>\n"}, {'answer_id': 83866, 'author': 'Asgeir S. Nilsen', 'author_id': 16023, 'author_profile': 'https://Stackoverflow.com/users/16023', 'pm_score': 0, 'selected': False, 'text': '<p>Unless you <em>really</em> need your Logger to be static, you could use</p>\n\n<pre><code>final Logger logger = LoggerFactory.getLogger(getClass());\n</code></pre>\n'}, {'answer_id': 104851, 'author': 'erickson', 'author_id': 3474, 'author_profile': 'https://Stackoverflow.com/users/3474', 'pm_score': 5, 'selected': False, 'text': '<p>Creating a stack trace is a relatively slow operation. Your caller already knows what class and method it is in, so the effort is wasted. This aspect of your solution is inefficient.</p>\n\n<p>Even if you use static class information, you should not fetch the Logger again for each message. <a href="http://www.qos.ch/logging/thinkAgain.jsp" rel="noreferrer">From the author</a> of Log4j,Ceki Gülcü: </p>\n\n<blockquote>\n  <p>The most common error in wrapper classes is the invocation of the Logger.getLogger method on each log request. This is guaranteed to wreak havoc on your application\'s performance. Really!!! </p>\n</blockquote>\n\n<p>This is the conventional, efficient idiom for getting a Logger is during class initialization:</p>\n\n<pre><code>private static final Logger log = Logger.getLogger(MyClass.class);\n</code></pre>\n\n<p>Note that this gives you a separate Logger for each type in a hierarchy. If you come up with a method that invokes <code>getClass()</code> on an instance, you will see messages logged by a base type showing up under the subtype\'s logger. Maybe this is desirable in some cases, but I find it confusing (and I tend to favor composition over inheritance anyway). </p>\n\n<p>Obviously, using the dynamic type via <code>getClass()</code> will require you to obtain the logger at least once per instance, rather than once per class like the recommended idiom using static type information.</p>\n'}, {'answer_id': 303344, 'author': 'ykaganovich', 'author_id': 10026, 'author_profile': 'https://Stackoverflow.com/users/10026', 'pm_score': 2, 'selected': False, 'text': "<p>You don't need to create a new Throwable object. You can just call \n<code>Thread.currentThread().getStackTrace()[1]</code></p>\n"}, {'answer_id': 1268633, 'author': 'EGB', 'author_id': 155399, 'author_profile': 'https://Stackoverflow.com/users/155399', 'pm_score': 3, 'selected': False, 'text': "<p>Assuming you are keeping static refs to the loggers, here's a standalone static singleton:</p>\n\n<pre><code>public class LoggerUtils extends SecurityManager\n{\n    public static Logger getLogger()\n    {\n        String className = new LoggerUtils().getClassName();\n        Logger logger = Logger.getLogger(className);\n        return logger;\n    }\n\n    private String getClassName()\n    {\n        return getClassContext()[2].getName();\n    }\n}\n</code></pre>\n\n<p>Usage is nice and clean:</p>\n\n<pre><code>Logger logger = LoggerUtils.getLogger();\n</code></pre>\n"}, {'answer_id': 1705696, 'author': 'Cowan', 'author_id': 17041, 'author_profile': 'https://Stackoverflow.com/users/17041', 'pm_score': 4, 'selected': False, 'text': '<p>We actually have something quite similar in a LogUtils class. Yes, it\'s kind of icky, but the advantages are worth it as far as I\'m concerned. We wanted to make sure we didn\'t have any overhead from it being repeatedly called though, so ours (somewhat hackily) ensures that it can ONLY be called from a static initializer context, a la:</p>\n\n<pre><code>private static final Logger LOG = LogUtils.loggerForThisClass();\n</code></pre>\n\n<p>It will fail if it\'s invoked from a normal method, or from an instance initializer (i.e. if the \'static\' was left off above) to reduce the risk of performance overhead. The method is:</p>\n\n<pre><code>public static Logger loggerForThisClass() {\n    // We use the third stack element; second is this method, first is .getStackTrace()\n    StackTraceElement myCaller = Thread.currentThread().getStackTrace()[2];\n    Assert.equal("&lt;clinit&gt;", myCaller.getMethodName());\n    return Logger.getLogger(myCaller.getClassName());\n}\n</code></pre>\n\n<p>Anyone who asks what advantage does this have over </p>\n\n<pre><code>= Logger.getLogger(MyClass.class);\n</code></pre>\n\n<p>has probably never had to deal with someone who copies and pastes that line from somewhere else and forgets to change the class name, leaving you dealing with a class which sends all its stuff to another logger.</p>\n'}, {'answer_id': 2400226, 'author': 'Alaa Murad', 'author_id': 288624, 'author_profile': 'https://Stackoverflow.com/users/288624', 'pm_score': 2, 'selected': False, 'text': '<p>Then the best thing is mix of two . </p>\n\n<pre><code>public class LoggerUtil {\n\n    public static Level level=Level.ALL;\n\n    public static java.util.logging.Logger getLogger() {\n        final Throwable t = new Throwable();\n        final StackTraceElement methodCaller = t.getStackTrace()[1];\n        final java.util.logging.Logger logger = java.util.logging.Logger.getLogger(methodCaller.getClassName());\n        logger.setLevel(level);\n\n        return logger;\n    }\n}\n</code></pre>\n\n<p>And then in every class:</p>\n\n<pre><code>private static final Logger LOG = LoggerUtil.getLogger();\n</code></pre>\n\n<p>in code :</p>\n\n<pre><code>LOG.fine("debug that !...");\n</code></pre>\n\n<p>You get static logger that you can just copy&amp;paste in every class and with no overhead ...</p>\n\n<p>Alaa</p>\n'}, {'answer_id': 6459115, 'author': 'Ed Sarrazin', 'author_id': 812881, 'author_profile': 'https://Stackoverflow.com/users/812881', 'pm_score': 2, 'selected': False, 'text': '<p>From reading through all the other feedback on this site, I created the following for use with Log4j:</p>\n\n<pre><code>package com.edsdev.testapp.util;\n\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport org.apache.log4j.Level;\nimport org.apache.log4j.Priority;\n\npublic class Logger extends SecurityManager {\n\nprivate static ConcurrentHashMap&lt;String, org.apache.log4j.Logger&gt; loggerMap = new ConcurrentHashMap&lt;String, org.apache.log4j.Logger&gt;();\n\npublic static org.apache.log4j.Logger getLog() {\n    String className = new Logger().getClassName();\n    if (!loggerMap.containsKey(className)) {\n        loggerMap.put(className, org.apache.log4j.Logger.getLogger(className));\n    }\n    return loggerMap.get(className);\n}\npublic String getClassName() {\n    return getClassContext()[3].getName();\n}\npublic static void trace(Object message) {\n    getLog().trace(message);\n}\npublic static void trace(Object message, Throwable t) {\n    getLog().trace(message, t);\n}\npublic static boolean isTraceEnabled() {\n    return getLog().isTraceEnabled();\n}\npublic static void debug(Object message) {\n    getLog().debug(message);\n}\npublic static void debug(Object message, Throwable t) {\n    getLog().debug(message, t);\n}\npublic static void error(Object message) {\n    getLog().error(message);\n}\npublic static void error(Object message, Throwable t) {\n    getLog().error(message, t);\n}\npublic static void fatal(Object message) {\n    getLog().fatal(message);\n}\npublic static void fatal(Object message, Throwable t) {\n    getLog().fatal(message, t);\n}\npublic static void info(Object message) {\n    getLog().info(message);\n}\npublic static void info(Object message, Throwable t) {\n    getLog().info(message, t);\n}\npublic static boolean isDebugEnabled() {\n    return getLog().isDebugEnabled();\n}\npublic static boolean isEnabledFor(Priority level) {\n    return getLog().isEnabledFor(level);\n}\npublic static boolean isInfoEnabled() {\n    return getLog().isInfoEnabled();\n}\npublic static void setLevel(Level level) {\n    getLog().setLevel(level);\n}\npublic static void warn(Object message) {\n    getLog().warn(message);\n}\npublic static void warn(Object message, Throwable t) {\n    getLog().warn(message, t);\n}\n</code></pre>\n\n<p>}</p>\n\n<p>Now in your code all you need is</p>\n\n<pre><code>Logger.debug("This is a test");\n</code></pre>\n\n<p>or</p>\n\n<pre><code>Logger.error("Look what happened Ma!", e);\n</code></pre>\n\n<p>If you need more exposure to log4j methods, just delegate them from the Logger class listed above.</p>\n'}, {'answer_id': 11937492, 'author': 'joseaio', 'author_id': 1312464, 'author_profile': 'https://Stackoverflow.com/users/1312464', 'pm_score': 0, 'selected': False, 'text': '<p>Please see my static getLogger() implementation (use same "sun.*" magic on JDK 7 as default java Logger doit)</p>\n\n<ul>\n<li><p>note static logging methods (with static import) without ugly log property...</p>\n\n<p>import static my.pakg.Logger.*;</p></li>\n</ul>\n\n<p>And their speed is equivalent to native Java implementation (checked with 1 million of log traces)</p>\n\n<pre><code>package my.pkg;\n\nimport java.text.MessageFormat;\nimport java.util.Arrays;\nimport java.util.IllegalFormatException;\nimport java.util.logging.Level;\nimport java.util.logging.LogRecord;\n\nimport sun.misc.JavaLangAccess;\nimport sun.misc.SharedSecrets;\n\n\npublic class Logger {\nstatic final int CLASS_NAME = 0;\nstatic final int METHOD_NAME = 1;\n\n// Private method to infer the caller\'s class and method names\nprotected static String[] getClassName() {\n    JavaLangAccess access = SharedSecrets.getJavaLangAccess();\n    Throwable throwable = new Throwable();\n    int depth = access.getStackTraceDepth(throwable);\n\n    boolean lookingForLogger = true;\n    for (int i = 0; i &lt; depth; i++) {\n        // Calling getStackTraceElement directly prevents the VM\n        // from paying the cost of building the entire stack frame.\n        StackTraceElement frame = access.getStackTraceElement(throwable, i);\n        String cname = frame.getClassName();\n        boolean isLoggerImpl = isLoggerImplFrame(cname);\n        if (lookingForLogger) {\n            // Skip all frames until we have found the first logger frame.\n            if (isLoggerImpl) {\n                lookingForLogger = false;\n            }\n        } else {\n            if (!isLoggerImpl) {\n                // skip reflection call\n                if (!cname.startsWith("java.lang.reflect.") &amp;&amp; !cname.startsWith("sun.reflect.")) {\n                    // We\'ve found the relevant frame.\n                    return new String[] {cname, frame.getMethodName()};\n                }\n            }\n        }\n    }\n    return new String[] {};\n    // We haven\'t found a suitable frame, so just punt.  This is\n    // OK as we are only committed to making a "best effort" here.\n}\n\nprotected static String[] getClassNameJDK5() {\n    // Get the stack trace.\n    StackTraceElement stack[] = (new Throwable()).getStackTrace();\n    // First, search back to a method in the Logger class.\n    int ix = 0;\n    while (ix &lt; stack.length) {\n        StackTraceElement frame = stack[ix];\n        String cname = frame.getClassName();\n        if (isLoggerImplFrame(cname)) {\n            break;\n        }\n        ix++;\n    }\n    // Now search for the first frame before the "Logger" class.\n    while (ix &lt; stack.length) {\n        StackTraceElement frame = stack[ix];\n        String cname = frame.getClassName();\n        if (isLoggerImplFrame(cname)) {\n            // We\'ve found the relevant frame.\n            return new String[] {cname, frame.getMethodName()};\n        }\n        ix++;\n    }\n    return new String[] {};\n    // We haven\'t found a suitable frame, so just punt.  This is\n    // OK as we are only committed to making a "best effort" here.\n}\n\n\nprivate static boolean isLoggerImplFrame(String cname) {\n    // the log record could be created for a platform logger\n    return (\n            cname.equals("my.package.Logger") ||\n            cname.equals("java.util.logging.Logger") ||\n            cname.startsWith("java.util.logging.LoggingProxyImpl") ||\n            cname.startsWith("sun.util.logging."));\n}\n\nprotected static java.util.logging.Logger getLogger(String name) {\n    return java.util.logging.Logger.getLogger(name);\n}\n\nprotected static boolean log(Level level, String msg, Object... args) {\n    return log(level, null, msg, args);\n}\n\nprotected static boolean log(Level level, Throwable thrown, String msg, Object... args) {\n    String[] values = getClassName();\n    java.util.logging.Logger log = getLogger(values[CLASS_NAME]);\n    if (level != null &amp;&amp; log.isLoggable(level)) {\n        if (msg != null) {\n            log.log(getRecord(level, thrown, values[CLASS_NAME], values[METHOD_NAME], msg, args));\n        }\n        return true;\n    }\n    return false;\n}\n\nprotected static LogRecord getRecord(Level level, Throwable thrown, String className, String methodName, String msg, Object... args) {\n    LogRecord record = new LogRecord(level, format(msg, args));\n    record.setSourceClassName(className);\n    record.setSourceMethodName(methodName);\n    if (thrown != null) {\n        record.setThrown(thrown);\n    }\n    return record;\n}\n\nprivate static String format(String msg, Object... args) {\n    if (msg == null || args == null || args.length == 0) {\n        return msg;\n    } else if (msg.indexOf(\'%\') &gt;= 0) {\n        try {\n            return String.format(msg, args);\n        } catch (IllegalFormatException esc) {\n            // none\n        }\n    } else if (msg.indexOf(\'{\') &gt;= 0) {\n        try {\n            return MessageFormat.format(msg, args);\n        } catch (IllegalArgumentException exc) {\n            // none\n        }\n    }\n    if (args.length == 1) {\n        Object param = args[0];\n        if (param != null &amp;&amp; param.getClass().isArray()) {\n            return msg + Arrays.toString((Object[]) param);\n        } else if (param instanceof Throwable){\n            return msg;\n        } else {\n            return msg + param;\n        }\n    } else {\n        return msg + Arrays.toString(args);\n    }\n}\n\npublic static void severe(String msg, Object... args) {\n    log(Level.SEVERE, msg, args);\n}\n\npublic static void warning(String msg, Object... args) {\n    log(Level.WARNING, msg, args);\n}\n\npublic static void info(Throwable thrown, String format, Object... args) {\n    log(Level.INFO, thrown, format, args);\n}\n\npublic static void warning(Throwable thrown, String format, Object... args) {\n    log(Level.WARNING, thrown, format, args);\n}\n\npublic static void warning(Throwable thrown) {\n    log(Level.WARNING, thrown, thrown.getMessage());\n}\n\npublic static void severe(Throwable thrown, String format, Object... args) {\n    log(Level.SEVERE, thrown, format, args);\n}\n\npublic static void severe(Throwable thrown) {\n    log(Level.SEVERE, thrown, thrown.getMessage());\n}\n\npublic static void info(String msg, Object... args) {\n    log(Level.INFO, msg, args);\n}\n\npublic static void fine(String msg, Object... args) {\n    log(Level.FINE, msg, args);\n}\n\npublic static void finer(String msg, Object... args) {\n    log(Level.FINER, msg, args);\n}\n\npublic static void finest(String msg, Object... args) {\n    log(Level.FINEST, msg, args);\n}\n\npublic static boolean isLoggableFinest() {\n    return isLoggable(Level.FINEST);\n}\n\npublic static boolean isLoggableFiner() {\n    return isLoggable(Level.FINER);\n}\n\npublic static boolean isLoggableFine() {\n    return isLoggable(Level.FINE);\n}\n\npublic static boolean isLoggableInfo() {\n    return isLoggable(Level.INFO);\n}\n\npublic static boolean isLoggableWarning() {\n    return isLoggable(Level.WARNING);\n}\npublic static boolean isLoggableSevere() {\n    return isLoggable(Level.SEVERE);\n}\n\nprivate static boolean isLoggable(Level level) {\n    return log(level, null);\n}\n\n}\n</code></pre>\n'}, {'answer_id': 14670532, 'author': 'yegor256', 'author_id': 187141, 'author_profile': 'https://Stackoverflow.com/users/187141', 'pm_score': 0, 'selected': False, 'text': '<p>Take a look at <a href="http://www.jcabi.com/jcabi-log/apidocs-0.7.7/com/jcabi/log/Logger.html" rel="nofollow"><code>Logger</code></a> class from <a href="http://www.jcabi.com/jcabi-log/" rel="nofollow">jcabi-log</a>. It does exactly what you\'re looking for, providing a collection of static methods. You don\'t need to embed loggers into classes any more:</p>\n\n<pre><code>import com.jcabi.log.Logger;\nclass Foo {\n  public void bar() {\n    Logger.info(this, "doing something...");\n  }\n}\n</code></pre>\n\n<p><code>Logger</code> sends all logs to SLF4J, which you can redirect to any other logging facility, in runtime.</p>\n'}, {'answer_id': 32010391, 'author': 'muttonUp', 'author_id': 3696510, 'author_profile': 'https://Stackoverflow.com/users/3696510', 'pm_score': 1, 'selected': False, 'text': "<p>I just have the following line at the beginning of most of my classes.</p>\n\n<pre><code>  private static final Logger log = \n     LoggerFactory.getLogger(new Throwable().getStackTrace()[0].getClassName());\n</code></pre>\n\n<p>yes there is some overhead the very first time an object of that class is created, but I work mostly in webapps, so adding microseconds onto a 20 second startup isn't really a problem.</p>\n"}, {'answer_id': 32132312, 'author': 'Neeraj', 'author_id': 528757, 'author_profile': 'https://Stackoverflow.com/users/528757', 'pm_score': 5, 'selected': False, 'text': '<p>The <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/invoke/MethodHandles.html" rel="noreferrer">MethodHandles</a> class (as of Java 7) includes a <a href="https://docs.oracle.com/javase/7/docs/api/java/lang/invoke/MethodHandles.Lookup.html" rel="noreferrer">Lookup</a> class that, from a static context, can find and return the name of the current class. Consider the following example:</p>\n\n<pre><code>import java.lang.invoke.MethodHandles;\n\npublic class Main {\n  private static final Class clazz = MethodHandles.lookup().lookupClass();\n  private static final String CLASSNAME = clazz.getSimpleName();\n\n  public static void main( String args[] ) {\n    System.out.println( CLASSNAME );\n  }\n}\n</code></pre>\n\n<p>When run this produces:</p>\n\n<pre><code>Main\n</code></pre>\n\n<p>For a logger, you could use:</p>\n\n<pre><code>private static Logger LOGGER = \n  Logger.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());\n</code></pre>\n'}, {'answer_id': 39446629, 'author': 'user2189998', 'author_id': 2189998, 'author_profile': 'https://Stackoverflow.com/users/2189998', 'pm_score': 2, 'selected': False, 'text': '<p>A good alternative is to use (one of) the lombok logs annotations :\n<a href="https://projectlombok.org/features/Log.html" rel="nofollow">https://projectlombok.org/features/Log.html</a></p>\n\n<p>It generate the corresponding log statement with the current class.</p>\n'}, {'answer_id': 52744364, 'author': 'James Mudd', 'author_id': 4653517, 'author_profile': 'https://Stackoverflow.com/users/4653517', 'pm_score': 1, 'selected': False, 'text': '<p>Google Flogger logging API supports this e.g.</p>\n\n<pre><code>private static final FluentLogger logger = FluentLogger.forEnclosingClass();\n</code></pre>\n\n<p>See <a href="https://github.com/google/flogger" rel="nofollow noreferrer">https://github.com/google/flogger</a> for more details.</p>\n'}, {'answer_id': 54787201, 'author': 'James Mudd', 'author_id': 4653517, 'author_profile': 'https://Stackoverflow.com/users/4653517', 'pm_score': 1, 'selected': False, 'text': '<p>A nice way to do this from Java 7 onwards:</p>\n\n<pre><code>private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());\n</code></pre>\n\n<p>The logger can be <code>static</code> and that fine.\nHere its using the SLF4J API</p>\n\n<pre><code>import org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n</code></pre>\n\n<p>But in principal can be used with any logging framework. If the logger needs a string argument add <code>toString()</code></p>\n'}, {'answer_id': 56684047, 'author': 'Choletski', 'author_id': 3595288, 'author_profile': 'https://Stackoverflow.com/users/3595288', 'pm_score': 1, 'selected': False, 'text': '<p><strong>Simple and trivial OLD SCHOOL:</strong></p>\n\n<p>Just create your own class and pass there class name, method name + comment (if class /method changed they\'re refactored automatically Shift+F6)</p>\n\n<pre><code>public class MyLogs {    \n    public static void LOG(String theClass, String theMethod, String theComment) {\n        Log.d("MY_TAG", "class: " + theClass + " meth : " + theMethod + " comm : " + theComment);\n    }\n}\n</code></pre>\n\n<p>and just use it anywhere in the app (no context required, no initialzation, no extra libs and no look up) - can be used for any programing language!</p>\n\n<pre><code>MyLogs.LOG("MainActivity", "onCreate", "Hello world");\n</code></pre>\n\n<p>this will print in your console:</p>\n\n<blockquote>\n  <p>MY_TAG class: MainActivity meth: onCreate comm: Hello world</p>\n</blockquote>\n'}]
['https://Stackoverflow.com/questions/80692', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/15187/']