Log4J2 StatusLogger messages are not logged in ODL - log4j2

I have recently upgraded log4j2 in my application. It is running on top of the open day light controller. The pax-logging-log4j2 (version 1.11.3) bundle is added to the karaf start up bundles. With Log4J2, I have enabled the asynchronous logging as well. The below VM argument is added in the karaf start up script for enabling asynchronous logging.
-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
-DAsyncLogger.WaitStrategy=Sleep
Application logging is working as expected but sometimes, the logs are not in order (timestamps are overlapped). To resolve this, I have tried to set AsyncQueueFullPolicy to ENQUEUE and RingBufferSize to 4098*1024 but no luck.
-Dlog4j2.AsyncQueueFullPolicy=Enqueue
-DAysncLogger.RingBufferSize=4194304
Tried to enable Log4J2 status logger (as like below) but the logs are not getting logged.
status=debug is added the "org.ops4j.apache.pax.logging.cfg" file.
Couple of issues, log4j2 status logger is not logged and application logs are not in order.
Any help here would be of great help.
EDIT:
Further analysis of the status logger shows asynchronous logging is reverted to synchronous with reason "com.lmax.disruptor.EventFactory cannot be found".
org.ops4j.pax.logging.pax-logging-api [log4j2] WARN : Asynchronous loggers defined, but the disruptor library is not available. Reverting to synchronous loggers. Ignored FQCN: org.apache.logging.log4j.spi.AbstractLogger
java.lang.ClassNotFoundException: com.lmax.disruptor.EventFactory cannot be found by org.ops4j.pax.logging.pax-logging-log4j2_1.11.3
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:439)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:352)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:344)
at org.eclipse.osgi.internal.loader.ModuleClassLoader.loadClass(ModuleClassLoader.java:160)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.ops4j.pax.logging.log4j2.internal.PaxLoggingServiceImpl.updated(PaxLoggingServiceImpl.java:263)
at org.ops4j.pax.logging.log4j2.internal.PaxLoggingServiceImpl$1ManagedPaxLoggingService.updated(PaxLoggingServiceImpl.java:581)
at org.apache.felix.cm.impl.helper.ManagedServiceTracker.updated(ManagedServiceTracker.java:189)
at org.apache.felix.cm.impl.helper.ManagedServiceTracker.updateService(ManagedServiceTracker.java:152)
at org.apache.felix.cm.impl.helper.ManagedServiceTracker.provideConfiguration(ManagedServiceTracker.java:85)
at org.apache.felix.cm.impl.ConfigurationManager$ManagedServiceUpdate.provide(ConfigurationManager.java:1463)
at org.apache.felix.cm.impl.ConfigurationManager$ManagedServiceUpdate.run(ConfigurationManager.java:1419)
at org.apache.felix.cm.impl.UpdateThread.run0(UpdateThread.java:141)
at org.apache.felix.cm.impl.UpdateThread.run(UpdateThread.java:109)
at java.lang.Thread.run(Thread.java:748)
Added "pax-logging-log4j2-extra" in startup.properties and the dependency issues are resolved.
AsyncLoggerContext is created now.
org.ops4j.pax.logging.pax-logging-api [log4j2] DEBUG : Starting LoggerContext[name=pax-logging, org.apache.logging.log4j.core.async.AsyncLoggerContext#1eb9a021] with configuration org.apache.logging.log4j.core.config.properties.PropertiesConfiguration#3810215b... Ignored FQCN: org.apache.logging.log4j.spi.AbstractLogger
but it is not picking the custom AsyncQueueFullPolicy added in the VM argument.
-Dlog4j2.AsyncQueueFullPolicy=a.b.c.d.BlockingQueueFullPolicy
Logs:
org.ops4j.pax.logging.pax-logging-api [log4j2] DEBUG : Using DefaultAsyncQueueFullPolicy. Could not create custom AsyncQueueFullPolicy 'a.b.c.d.BlockingQueueFullPolicy': java.lang.ClassNotFoundException: com.fujitsu.fnc.sdnfw.async.BlockingQueueFullPolicy cannot be found by org.ops4j.pax.logging.pax-logging-api_1.11.3 Ignored FQCN: org.apache.logging.log4j.spi.AbstractLogger
Created a fragment bundle with the below custom policy and installed it in karaf.
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.async.AsyncQueueFullPolicy;
import org.apache.logging.log4j.core.async.EventRoute;
public class BlockingQueueFullPolicy implements AsyncQueueFullPolicy {
public BlockingQueueFullPolicy() {
// Don't Delete. Default constructor is required
}
#Override
public EventRoute getRoute(long backgroundThreadId, Level level) {
return EventRoute.ENQUEUE;
}
}
and pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>a.b.c.d.fw-async-policy-api</Bundle-SymbolicName>
<Bundle-Name>Custom Async Queue Full Policy API</Bundle-Name>
<Bundle-Vendor>XYZ</Bundle-Vendor>
<Bundle-ActivationPolicy>eager</Bundle-ActivationPolicy>
<Embed-Transitive>
false
</Embed-Transitive>
<Export-Package>
a.b.c.d
</Export-Package>
<Fragment-Host>system.bundle; extension:=framework</Fragment-Host>
<Import-Package>*</Import-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.slf4j.impl.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.slf4j.impl.version}</version>
</dependency>
</dependencies>

