Drools logging with logback - drools

I'm using Drools 5.4.0.Final
For logging I'm using logback in my application.
I tried to add update my logback.xml with
<logger name="org.drools" level="debug"/>
But I see nothing in my logs concerning Drools.
I would expect to see so my lines of logs concerning the drools initialization.

You can pass the LOGGER to the StatefulKnowledgeSession
private static final Logger LOGGER = LoggerFactory.getLogger(Example.class);
private transient StatefulKnowledgeSession ksession;
.
.
.
ksession.setGlobal("logger", LOGGER);
and in your DRL file, you have to define global org.slf4j.Logger logger and then you can use the logger in your rules.

Drools 5.4.0.Final does not support any logging framework natively. The next version, Drools 5.5.0.Beta1, will. It will also be documented in the manual how to use it. See this issue for more info.
Drools 5.5.0.Beta1 will log to slf4j-api, so you can logback, log4j, jdk-logging, slf4j-simple, ... You still need to explicitly call KnowledgeRuntimeLoggerFactory.newConsoleLogger() and add that to the event listeners.

Related

Enable TRACE for a particular logger in ActiveMQ Artemis

How do I setup logging.properties to log diverts in artemis.log?
I understand that TRACE should be used for org.apache.activemq.artemis.core.server.impl.DivertImpl
How do I set it up in etc/logging.properties?
To enable a particular logger (e.g. org.apache.activemq.artemis.core.server.impl.DivertImpl) in logging.properties you must first add the logger to the loggers list at the top of the file. Here is the default loggers list with org.apache.activemq.artemis.core.server.impl.DivertImpl added:
loggers=org.eclipse.jetty,org.jboss.logging,org.apache.activemq.artemis.core.server,org.apache.activemq.artemis.utils,org.apache.activemq.artemis.journal,org.apache.activemq.artemis.jms.server,org.apache.activemq.artemis.integration.bootstrap,org.apache.activemq.audit.base,org.apache.activemq.audit.message,org.apache.activemq.audit.resource,org.apache.activemq.artemis.core.server.impl.DivertImpl
Then you need to configure the logging level for the logger to TRACE, e.g.:
logger.org.apache.activemq.artemis.core.server.impl.DivertImpl.level=TRACE
Lastly, you need to update the level of the necessary handler to allow the TRACE logging through, e.g.:
handler.CONSOLE.level=TRACE
or
handler.FILE.level=TRACE

spring-cloud-sleuth with opentracing

I'm using the latest milestone of spring-cloud-sleuth and I can't seem to get traces emitted through opentracing. I have a Tracer bean defined and spring boot seems to acknowledge that, but no traces are being emitted.
Is there a way to check if spring-cloud-sleuth is aware of the Tracer bean?
update
I did see the merged documentation and have a Tracer instance on the bean, as defined below:
#Bean(name = "tracer")
#Primary
public Tracer lightstepTracer() throws MalformedURLException {
Options opt = lightstepOptionsBuilder.build();
log.info("Instantiating LightStep JRETracer.");
return new JRETracer(opt);
}
I'm not explicitly importing the OpenTracing APIs, because the LightStep tracer pulls that in transitively, but I can try doing that.
I've also explicitly enabled OpenTracing support in my application.yml file.
sleuth:
opentracing:
enabled: true
If you go to the latest snapshot documentation (or milestone) and you search for the word OpenTracing, you would get your answer. It's here https://cloud.spring.io/spring-cloud-sleuth/single/spring-cloud-sleuth.html#_opentracing
Spring Cloud Sleuth is compatible with OpenTracing. If you have OpenTracing on the classpath, we automatically register the OpenTracing Tracer bean. If you wish to disable this, set spring.sleuth.opentracing.enabled to false
So it's enough to just have OpenTracing on the classpath and Sleuth will work out of the box

Using Actor Logging Via SLF4j and logback vs using org.slf4j to log using SLF4J and logback

I am confused with the best practice to use in logging. I found by reading that SLF4J removes the coupling between the application and logging API etc. So if i use actor logging, will it not be closely coupled to application?.I have also checked a lot of github codes and i noticed that they only use actor logging and not org.SLF4J.LoggerFactory logging. Why?
Some links which i referred
SACHA'S BLOG OF PROGRAMMATICALNESS
Another Good read
stack Overflow -> Checked the last answer
Thanks in advance
So we are in a new world, a world where we want to be reactive and non-blocking but some information before that.
Akka is using for logging SLF4j api that is a facade over common logging libraries i.e. log4j, logback, but does all of this async in order to not block actor.
So:
log.info("Received msg: {} use thread {} to dispatch", message, Thread.currentThread().getName());
in an actor where log is defined as:
LoggingAdapter log = Logging.getLogger(getContext().system(), this);
sends a logging message to logging actor, and the IO operations is actually done by this specialized actor.
Log4j or logback is only the implementation of actual logging, that's why you still need to configure one of if in your project.
log4j.appender.file.layout.ConversionPattern=[%d,%p] [%X{sourceThread}] [%c{1}.%M:%L] %m%n
%X{sourceThread} actually gives you the execution thread where the logging message was issued by original actor and not the thread that executes the IO operation inside logging actor (logged by %t) - more on this http://doc.akka.io/docs/akka/current/java/logging.html
My advice is to use log4j 2 since is using async operations and will not block the thread behind logging actor - more about log4j 2 performance on https://www.grobmeier.de/log4j-2-performance-close-to-insane-20072013.html

Resteasy Bean Validation Not Working on Remote Server

