Liferay Log override - java

i want override the interface Log, because i use always this menssage:
private final static Log log = LogFactoryUtil.getLog(classess.class);
log.error("La cita " + cita.getIdCita() + " ha producido un excepcion en " + e.getClass() + " casuda por "
+ e.getCause() + ". Trace: " + e.getLocalizedMessage());
my idea is override log.error for get in for parameter the throwlable only and then print the message but i don't know how call to original error.

If I understood correctly, you want to introduce a new method (with 4 parameters) to the Log interface. This is completely discouraged, as your new interface would be utterly incompatible with the assumption that anybody else makes when using this interface (or when providing alternative implementations). You would basically maintain your own private fork of Liferay, largely incompatible with the rest of the world. And that only for a change in a lowly Log class.
Don't go there. It's not too bad to construct an error message like you do in the snippet that you include in your question.
If you have the same thing duplicated everywhere in your code and think it would be cleaner otherwise, encapsulate Liferay's logging within your own logging class and use that, delegating to Liferay's log in the end.
However, don't invest too much time in fancy logging. IMHO that problem has been tackled once and forever, and within an application context, you'd not be able to deliver significant enhancement to the logging world...

Related

ArchUnit class link in violation messages

I've noticed that using standard ArchConditions display messages in the following format:
Class <full_class_path> does not <some_rule> in (<class_link>)
However, this is not the case for custom conditions that add violation messages to the event like:
events.add(SimpleConditionEvent.violated(item, item.getName() + " some message"));
With this, no link to the violating class is appended to the message automatically. I wonder what the first argument (correspondingObject) is actually used for then.
Is this a bug in the framework or am I missing something? Having these links are really useful. I've tried using the JavaDoc #link notation in the message string to no avail.
Most of the domain classes like JavaClass, JavaMember or JavaAccess implement the interface HasSourceCodeLocation, which contains the method getSourceCodeLocation to obtain the location in the source code. The returned object SourceCodeLocation can then be used to output the location via the toString method.
For example
events.add(SimpleConditionEvent.violated(item, item.getDescription() + " is violated in " + item.getSourceCodeLocation()));
would return
Class <org.example.Dummy> is violated in (Dummy.java:0)

How to solve this issue "Standard outputs should not be used directly to log anything "

I need a print statement. But sonar not allowed this type.
String txt="Something";
System.out.println("Print: "+txt);
Expected output:
Print: Something
I tried this format logger.log().its not working for our requirement.
Sonarqube does not like it if you use System.out, or if you have string concatenation or other computation in the arguments you pass to the logging function. Construct the full message on a separate line before logging it:
String txt = "Print: " + "Something";
String logMessage = "Print: " + txt;
logger.log(Level.INFO, logMessage);
If logger is not meeting your requirements, make it to do so by configuring it.
There are some widely used logging frameworks that are highly configurable and I doubt that they will not be able to do whatever you are doing with plain System.out.println
For example, check out very popular SLF4J and Logback as logging provider.
http://www.slf4j.org/
http://logback.qos.ch/

SLF4J: isDebugEnabled() not working

My java application which is using SLF4J is running on Unix box and my code has entries like :
if (LOG.isDebugEnabled())
LOG.debug("There is nothing in the cache for " + quote.getObject().getObjectId() + " - using the init quote");
I try to enable logging at ALL or DEBUG or TRACE via JMX but still above log statement doesn't get printed. All statement without "isDebugEnabled()" get printed.
Any ideas what can be done to enable these log statements? I cannot change logback.xml and only use JMX to change log levels.
If I've understood you correctly, when you say "All statements without isDebugEnabled() get printed", you mean this gets printed:
LOG.debug("There is nothing in the cache for " + quote.getObject().getObjectId() + " - using the init quote");
but this doesn't:
if (LOG.isDebugEnabled())
LOG.debug("There is nothing in the cache for " + quote.getObject().getObjectId() + " - using the init quote");
That doesn't make sense, since LOG.debug() would internally do the equivalent of if (isDebugEnabled()). Therefore you should run your code through a debugger to find out what is going on.
If you mean that LOG.debug(...) does NOT get printed but other levels do, you should follow the link in #a_a's comment to set the level programmatically to Debug.

SonarQube: Invoke method(s) only conditionally