Related

How to set log level in QAF / Qmetry framework?

I would like to reduce the log level displayed in the console during my automation run in QAF / QMetry framework. When I tried playing around in log4j.properties, it is not showing any difference in the console logging. Tried following in log4j.properties:
log4j.logger.com.qmetry.qaf=ERROR
log4j.rootCategory=off
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=ERROR
log4j.appender.CONSOLE.Follow=false
Note: Not seeing any ws.log file created as mentioned in the below property
log4j.logger.com.qmetry.qaf.automation.ws=DEBUG, file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.file=${outputDir}/ws.log
log4j.appender.file.MaxFileSize=1GB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.conversionPattern=%d{[dd.MM.yyyy] [HH:mm:ss]} %p [%t] %c (%F:%L) - %m%n
Log4j is set in the Maven config: (I have also tried putting the log4j config in the src folder).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.9</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>${testSuiteFile}</suiteXmlFile>
</suiteXmlFiles>
<reportsDirectory>${test.results.dir}/${run.time}</reportsDirectory>
<systemPropertyVariables>
<org.uncommons.reportng.xml-dialect>testng</org.uncommons.reportng.xml-dialect>
<org.uncommons.reportng.escape-output>false</org.uncommons.reportng.escape-output>
<log4j.configuration>file:///${resource.dir}/log4j.properties</log4j.configuration>
<outputDir>${output.dir}</outputDir>
<test.results.dir>${output.dir}/html</test.results.dir>
<json.report.root.dir>${test.results.dir}</json.report.root.dir>
<json.report.dir>${output.dir}/json</json.report.dir>
<selenium.screenshots.dir>${output.dir}/img</selenium.screenshots.dir>
<selenium.screenshots.relative.path>../img</selenium.screenshots.relative.path>
</systemPropertyVariables>
</configuration>
</plugin>
You need to set log4j properties file location. Refer sample ant or maven project. If you are not familiar, easiest way is to move log4j.properties file under src directory.

Using Jasypt to secure spring boot database password, but received error

This is what i did with Jasypt for springboot:
i have confiured my maven dependency as follows:
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.2</version>
</dependency>
then i have configured my application.properties
(java -cp jasypt-1.9.3.jar
org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="mypassword"
password=123 algorithm=PBEWithMD5AndDES):
spring.datasource.password=ENC(YZ2Lt/juEKhtYIIGNNdm7gmy9p0xrFM7)
jasypt.encryptor.password=123
jasypt.encryptor.algorithm=PBEWithMD5AndDES
when i run my application i've got this:
Failed to bind properties under 'spring.datasource.password' to
java.lang.String:
Reason: Failed to bind properties under 'spring.datasource.password'
to java.lang.String
Action: Update your application's configuration
Anyone have any idea why this is happening? did i miss anything? Thanks in advance!

Using a property from one property file into log4j2 properties file