I have a problem similar to the one described here.
I am using RESTEasy within a standalone Jetty application. When I start the application locally and call a service (e.g. localhost:16880/rest/user/login) bean validation works fine, i.e. I get validation errors like this:
[PARAMETER]
[UserService#login(arg0).appKey]
[app_key may not be null or empty]
[]
However, when I deploy my application to a remote host and call the same service (e.g. remotehost:16880/rest/user/login) bean validation is not invoked at all.
I am using the #ValidateRequest annotation for the service and #Valid annotation for the bean parameter.
My Resteasy version is 3.0.13.Final, though I have tried earlier versions as well. I have tried to write my custom validator, but that didn't work either.
I am puzzled why the validation works locally, but not on remote server. Any suggestions would be highly appreciated.
Since you are using Jetty as standalone server, you have to define RESTEasy validation providers where you define ServletContextHandler. Note that in standalone server there is no container to scan for #Provider classes and to activate them, so you must do it manually.
I expect that you create and start your server app something like:
//create a server listening at some port
Server server= new Server(port);
//add server handlers
HandlerList handlers= new HandlerList();
initHandlers(handlers);
server.setHandler(handlers);
//start the server
server.start();
In initHandlers you must have defined your RESTEasy support:
public void initHandlers(List<HandlerList> handlers) {
//define root context handler
ServletContextHandler servletContextHandler= new ServletContextHandler(ServletContextHandler.SESSIONS);
servletContextHandler.setContextPath("/");
handlers.addHandler(servletContextHandler);
//define RESTEasy handler
ServletHolder restServlet= new ServletHolder(new HttpServlet30Dispatcher());
//since this is a standalone server, somewhere you have to define RESTful services and Singletons
restServlet.setInitParameter("javax.ws.rs.Application", "com.exampleapp.MyRestApplication");
restServlet.setInitParameter("resteasy.servlet.mapping.prefix", "rest");
servletContextHandler.addServlet(restServlet, "rest/*");
}
So what is left to do now is to add Validation provider as init parameter:
restServlet.setInitParameter("resteasy.providers", "org.jboss.resteasy.plugins.validation.ValidatorContextResolver,org.jboss.resteasy.api.validation.ResteasyViolationExceptionMapper");
On this link I tried to find the name of the validator providers: https://docs.jboss.org/resteasy/docs/3.0.4.Final/userguide/html/Validation.html
RESTEasy obtains a bean validation implemenation by looking in the available META-INF/services/javax.ws.rs.Providers files for an implementation of ContextResolver
So it does not say what, but says where. Now open the "resteasy-hibernatevalidator-provider-3...*.jar (from Eclipse -> Maven dependencies or manually unzip) and look into META-INF/services/javax.ws.rs.ext.Providers It says:
org.jboss.resteasy.plugins.validation.hibernate.ValidatorContextResolver
org.jboss.resteasy.api.validation.ResteasyViolationExceptionMapper
If you don't have this dependency, then add it to your pom file:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-hibernatevalidator-provider</artifactId>
<version>${resteasy.version}</version>
</dependency>
One more note: that at the same place where you described validation providers, you also add other providers, if you happen to need them (such as JacksonJaxbJson, etc).

how to write log4j-gwt messages into a file instead of console?

I am using log4j-gwt aud gwt's remote logging. I get the messages logged on my console as expected but did not managed to get the message print on my physical .log file.
Any idea of how I can do this?
Here is my log4j properties file (which works fine for all non-gwt related messages):
# CONSOLE APPENDER CONFIG [common] ---------------------------------------------------------------
log4j.appender.CONSOLE_APPENDER=org.apache.log4j.ConsoleAppender
#log4j.appender.CONSOLE_APPENDER.layout=org.apache.log4j.SimpleLayout
log4j.appender.CONSOLE_APPENDER.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE_APPENDER.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
# ROOT LOGGER CONFIG ----------------------------------------------------------------------
log4j.rootLogger=DEBUG,ROOT_FILE_APPENDER
log4j.appender.ROOT_FILE_APPENDER=org.apache.log4j.RollingFileAppender
log4j.appender.ROOT_FILE_APPENDER.File=C:/log/tbps_root.log
log4j.appender.ROOT_FILE_APPENDER.MaxFileSize=20480KB
log4j.appender.ROOT_FILE_APPENDER.MaxBackupIndex=5
log4j.appender.ROOT_FILE_APPENDER.layout=org.apache.log4j.PatternLayout
log4j.appender.ROOT_FILE_APPENDER.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
# GWT -------------------------------------------------------------------------------------
#These are various unseccsful attemps...
log4j.logger.com.google.gwt.logging.server.RemoteLoggingServiceUtil=DEBUG,ROOT_FILE_APPENDER
log4j.logger.com.google.gwt.logging.server.RemoteServiceServlet=DEBUG,ROOT_FILE_APPENDER
log4j.logger.com.google.gwt.logging.server.simpleRemoteHandler=DEBUG,ROOT_FILE_APPENDER
log4j.logger.com.google.gwt.logging=DEBUG,ROOT_FILE_APPENDER
log4j.logger.com.google.gwt.logging.Logging=DEBUG,ROOT_FILE_APPENDER
log4j.logger.com.google.gwt.logging.server=DEBUG,ROOT_FILE_APPENDER
GWT-log4j and GWT's RemoteLoggingService use different loggers, as described here. Hence, your log4j properties are not being applied to GWT's remote logger.
You can either implement your own remote logging class, or use slf4j to "bridge" the two loggers.
I recently added logs of the user's actions to a GWT application. I first tried using GWT-log4j in conjunction with RemoteLoggingService and had this same issue. After reading the above link I created my own logger class -- this was particularly nice as I could pass data objects to the remote logger allowing me to serialize the state of the GWT application. This later became very useful :)