Reputation: 1033
I am using logback but, rather than having the logger class called directly, I would like to have a custom class/wrapper class which logs the data. (This is required by the usecase). I would like to print the source class names which are calling this wrapper class rather than the wrapper class. I tried logging with this class but its always printing the className of the wrapper class.
class MyAppLogTest {
public static void main(String args[]) {
String msg="Some Msg";
ApplicationLogger.logData( "MyAppLogTest", "main",msg);
}
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class ApplicationLogger {
private static Logger logger = null;
static {
logger = (Logger) LoggerFactory.getLogger(ApplicationLogger.class);
}
public static void logData(final String clazz, final String method,final String msg) {
logger.info(msg);
}
}
Regards
Upvotes: 0
Views: 745
Reputation: 3117
I'm not sure if there is a nice and straightforward way to access the name of the method that called the logger. But I think a solution to access the class name of the caller could be something like this (I didn't have time to run it, but I think it would work):
class MyAppLogTest {
// An static instance of your custom logger initialized with
// the class that would call it
private static ApplicationLogger applicationLogger = new ApplicationLogger(MyAppLogTest.class);
public static void main(String args[]) {
String msg="Some Msg";
applicationLogger.logData("main", msg);
}
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class ApplicationLogger {
private static Logger logger;
private Class callingClass;
public ApplicationLogger(Class callingClass) {
this.callingClass = callingClass;
this.logger = (Logger) LoggerFactory.getLogger(callingClass);
}
}
public static void logData(final String method, final String msg) {
logger.info(method + "-" + msg);
}
}
If it's really important to have also access to the method name, you can add another property of type Method
to your ApplicationLogger
class and initialize it in constructor. Then you can instantiate the logger per method (which could easily become a performance bottleneck) and passing your current method as that parameter.
Also I think it worth to take a look at Aspect Oriented Programming techniques/libraries. Maybe you could find another solution based on AOP for your original problem.
Upvotes: 0
Reputation: 38300
Not a great solution, but you can pull the calling class from the stack and use in the log message.
To do this, you can do something like this:
final StringBuilder returnValue = new StringBuilder();
final Throwable throwable = new Throwable();
try
{
final StackTraceElement[] elements = throwable.getStackTrace();
final String methodName;
if ((elements != null) &&
(elements.length > 2))
{
methodName = elements[2].getMethodName();
returnValue.append(methodName);
returnValue.append("()");
}
}
catch (Exception ignoredException)
{
// use some default value.
}
return returnValue;
The index of the desired class may not be 2 for you.
Upvotes: 1