I have one properties file, let's say abc.properties and a log4j2.properties file. I am unable to access the logs.dir property which is present in abc.properties file into log4j2.properties file. This is done in order to switch the log file location based on different environment. Thanks.
If abc.properties and log4j2.properties configuration file are on the same directory then access logs.dir using below way in log4j2.properties file -
property.fileName=${bundle:abc:logs.dir}
Adding more details about environment as asked in comments -
Project Structure - A simple Maven project.
Dependency - I tried with version log4j2 version 2.8.2 , below are dependencies in pom.xml -
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
Content of abc.properties -
logs.dir = ./logs/abcfile.log
Relevant content of log4j2 -
appender.rolling.type = RollingFile
appender.rolling.name = fileLogger
appender.rolling.fileName=${bundle:abc:logs.dir}
appender.rolling.filePattern=${basePath}app_%d{yyyyMMdd}.log.gz
As you can see in screenshot also, logs are getting generated on the path specified in abc.properties file.

How to Inject SessionContext in arquillian embedded container for wildfly 8.2

My wildfly server not running after adding the line
#Resource
private SessionContext sessionContext;
How to inject Session Context in embeded arquillian with wildfly 8.2 version???
I even tried to add the line
.addAsWebInfResource(new File("D:\wildfly-.2.0.Final\domain\configuration\domain.xml"))
mentioning the domain.xml of my wildfly server where I have crated users. but again not able to start the server. Also when I remove the line of injecting SessionContext my server starts normally.
#RunWith(Arquillian.class)
public class CRLManagerTest {
private static final Logger LOGGER = LoggerFactory.getLogger(CRLManagerTest.class);
#Deployment
public static WebArchive createDeployment() {
WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "test.war")
.addClass(CrManagerFacade1.class)
.addClass(SessionContext.class)
.addClass(CrManagerFacade.class)
.addClass(CrManager.class)
.addAsResource("META-INF/persistence.xml", "META-INF/persistence.xml")
.addAsWebInfResource(new File("D:\\wildfly-.2.0.Final\\domain\\configuration\\domain.xml"))
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml") .addAsManifestResource("META-INF/persistence.xml", "persistence.xml") .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")
;
return webArchive;
}
#Resource
private SessionContext sessionContext;
#Test
public void testUpdateReceipt1() throws Exception {
LOGGER.info(">>>>>>>>>>>>> This is a test");
Assert.assertEquals("hello","hello");
}
Here is my arquillian.xml
<container qualifier="jboss-managed" default="true">
<configuration>
<property name="jbossHome">${jbossHome}</property>
</configuration>
</container>
Looks like you're not using the Servlet protocol, so Arquillian isn't doing an http request, which would mean nothing that relies on a servlet or anything in the Request / Session would be available. Wildfly does not use the servlet protocol by default so you need to enable it.
Add this to your arquillian.xml:
<!-- Sets the protocol which is how Arquillian talks and executes the tests inside the container -->
<defaultProtocol type="Servlet 3.0" />
And this to your pom.xml:
<dependency>
<groupId>org.jboss.arquillian.protocol</groupId>
<artifactId>arquillian-protocol-servlet</artifactId>
<scope>test</scope>
</dependency>
The correct answer is to add classess to ShrinkWrat.create method.
.addClasses(CRLManagerTest.class, CrManagerFacade.class,
CrManager.class)

Tapestry getting started

All goes OK until mvn jetty:run which ends with [ERROR] Failed to execute goal org.mortbay.jetty:maven-jetty-plugin:6.1.16:run (default-cli) on project newapp: Failure: Address already in use: bind
That is no surprise as I have Tomcat running on 8080 with my own site (that can not be changed). Did mvn indeed install jetty and tries running it? May I configure Jetty to a different port or maybe use Tomcat instead?
You can configure Jetty to use another port by setting the system property jetty.port.
The jetty.port property can be set in the command line when running Maven:
mvn -Djetty.port=9090 jetty:run
Or it can be set in the project's pom.xml, as part of the maven-jetty-plugin configuration:
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.16</version>
<configuration>
<systemProperties>
<systemProperty>
<name>tapestry.execution-mode</name>
<value>development</value>
</systemProperty>
<systemProperty>
<name>jetty.port</name>
<value>9090</value>
</systemProperty>
</systemProperties>
</configuration>
</plugin>
In both examples Jetty is configured to listen to port 9090.

Resources