here is the current logging which I am seeing in Server:
12:40:10,190 | INFO | -549263035-19951 | ServiceImpl | Upload started
12:40:12,912 | INFO | -549263035-19960 | ServiceImpl | Upload started
12:40:12,915 | INFO | -549263035-19958 | ServiceImpl | Upload started
My application is using log4j to implement logging. here is the log4j.properties file which is sitting inside META-INF.
log4j.rootCategory=DEBUG, O
log4j.appender.O=org.apache.log4j.ConsoleAppender
log4j.appender.O.layout=org.apache.log4j.PatternLayout
log4j.appender.O.layout.ConversionPattern=[%d{ISO8601}]%5p%6.6r[%t]%x - %C.%M(%F:%L) - %m%n
As we can clearly see, current logging has the time information for every event. I wanted to know if there is a way I could make some changes in this properties file or elsewhere to include the full timestamp i.e. Date and time both.
something like :
2013-07-18 12:40:12 | INFO | -549263035-19958 | ServiceImpl | Upload started
Thanks for suggestion.
Found my answer.
this application was deployed in Servicemix container. Apparantly inside servicemix's installation directory I found this configuration file.
"/usr/local/servicemix/etc/org.ops4j.pax.logging.cfg".
Inside this file, there was a SiftingAppender which was using %d[ABSOLUTE] as a conversion pattern. So basically every bundle which is deployed under servicemix is going to use this "siftingappender" properties. I just removed [ABSOLUTE] from this configuration file and started getting the Date in my logs.
Related
EDIT: To clarify the question, I added many explanations.
In my project dependencies, I have both slf4j and log4j. This can't be changed for some technical reason.
>gradlew dependencies
Starting a Gradle Daemon, 1 incompatible and 1 stopped Daemons could
not be reused, use --status for details
> Task :dependencies
.
.
| | | +--- org.springframework.boot:spring-boot-starter-logging:2.5.7
| | | | +--- ch.qos.logback:logback-classic:1.2.7
| | | | | +--- ch.qos.logback:logback-core:1.2.7
| | | | | \--- org.slf4j:slf4j-api:1.7.32
| | | | +--- org.apache.logging.log4j:log4j-to-slf4j:2.14.1
| | | | | +--- org.slf4j:slf4j-api:1.7.25 -> 1.7.32
| | | | | \--- org.apache.logging.log4j:log4j-api:2.14.1 -> 2.17.0
| | | | \--- org.slf4j:jul-to-slf4j:1.7.32
| | | | \--- org.slf4j:slf4j-api:1.7.32
.
.
+--- org.apache.logging.log4j:log4j-core:2.17.0
| \--- org.apache.logging.log4j:log4j-api:2.17.0
+--- org.apache.logging.log4j:log4j-api:2.17.0
BUILD SUCCESSFUL in 16s
1 actionable task: 1 executed
I want to set the log level in the code, and AFAIK that can only be done with log4j. As a result, I simply look for a way to make this code line (LogManager is part of log4j) returns log4j implementation and not slf4j implementation:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
.
.
private final Logger logger = LogManager.getLogger(getClass());
Sadly, the logger's class returns is org.apache.logging.slf4j.SLF4JLogger:
System.out.println("logger class is: [" + logger.getClass() + "]");
output:
logger class is: [class org.apache.logging.slf4j.SLF4JLogger]
Even though it sounds easy, I haven't been able to do it or find an example online. What can be done?
Log4j 2.x Core and the Log4j to SLF4J Adapter are two implementations of the Log4j 2.x API. If they are both present on the classpath log4j-to-slf4j is used. That is what happens in your case: messages logged using the Log4j 2.x API are sent to SLF4J, which sends them to Logback.
That is the standard logging configuration brought by the spring-boot-starter-logging. If you want to use Log4j 2 as backend instead you need to exclude that artifact and add spring-boot-starter-log4j2.
Anyway, since you are using Spring Boot, you have two ways to set the level of a logger:
Using Spring Boot's LoggingSystem abstraction (works for all available logging systems):
final LoggingSystem loggingSystem = LoggingSystem.get(getClass().getClassLoader());
loggingSystem.setLogLevel("loggerName", LogLevel.DEBUG);
Using the underlying logging system. In your case it is Logback, so you should use:
final Logger logger = LoggerFactory.getLogger("loggerName");
if (logger instanceof ch.qos.logback.classic.Logger) {
((ch.qos.logback.classic.Logger) logger).setLevel(Level.DEBUG);
}
Remark: due to recent vulnerabilities in both Log4j and Logback, you should bump your version of Spring Boot to 2.5.8 (or 2.6.2).
Whats the full class path of LogManager? It has to be imported, there you should see the full class.
My guess is that you need to change the Import to import some log4j LogManager, not the slf4j one.
I am using Camel 2.17.3 and karaf 4.0.7 (also tried 4.0.1).
I have a Camel route that runs fine in Eclipse when a junit test starts it, but hangs when deployed to karaf. If I change the amqp: 'from' component to timer: the route runs fine in karaf.
My AMQP setup in the routebuilder is:
#Override
public void configure() throws Exception {
getContext().addComponent("amqp", AMQPComponent.amqpComponent(String.format("amqp://%s:%s?amqp.saslMechanisms=ANONYMOUS", AMQP_SERVICE_HOST, AMQP_SERVICE_PORT)));
Even this route will hang karaf, and run fine in Eclipse:
from("amqp:queue:myqueue").routeId("myRoute")
.log("temp")
In Karaf, when I say "hang", I observe these things:
If I try to exit karaf, it hangs - I need to kill the process.
If I try to stop the bundle, karaf hangs - I need to kill the process.
Neither camel:context-list nor camel:route-list return anything
I do not get a "route consuming from..." message in the log. This is all
the output from starting the bundle:
2016-10-08 23:46:00,593 | INFO | nsole user karaf | bundle
| 90 - org.apache.aries.spifly.dynamic.bundle - 1.0.1 | Bundle
Considered for SPI providers: mis-routes 2016-10-08 23:46:00,593 |
INFO | nsole user karaf | bundle | 90 -
org.apache.aries.spifly.dynamic.bundle - 1.0.1 | No 'SPI-Provider'
Manifest header. Skipping bundle: mis-routes 2016-10-08 23:46:05,595 |
INFO | ool-130-thread-1 | OsgiDefaultCamelContext | 56 -
org.apache.camel.camel-core - 2.17.3 | Apache Camel 2.17.3
(CamelContext: mis-routes) is starting 2016-10-08 23:46:05,599 | INFO
| ool-130-thread-1 | OsgiDefaultCamelContext | 56 -
org.apache.camel.camel-core - 2.17.3 | MDC logging is enabled on
CamelContext: mis-routes 2016-10-08 23:46:05,601 | INFO |
ool-130-thread-1 | ManagedManagementStrategy | 56 -
org.apache.camel.camel-core - 2.17.3 | JMX is enabled 2016-10-08
23:46:05,708 | INFO | ool-130-thread-1 |
DefaultRuntimeEndpointRegistry | 56 - org.apache.camel.camel-core -
2.17.3 | Runtime endpoint registry is in extended mode gathering usage statistics of all incoming and outgoing endpoints (cache limit: 1000)
2016-10-08 23:46:05,804 | INFO | ool-130-thread-1 |
OsgiDefaultCamelContext | 56 - org.apache.camel.camel-core -
2.17.3 | AllowUseOriginalMessage is enabled. If access to the original message is not needed, then its recommended to turn this option off as
it may improve performance. 2016-10-08 23:46:05,805 | INFO |
ool-130-thread-1 | OsgiDefaultCamelContext | 56 -
org.apache.camel.camel-core - 2.17.3 | StreamCaching is not in use. If
using streams then its recommended to enable stream caching. See more
details at http://camel.apache.org/stream-caching.html
Any help would be hugely appreciated. Thanks!
The reason should be related to this issue in Camel JIRA: https://issues.apache.org/jira/browse/CAMEL-10278
The main problem is proton-j 0.10 is incompatible with qpid-jms-client version 0.8. We upgraded the dependency to proton-j 0.12.0 and the fix will be available in the Camel 2.17.4 release.
For the moment you can use Camel 2.17.4-SNAPSHOT or upgrade the dependency in the Camel-Amqp Karaf feature.
I'm currently developing a Java DSL route, which will fetch a message from a JMS queue, process it, and put it in a database using JPA. Fairly simple really:
public void configure() {
from("{{ribMessage.source}}")
.split(xpath("/RibMessages/*"))
.streaming()
.process(new RibMessageToEntityProcessor())
.to("{{ribMessage.destination}}");
}
As you can see, I'm trying to use camel properties here, which I have defined in a properties file on my classpath:
ribMessage.source=activemq:queue:in.item_q
ribMessage.destination=jpa:com.axstores.aim.entities.XMLImport
The properties file is defined in spring like so:
<bean id="properties" class="org.apache.camel.component.properties.PropertiesComponent">
<property name="location" value="classpath:ribmessage.properties"/>
</bean>
I've updated the activemq config to include a camel.xml, and I've added my route package to the ActiveMQ camel.xml. And during startup, ActiveMQ is finding my route, but then it looks like it isn't able to find my property, and looks up URI {{ribMessage.source}} instead. This fails of course, and the next line in the log says that Camel is shutting down.
2014-02-01 23:31:20,278 | DEBUG | Searching for implementations of org.apache.camel.RoutesBuilder in packages: [com.axstores.aim] | org.apache.camel.impl.DefaultPackageScanClassResolver | main
2014-02-01 23:31:20,374 | DEBUG | Found: [class com.axstores.aim.routes.RibMessageToAimRoute] | org.apache.camel.impl.DefaultPackageScanClassResolver | main
...
2014-02-01 23:46:52,410 | TRACE | Starting service | org.apache.camel.support.ServiceSupport | main
2014-02-01 23:46:52,414 | TRACE | Getting endpoint with uri: {{ribMessage.source}} | org.apache.camel.spring.SpringCamelContext | main
2014-02-01 23:46:52,416 | INFO | Apache Camel 2.12.1 (CamelContext: camel) is shutting down | org.apache.camel.spring.SpringCamelContext | main
I suspect that I'm missing something in my config, because it seems to me like my spring config file is not being read at all.
Any clues? More info needed?
Full log for reference
Spring config
You need to add the camel-jpa component JAR to the classpath of the ActiveMQ broker. And as well what additional JARs you may need for JPA such as the JPA implementation and JDBC drivers and whatnot.
So with some help from the Claus and Peter gave, and some trial and error, I was finally able to get going ActiveMQ up and running, with my routes.
There was one major thing I missed in my config, which basically screwed up everything else. Active MQ was able to find my route through the config, but it still didn't seem to load my spring config.
I finally figured out that I had to add the following import statement to my ActiveMQ camel.xml, in order for it to load the spring config from my jar file.
<import resource="classpath:META-INF/spring/camel-context.xml"/>
Adding this allowed ActiveMQ to resolve my ribmessage.properties, as Peter mentioned in a comment above, this was not being done at all initially. This also loaded my JPA config, which revealed a bunch of missing jars, as Claus pointed out in the comment above.
For this project I'm using EclipseLink and Oracle 11g, so besides camel-jpa, I also had to add the follwing jars to the ActiveMQ classpath:
ojdbc7-12.1.0.1.jar
eclipselink-2.5.1.jar
spring-orm-3.2.4.RELEASE.jar
persistence-api-1.0.jar
spring-jdbc-3.2.4.RELEASE.jar
Hopefully someone can benefit from my (in)experiences.
I really only discovered Camel one week ago, and it seems to be an awesome framework for building integrations :-)
Below is the error from the log that i see after starting the service... can you help resolving this issue.
2013-08-22 10:35:37,111 | DEBUG | l Console Thread | AbstractServiceReferenceRecipe | r.AbstractServiceReferenceRecipe 143 | 7 - org.apache.aries.blueprint.core - 1.1.0 | Found initial references null for OSGi service (&(&(org.apache.aries.jpa.proxy.factory=true)(osgi.unit.name=tenant))(objectClass=javax.persistence.EntityManagerFactory))
2013-08-22 10:35:37,111 | DEBUG | l Console Thread | BlueprintContainerImpl | container.BlueprintContainerImpl 280 | 7 - org.apache.aries.blueprint.core - 1.1.0 | Running blueprint container for bundle com.igt.arcus.framework.jta.arcus-framework-feature-service in state WaitForInitialReferences
2013-08-22 10:35:37,111 | INFO | l Console Thread | BlueprintContainerImpl | container.BlueprintContainerImpl 344 | 7 - org.apache.aries.blueprint.core - 1.1.0 | Bundle com.igt.arcus.framework.jta.arcus-framework-feature-service is waiting for dependencies [(&(&(org.apache.aries.jpa.proxy.factory=true)(osgi.unit.name=tenant))(objectClass=javax.persistence.EntityManagerFactory))]
2013-08-22 10:35:37,112 | DEBUG | l Console Thread | BlueprintEventDispatcher | ntainer.BlueprintEventDispatcher 136 | 7 - org.apache.aries.blueprint.core - 1.1.0 | Sending blueprint container event BlueprintEvent[type=GRACE_PERIOD, dependencies=[(&(&(org.apache.aries.jpa.proxy.factory=true)(osgi.unit.name=tenant))(objectClass=javax.persistence.EntityManagerFactory))]] for bundle com.igt.arcus.framework.jta.arcus-framework-feature-service
In case you use Aries JPA you should see two EntityManagerFactory services:
jpa-container picks up your bundle with the persistence.xml and creates an Entity manager factory
jpa-container-context picks up every EntityManagerFactory service and makes a new managed EntityManagerFactory service with the (org.apache.aries.jpa.proxy.factory=true) service property key-value pair
The second does not exist in your environment. There can be two causes:
aries-jpa-container-context is not in your OSGi environment or it is not in ACTIVE state
The original EntityManagerFactory service is not registered as some dependency is missing
You can check it if you open an OSGi console and check what services available. If there is no EntityManagerFactory service at all, the second is your problem.
Check if all of your bundles are active! If they are, check if you have all the services that jpa-container needs: TransactionManager, DataSource or DataSourceFactory and a javax.persistence.spi.PersistenceProvider service for Hibernate. If any of the services are missing aries-jpa-container will pick up your bundle but will never create the EntityManagerFactory.
I implemented an own jpa-container that works almost the same way as aries-jpa-container. If you replace the aries-jpa-container (only that one, the jpa-container-context should be left there) it will log more messages at INFO level for you what is missing. The container is available here. A sample application is available that uses hibernate is available at https://github.com/everit-org/osgi-hibernate. After running "mvn install" you will find itests/core/target/eosgi-itests-dist/equinox a subfolder where you can start the working application with on equinox server with bin/runconsole.sh.
The current aries jpa container jar 1.0.0 has a bug that makes it swallow exceptions on creating the EntityManager. A colleague of me opened the aries bug: https://issues.apache.org/jira/browse/ARIES-1160
I created a second patch that can be applied to the 1.0.0 sources to create a jar that correctly logs the exception. Check out the 1.0.0 tag of aries jpa container, apply the patch and build.
When you then run in karaf you should see the real source of the error.
I have simply donwloaded JSW community edition, unwrapped into a directory:
c:\servicetest
So here i have a bin, conf, lib and log subdirs, among others.
From now on this will be (root).
I referenced the (root)/lib/wrapper.jar into my ide (netbeans) and create a very simple service (remember the class name is Main):
public class Main extends WrapperSimpleApp {
public Main(String[] args) {
super(args);
}
#Override
public void run() {
while(true) {
Logger.getLogger(Main.class.getName()).log(Level.INFO, "I'm alive");
try
{ Thread.sleep(2000); }
catch (InterruptedException ex)
{ return; }
}
}
}
As you see, it basically does nothing but logging a message. But actually it neither starts.
I compiled the project (MyProject.jar), copied the jar into the (root) directory and modified the (root)/config/wrapper.conf adding:
wrapper.java.classpath.3=../MyProject.jar
and
wrapper.java.mainclass=textappender.Main
Then i've installed the service in command line, with:
C:\servicetest\bin>wrapper -i ../conf/wrapper.conf
then i've started the service, either via services.msc control panel or via
C:\servicetest\bin>wrapper -t ../conf/wrapper.conf
In logs/wrapper.log i get:
ERROR | wrapper | 2012/05/21 21:35:11 | JVM exited while loading the application.
UPDATE 1
Following Tanuki Software advice, i've set in my (root)/config/wrapper.conf (well, uncommented since it already was):
wrapper.debug=TRUE
And now i get this:
INFO | jvm 1 | 2012/05/22 10:46:37 | WrapperManager Debug: WrapperManager.stop(1) called by thread: main
INFO | jvm 1 | 2012/05/22 10:46:37 | WrapperManager Debug: Backend not connected, not sending packet STOP : 1
INFO | jvm 1 | 2012/05/22 10:46:37 | WrapperManager Debug: Stopped checking for control events.
DEBUG | wrapper | 2012/05/22 10:46:37 | Pause reading child process output to share cycles.
INFO | jvm 1 | 2012/05/22 10:46:37 | WrapperManager Debug: Thread, main, handling the shutdown process.
INFO | jvm 1 | 2012/05/22 10:46:37 | WrapperManager Debug: shutdownJVM(1) Thread: main
INFO | jvm 1 | 2012/05/22 10:46:38 | WrapperManager Debug: wait for 0 shutdown locks to be released.
INFO | jvm 1 | 2012/05/22 10:46:38 | WrapperManager Debug: Backend not connected, not sending packet STOPPED : 1
INFO | jvm 1 | 2012/05/22 10:46:38 | WrapperManager Debug: calling System.exit(1)
DEBUG | wrapper | 2012/05/22 10:46:38 | JVM process exited with a code of 1, setting the wrapper exit code to 1.
But given my very simple implementation, i cannot guess what is going wrong.
rather than extending WrapperSimpleApp, your main class should implement the org.tanukisoftware.wrapper.WrapperListener interface.
You can find a very detailed description about implementing the interface on our website:
http://wrapper.tanukisoftware.com/doc/english/integrate-listener.html
Please let me know if you have any further questions about the implementation and/or the configuration properties in your conf file.
Another advise which comes in handy for me sometimes, is rather than running your application immediately as service, I find it easier to do the integration by running first as console application, because you can see the output directly on your console. Once everything seems working, I go ahead and install/run as service.
To run as console application, you would run for example:
C:\servicetest\bin>wrapper -c ../conf/wrapper.conf
You can also turn on debug output for the Wrapper by setting
wrapper.debug=true
in your conf file.
Edit due to the comment:
if your application is actually as simple as you describe, then just write your application as normal Java application without any Wrapper API parts.
You can use the WrapperSimpleApp to run your application out of the box with codeless integration into the Wrapper.
All you need to do is set the following properties in your conf file:
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
wrapper.app.parameter.1=textappender.Main
wrapper.java.classpath.1=../lib/wrapper.jar
wrapper.java.classpath.2=../MyProject.jar
With this configuration, the Wrapper will be able to run your application as windows service.
UPDATE2
I'm not sure what your code exactly looks like, but it seems you are calling WrapperManager.stop() in your main class...
Following the initial example class, I have modified the class, so it is not using any Wrapper-API (which for an simple application is not necessary):
public class Main {
public static void main(String[] args) {
while(true) {
Logger.getLogger(Main.class.getName()).log(Level.INFO, "I'm alive");
try
{ Thread.sleep(2000); }
catch (java.lang.InterruptedException ex)
{ return; }
}
}
}
After compile and creating the jar, the necessary properties in the conf file are:
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
wrapper.app.parameter.1=textappender.Main
wrapper.java.classpath.1=../lib/wrapper.jar
wrapper.java.classpath.2=../MyProject.jar
cheers,