Add jaeger trace id and span id to log4j2 logs - log4j2

I want to inject x-b3-traceid and x-b3-spanid in logs with pattern as shown-
property name="PATTERN" value="%h %l %u [%date{dd/MMM/yyyy:HH:mm:ss.SSS}] "%r" %s %b "%i{Referer}" "%i{User-Agent}" [trace=%responseHeader{X-B3-TraceId},span=%i{X-B3-SpanId}] %D"
For zipkins, there are libraries available like
brave-context-log4j2 –
(https://github.com/openzipkin/brave/tree/master/context/log4j2)
Spring cloud sleuth. (https://cloud.spring.io/spring-cloud-sleuth/)
How can I add that while using jaeger?

The best way to move forward in order to use Jaegar is NOT TO USE JAEGAR CLIENT! Jaegar has the ability to collect Zipkin spans.
https://www.jaegertracing.io/docs/1.8/getting-started/#migrating-from-zipkin
You should take advantage of this and use the below Sleuth+Zipkin dependency and exclude Jaegar agent jars in your spring boot app.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
The above will send Zipkin spans to http://localhost:9411 by default. You can override this in your Spring Boot app to point to your Jaegar server easily by overriding the zipkin base URL.
spring.zipkin.base-url=http://your-jaegar-server:9411
Sleuth will do all the heavy lifting and the default logging will log the span and traceIds.
In the log4j2.xml file, all you have to mention is
[%X]
I'll be uploading a working example of this approach into my GitHub and sharing the link.
EDIT 1:
You can find the sample code here:
https://github.com/anoophp777/spring-webflux-jaegar-log4j2

Related

How to add logs in RHPAM DMN?

I need help in RHPAM Business Central.
Anybody knows how to add any print statements or logs in DMN's for debugging DMN flow?
You can define your own DMNRuntimeEventListener.
The listener is usually wired in Drools library using: https://docs.drools.org/8.33.0.Final/drools-docs/docs-website/drools/DMN/index.html#dmn-properties-ref_dmn-models:~:text=org.kie.dmn.runtime.listeners.%24LISTENER_NAME
e.g.: with a configuration such as:
-Dorg.kie.dmn.runtime.listeners.mylistener=org.acme.MyDMNListener
or alternatively with analogous configuration in kmodule.xml
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<configuration>
<property key="org.kie.dmn.runtime.listeners.mylistener" value="org.acme.MyDMNListener"/>
</configuration>
</kmodule>
This latter option, is the one you might preference on RHPAM Business Central.
You might find helpful this tutorial: https://www.youtube.com/watch?v=WzstCC3Df0Q

How to override logging in dataflow with my logback.xml file?

We are trying to use our logback.xml that we use in GCP Cloud run which has amazing filtering features. Our logback.xml contains this for cloud run
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="com.orderlyhealth.api.logging.logback.GCPCloudLoggingJSONLayout">
<pattern>${CONSOLE_PATTERN}</pattern>
</layout>
</encoder>
</appender>
And our GCPCloudLoggingJSONLayout does a great job at setting all the things we need like clientId, customerRequestId, etc. etc. and we can filter across many many microservices on one customer or one customer request. We lose this in dataflow currently though. We tried adding logback.xml to src/main/resources and deploying the project seems to use it in the shell like so
{"message":"[main][-][:] o.a.b.r.d.DataflowRunner Template successfully created.\n",
"logger":"org.apache.beam.runners.dataflow.DataflowRunner",
"transactionId":null,"socket":null,"clntSocket":null,
"version":null,
"timestamp":{"seconds":1619694798,"nanos":4000000},
"thread":"main",
"severity":"INFO",
"instanceId":null,
"headers":{},
"messageInfo":{"message":"Message short enough. Displayed top level"}
}
thanks for any ideas on modifying dataflow logging.
Currently we see this instead which is not nearly as useful for tracing the customer request through systems
I don't think you can change how Dataflow logs to Cloud logging.
Instead, you can change how/what you log and let Dataflow pass them through to cloud logging. See Logging pipeline messages.
Or you can use cloud logging client libraries in your pipeline directly: https://cloud.google.com/logging/docs/reference/libraries.
Please take a look at How to override Google DataFlow logging with logback? for the latest version of this answer
I copied the current answer there to make it easier for folks who want to look:
Dataflow relies on using java.util.logging (aka JUL) as the logging backend for SLF4J and adds various bridges ensuring that logs from other libraries are output as well. With this kind of setup, we are limited to adding any additional details to the log message itself only.
This also applies to any runner executing a portable job since the container with the SDK harness has a similar logging configuration. For example Dataflow Runner V2.
To do this we want to create a custom formatter to apply to the root JUL logger. For example:
public class CustomFormatter extends SimpleFormatter {
public String formatMessage(LogRecord record) {
// implement whatever logic the is needed to add details to the message portion of the log statement
return super.formatMessage(record);
}
}
And then during start-up of the worker we need to update the root logger to use this formatter. We can achieve this using a JvmInitializer and implement the beforeProcessing method like so:
#AutoService(JvmInitializer.class)
public class LoggerInitializer implements JvmInitializer {
public void beforeProcessing(PipelineOptions options) {
LogManager logManager = LogManager.getLogManager();
Logger rootLogger = logManager.getLogger("");
for (Handler handler : rootLogger.getHandlers()) {
handler.setFormatter(new CustomFormatter());
}
}
}

Error when creation data source for neo4j in websphere application server

Im trying to create data source for neo4j in websphere application server but its failing to connect. Any pointers on this would be helpful.
JDBC Driver Created with the following parameters:
Name : neo4j Driver
Class path : path of the neo4j jdbc jar/neo4j-jdbc-driver-3.3.1.jar
Implementation class name : org.neo4j.jdbc.Driver
Data source created with the following :
jndi Name: jdbc/neo4j
Custom Properties:
auth : container
type: javax.sql.DataSource
username: neo4j
password: password
url:jdbc:neo4j:bolt://localhost:port
removeAbandonedOnBorrow : true
closeMethod : close
The properties are added based on the pointers provided in https://github.com/neo4j-contrib/neo4j-jdbc
Here is the error from logs:
java.lang.Exception: DSRA8101E: DataSource class cannot be used as
one-phase: ClassCastException: org.neo4j.jdbc.bolt.BoltDriver
incompatible with javax.sql.ConnectionPoolDataSource [5/27/19
13:12:41:533 UTC] 00000111 SystemErr R at
com.ibm.ws.rsadapter.AdapterUtil.createDataStoreAdapterException(AdapterUtil.java:441)
[5/27/19 13:12:41:533 UTC] 00000111 SystemErr R at
com.ibm.ws.rsadapter.DSConfigHelper.getPooledConnection(DSConfigHelper.java:1340)
According to its documentation Neo4j is NOT a compliant JDBC driver.
We cover these aspects of the JDBC-APIs, everything that’s not
explicitely mentioned should be assumed to be not implemented
It also doesn't implement required javax.sql.DataSoruce interface, so it cannot be configured in the server. You will need to handle it in the application code.
To clarify for others who may find this post in the future - whether or not it is possible to directly configure to java.sql.Driver depends on whether WebSphere Application Server traditional vs Liberty is being used.
A more indirect approach is possible in WebSphere Application Server traditional, which involves mocking up a ConnectionPoolDataSource class around the driver. It is discussed under a related stack overflow post.
With Liberty 18.0.0.3 and above, it is possible to directly configure a dataSource specifying only the URL, with examples given under this knowledge center document.
Here is an example dataSource configuration in Liberty,
<featureManager>
<feature>jdbc-4.2</feature>
<feature>jndi-1.0</feature>
... other features
</featureManager>
<dataSource jndiName="jdbc/neo4j" containerAuthDataRef="neo4jAuth">
<jdbcDriver libraryRef="neo4j"/>
<properties URL="jdbc:neo4j:bolt://localhost:7687"/>
</dataSource>
<authData id="neo4jAuth" user="neo4j" password="password"/>
<library>
<file name="C:/drivers/neo4j/neo4j-jdbc-driver-3.3.1.jar"/>
</library>

Cannot set pagecache size with embedded Neo4J/Gremlin

I am writing a Java program that uses an embedded Neo4j graph with TinkerPop. Here's the relevant section of my pom
<dependency>
<groupId>org.apache.tinkerpop</groupId>
<artifactId>neo4j-gremlin</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-tinkerpop-api-impl</artifactId>
<version>0.7-3.2.3</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-tinkerpop-api</artifactId>
<version>0.1</version>
</dependency>
I want to add a configuration option to set the page cache size when initializing the graph. My PS Old Gen heap space is filling up.
Currently, I'm opening the Neo4j graph by passing it a org.apache.commons.configuration.Configuration object. I’m trying to set two properties, the directory and the pagecache. When I run my program, the "gremlin.neo4j.directory" property is processed, but the "dbms.memory.pagecache.size" is not, according to the graph's log file. The log file's first line is this:
2019-03-20 14:38:36.155+0000 WARN [o.n.i.p.PageCache] The
dbms.memory.pagecache.size setting has not been configured. It is
recommended that this setting is always explicitly configured, to
ensure the system has a balanced configuration. Until then, a computed
heuristic value of 8310519808 bytes will be used instead.
Using jvisualvm and jconsole, I can see that the memory in the PS Old gen is filling up with objects related to page caching so I'm trying to throttle how much data is cached by Neo4j.
Here's my code:
Configuration configuration = new BaseConfiguration();
configuration.addProperty("gremlin.neo4j.directory", "tmp/mygraph");
configuration.addProperty("dbms.memory.pagecache.size", "500m");
myGraph = Neo4jGraph.open(configuration);
Any idea what I'm doing wrong?
I think that you need to prefix your configuration keys that are Neo4j specific with gremlin.neo4j.conf thus:
Configuration configuration = new BaseConfiguration();
configuration.addProperty("gremlin.neo4j.directory", "tmp/mygraph");
configuration.addProperty("gremlin.neo4j.conf.dbms.memory.pagecache.size", "500m");
myGraph = Neo4jGraph.open(configuration);

How do I set up a wicket quickstart to use seam-wicket CDI?

What do I need to do to make CDI work on my wicket quickstart project? When I try to launch the Jetty server, I get an exception:
org.jboss.seam.solder.beanManager.BeanManagerUnavailableException: Failed to locate BeanManager using any of these providers: org.jboss.seam.solder.beanManager.DefaultJndiBeanManagerProvider(11), org.jboss.seam.solder.beanManager.ServletContainerJndiBeanManagerProvider(10)
at org.jboss.seam.solder.beanManager.BeanManagerLocator.getBeanManager(BeanManagerLocator.java:91)
at org.jboss.seam.wicket.SeamApplication.internalInit(SeamApplication.java:54)
at org.apache.wicket.protocol.http.WicketFilter.init(WicketFilter.java:723)
...
I am authoring a wicket project. I don't know the first thing about Seam, Weld, or CDI; I want to learn it by incorporating it into a small project. I am following this reference documentation:
http://docs.jboss.org/seam/3/wicket/latest/reference/en-US/html_single/
Right now, I am swimming in a sea of alien documentation trying to find the answer. Help!
Edit:
The Jetty server in the wicket quickstart is created programmatically. Based on the documentation given below, I created:
webapp/WEB-INF/jetty-env.xml:
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN"
"http://jetty.mortbay.org/configure.dtd">
<Configure id="webAppCtx" class="org.mortbay.jetty.webapp.WebAppContext">
<New id="BeanManager" class="org.mortbay.jetty.plus.naming.Resource">
<Arg><Ref id="webAppCtx"/></Arg>
<Arg>BeanManager</Arg>
<Arg>
<New class="javax.naming.Reference">
<Arg>javax.enterprise.inject.spi.BeanManager</Arg>
<Arg>org.jboss.weld.resources.ManagerObjectFactory</Arg>
<Arg/>
</New>
</Arg>
</New>
</Configure>
In web.xml, I have added the following snippet:
<resource-env-ref>
<resource-env-ref-name>BeanManager</resource-env-ref-name>
<resource-env-ref-type>
javax.enterprise.inject.spi.BeanManager
</resource-env-ref-type>
</resource-env-ref>
<listener>
<listener-class>org.jboss.seam.solder.resourceLoader.servlet.ResourceListener</listener-class>
</listener>
The following Java code is responsible for setting up the Jetty server in the quickstart environment, when Start is run:
Server server = new Server();
SocketConnector connector = new SocketConnector();
// Set some timeout options to make debugging easier.
connector.setMaxIdleTime(1000 * 60 * 60);
connector.setSoLingerTime(-1);
connector.setPort(8080);
server.setConnectors(new Connector[] { connector });
WebAppContext bb = new WebAppContext();
bb.setServer(server);
bb.setContextPath("/");
bb.setWar("src/main/webapp");
// FIXME: This doesn't seem to do anything? bb.addEventListener(new ResourceListener());
server.addHandler(bb);
/* I don't know what this commented code does, but it doesn't fix the problem when uncommented. */
// START JMX SERVER
// MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
// MBeanContainer mBeanContainer = new MBeanContainer(mBeanServer);
// server.getContainer().addEventListener(mBeanContainer);
// mBeanContainer.start();
I am using jetty version 6.1.25, according to my Maven Dependencies.
The 42Lines folks have published a Wicket-CDI integration library that includes a working example project.
Several of these guys are actually Wicket committers; they write good code, and they know what they're doing.
In a servlet container you need to bootstrap Weld CDI yourself to make it available to Seam. The documentation states this under installation:
http://docs.jboss.org/seam/3/wicket/latest/reference/en-US/html_single/#wicket.installation
With a link to the relative Weld bootstrapping documentation for either Jetty 6 or 7:
http://docs.jboss.org/weld/reference/latest/en-US/html/environments.html#d0e5286
It should work fine after configuring Jetty to bootstrap Weld. However please take not of the limitations of using Weld within a servlet container:
http://docs.jboss.org/weld/reference/latest/en-US/html/environments.html#d0e5221
Also ensure that you have an empty (or configured) beans.xml in your WEB-INF/ directory.

Resources