The following part of code raises a major bug at SonarQube :
"Invoke method(s) only conditionally."
How am I supposed to fix this?
if(us != null){
logger.info("Log this: {}", us.toString());
}
The call to us.toString() is redundant, toString() method will be called regardless the configured log level. You should pass only us as an argument to info without an if statement.
logger.info("Log this: {}", us);
As stated at the comments of the question, another working answer is:
if(logger.isInfoEnabled() && us != null){
logger.info("Log this: {}", us.toString());
}
You can just ignore this but it might be good to handle this scenario if possible, It would help us to handle and cutoff unnecessary computations.
One thing what it suggests here is to check if the Log Level that you are going to use is enabled or not.
if(logger.isInfoEnabled() && us != null){
// this inner code will only get executed if the above is true
logger.info("Log this: {}", us.toString());
}
Imagine having a complex task running inside, it would be a waste of time to do that if you are not going to log it anyways, if the log level is disabled. Logger will internally check that for you but doing it now before invoking the .info() will save you some cycles.
Passing message arguments that require further evaluation into a Guava com.google.common.base.Preconditions check can result in a performance penalty. That's because whether or not they're needed, each argument must be resolved before the method is actually called.
Similarly, passing concatenated strings into a logging method can also incur a needless performance hit because the concatenation will be performed every time the method is called, whether or not the log level is low enough to show the message.
Instead, you should structure your code to pass static or pre-computed values into Preconditions conditions check and logging calls.
Specifically, the built-in string formatting should be used instead of a string concatenation, and if the message is the result of a method call, then Preconditions should be skipped altogether, and the relevant exception should be conditionally thrown instead.
Noncompliant Code Example
logger.log(Level.DEBUG, "Something went wrong: " + message);
// Noncompliant; string concatenation performed even when log level too high to show DEBUG messages
logger.fine("An exception occurred with message: " + message);
// Noncompliant
LOG.error("Unable to open file " + csvPath, e); // Noncompliant
Preconditions.checkState(a > 0, "Arg must be positive, but got " + a);
// Noncompliant. String concatenation performed even when a > 0
Preconditions.checkState(condition, formatMessage()); // Noncompliant. formatMessage() invoked regardless of condition
Preconditions.checkState(condition, "message: %s", formatMessage());
// Noncompliant
Compliant Solution
logger.log(Level.SEVERE, "Something went wrong: {0} ", message);
// String formatting only applied if needed
logger.fine("An exception occurred with message: {}", message);
// SLF4J, Log4j
logger.log(Level.SEVERE, () -> "Something went wrong: " + message);
// since Java 8, we can use Supplier , which will be evaluated lazily
LOG.error("Unable to open file {0}", csvPath, e);
if (LOG.isDebugEnabled() {
LOG.debug("Unable to open file " + csvPath, e);
// this is compliant, because it will not evaluate if log level is above debug.
}
Preconditions.checkState(arg > 0, "Arg must be positive, but got %d", a); // String formatting only applied if needed
if (!condition) {
throw new IllegalStateException(formatMessage()); /
/ formatMessage() only invoked conditionally
}
if (!condition) {
throw new IllegalStateException("message: " + formatMessage());
}
Exceptions
catch blocks are ignored because the performance penalty is unimportant on exceptional paths (catch block should not be a part of standard program flow). Getters are ignored as well as methods called on annotations which can be considered as getters. This rule accounts for explicit test-level testing with SLF4J methods isXXXEnabled and ignores the bodies of such if statements.
It's related to performance issues. They recomend just putting a pure String or a final variable defined previously.
final var message = "Log this: " + us.toString();
logger.info(message);
https://sonarcloud.io/organizations/default/rules?languages=java&open=java%3AS2629&q=S2629
Short easy answer: just delete the .toString from your code since the formatter will take care of changing it to String for you.

Get formatted output from eclipse template variable

How can I make an eclipse java template that allows generating java code that eases the repeating part of registering code for a java method. Example:
Assume that the class description is like so:
class A{
public static void methodName(String s, int i, Object o) {
}
}
Now, what I want is to make a template that does something somewhat like this:
"${enclosing_type}.${enclosing_method}(" + ${variable1} + ", " + ${variable2} + ", " + ${variable3} + ")"
Given the available Eclipse variables I know, the idea would probably be:
"${enclosing_type}.${enclosing_method}(" + ${enclosing_method_arguments(" + \", \" + ")} + ")"
Where that argument would signal the glue to the join of each element of the enclosing_method_arguments. The result of the format would be:
"A.methodName(" + s + ", " + i + ", " + o + ")"
If there's an even better alternative, I'm open for suggestions.
This is meant to be used with a piece of code that is executed a LOT,
Unfortunately, String.format() (and related) "solution" is not an option here due to the requirement above and due to other inherited requirements with what I'm working on. It must generate that code in that format no matter what, unfortunately.
I'm open to any plugins that allow that and, if eclipse doesn't have it, I'm open to make a plugin myself... In case of me having to do a plugin please do show me the resources required to make it.
It should be possible to write a custom variable resolver. It is defined by org.eclipse.ui.editors.templates extension point
You could implement a custom resolver that points to Java context (its id is java defined in jdt.ui).
I don't know any plugins that would provide what you need out of the box.
If you are new to Eclipse plug-ins you might need to read the documentation on extending Eclipse. However, the task is really simple, so you should be able to do it after just a glimpse over the docs.

Categories

Resources