-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add @Logger(factory=MyLoggerFactory.class) #843
Comments
👤 Robot.Ninja.Sausage 🕗 May 01, 2015 at 20:00 UTC I would like a new logging annotation that could accept a factory class as a parameter, and would then generate the log field. For example, @ Logger(factory=MyLoggerFactory.class) would become public class MyClass {
} This would make it convenient to add custom loggers, in particular loggers that had custom methods on them that would allow for logging structured data. |
👤 Robot.Ninja.Sausage 🕗 May 27, 2015 at 19:22 UTC I just noticed that the output example is wrong. It should be import com.mycompany.MyLoggerFactory; public class MyClass {
} where MyLogger is the return type of getLogger. |
End of migration |
I'm actually surprised nobody else upvoted this feature. It would be quite useful when you write a wrapper around SLF4J or any other logger, to have business-oriented log methods (e.g. you create a logger method |
The statement "when you write a wrapper around SLF4J" doesn't really make sense since it is a facade. It is already a very extendable system. |
@rspilker It does. While SLF4J is a facade, it's purpose is to interact with logback and other loggers. IMHO placing another facade over it makes sense. Especially, |
@rspilker I probably wasn't explicit enough, sorry about that :/ Concrete example: for all your performance logs, you may write The idea instead is to create a "facade" logger on top of SLF4J, which would look like this: // In custom log facade called BusinessLogger.java
public void perf(Supplier<String> measurementDescription, double duration) {
if (logger.isInfoEnabled()) {
logger.info(measurementDescription.get() + "|" + duration);
}
}
// In business class
private static final BusinessLogger businessLogger = BusinessLoggerFactory.get(MyClass.class);
// And then you use in your business code
businessLogger.perf(() -> "Order for client " + clientId + " in country " + country, transactionTime); Benefits:
There are other benefits (like a BusinessContext) but these are the main ones I see in our day-to-day life in my company. If we could pass to an (existing or new) Lombok annotation a factory class, then we could benefit from all the Lombok work to inject the field, and also benefit from application business logger. The example from Robot.Ninja.Sausage looked neat: @Logger(factory=BusinessLoggerFactory.class)
MyClass {} would become MyClass {
private static final BusinessLogger log = com.mycompany.BusinessLoggerFactory.getLogger(MyClass.class);
} Obviously I have no idea if this is a huge dev or not in Lombok, but I definitely see how many persons could benefit from it. |
I exactly need the same feature as e.g. SLF4J does not support Java 8 specific features like the Supplier functional interface that makes lazy log evaluation much easier, e.g.
|
Hi @rspilker, What's the status on this issue please? Do you accept to add this feature?
package lombok.extern.custom;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.TYPE)
public @interface CustomLogger {
/** @return The category of the constructed Logger. By default, it will use the type where the annotation is placed. */
String topic() default "";
/** @return Mandatory logger factory class */
Class<?> factory();
/** @return Mandatory logger class */
Class<?> logger();
/** @return The factory method to retrieve the logger. */
String methodName() default "getLogger";
} In particular, 2 classes must be passed to this annotation: the logger factory, and the resulting logger, since they are often different.
public static void processAnnotation(LoggingFramework framework, AnnotationValues<?> annotation, JavacNode annotationNode, String loggerTopic, Class<?> factory, Class<?>logger, String factoryMethod)
public static void processAnnotation(LoggingFramework framework, AnnotationValues<?> annotation, JavacNode annotationNode, String loggerTopic) {
processAnnotation(framework, annotation, annotationNode, loggerTopic, null, null, null);
}
What's your opinion? |
@sir4ur0n I guess, configuration is more important than annotation arguments as you probably want to nearly always use the same logger of yours. You probably want both. FWIW, I'm using an Eclipse shortcut generating
where the topic gets obtained via |
@Maaartinus Good point on the Lombok configuration, this probably makes more sense. As for the trick to retrieve the class name, I'm not sure I understand the point. Lombok loggers already retrieve the class name, so there's no problem with that. |
@sir4ur0n Indeed, Lombok loggers are fine in this respect. Only manually declared loggers like
suffer from this problem. No idea why I mentioned that. |
It should SOLELY be configured via However, what if you want to mix em up? I know it's rare, but now presumably there's About using closures for 'efficiency': On most JVMs I doubt that's a solid idea. At any rate, we could add a lombok feature where any log.trace(...) statement is replaced with if (log.isTraceEnabled()) log.trace(...), if there's really a need for that. However, I bet the java community is going to move to log libs which can deal with closures, java will make them efficient, and idiomatic java becomes log.trace(() -> expensiveOperation()); |
Hi @rzwitserloot I'm not sure I understand why you closed this issue? The only reason why it would be useful to configure it in the Java annotation is so users create their own annotations (e.g. |
sorry to comment on a closed issue, but I have the same requirements like:
or the param is a loggerFactory Becasue sometimes we really can not use the default one. |
We have the same kind of requirement. We have a wrapped logger from ESAPI for Log4J. It would be nice to be able to use an annotation like |
|
@rspilker Yes, I agree it could be handled someplace like |
If someone wants to pick this up, we would accept pull requests. Before starting on this, please contact me and/or Reinier on how to approach this. Typically we start with a design, using before and after code. We can move those designs to the tests directory afterwards. It does not need to be in lombok.extern, since there should not be any external libraries involved. Currently, I think |
Regarding parameters for the factory, I think an enum can be used:
|
I need this feature, too. |
Hi all. I also need this feature. Let's assume we have class MyClass that writes some data into log on line 70. Usually we would see something like
From this log it is not possible to understand which node created which line. I have an id of every node in the cluster and what I want is to write some prefix with this id like
I can achieve it easily by custom slf4j logger wrapper like this:
but it requires manual logger creation because it is not possible with lombok annotation. |
@Diarsid have you considered https://logback.qos.ch/manual/mdc.html ? |
Migrated from Google Code (issue 808)
The text was updated successfully, but these errors were encountered: