Monitoring EclipseLink JPA progress - java

I'm back at my first EclipseLink JPA project and noticed some issues regarding the performance. Here's the situation:
The application runs with a local Apache Derby DB. During the creation of the EntityManager the console logs a few infos and warnings, which takes a few seconds but is fine so far. However, if I package the whole code into an executable jar and run it outside Eclipse, the whole process takes a lot more time.
Now while it would be wise to find the reason for this issues in the first place, I at least wanted to add a ProgressBar in order keep rough track of the progress.
I looked up the EclipseLink wiki and found out that it already features a PerformanceMonitor and some logging utilities. I am now stuck at the seemingly simple task of putting 1 and 1 together.
How can I hook up my ProgressBar with EclipseLink? Or another approach: How can I log ongoing activities of EclipseLink in the first place?
Any help is much appreciated.
Cheers

Here is the steps to produce a log file for an SE project (non-application server one) which has EclipseLink JPA:
Open the file "persistence.xml" and assign the following properties:
property name="eclipselink.logging.logger" value="JavaLogger"
property name="eclipselink.logging.level" value="FINEST"
Given that Eclipselink JavaLogger is in fact a java.util.logging one, refer to your JDK folder to locate the file logging.properties which is to be modified as follows:
handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
# Default global logging level.
.level= FINEST
# default file output is in user's home directory
# java.util.logging.FileHandler.pattern = %h/java%u.log
# but I prefer to hard wire it as follows:
java.util.logging.FileHandler.pattern = C\:/SamLogFile.log
java.util.logging.FileHandler.level = FINER
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
# I personally don't care about the stdout logging, so I turn it off.
java.util.logging.ConsoleHandler.level = OFF
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
Now you can place some logging within your class by importing:
import java.util.logging.Level;
import java.util.logging.Logger;
And calling:
public void yourMethod() {
Logger.getLogger( YourClassName.class.getName() ).log( Level.INFO, "I am logging well......!" ); }
Now you are set. Run/test your project and enjoy reading your log!

You can also take your logging code into a best practice by adding the 2 files slf4j-api-1.7.1.jar and the file slf4j-jdk14-1.7.1.jar to your classpath. These 2 files are to be downloaded from http://www.slf4j.org/download.html
Add to your class the imports:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Then add to your method this line:
LoggerFactory.getLogger(Mysafeperson.class.getName()).info("I am logging using the slf4j api");
This practice is making your code using the slf4j api instead of the java.util.logging (JUL) api. Thus your code is decoupled from JUL and ready for any logging framework to be bound as an slf4j implementation (choices are logback - log4j - or refer to this link.)
The idea I am promoting here is based upon the documentation in http://www.slf4j.org/legacy.html. So:
The file: slf4j-api-1.7.1 is your new api facade.
The file: slf4j-jdk14-1.7.1 makes a bridge from the existing logging implementation which is java.util.logging (JUL) and your application code calling the slf4j api.
Two tips remain:
Be aware that the available defined levels in JUL are:
SEVERE (highest value)
WARNING
INFO
CONFIG
FINE
FINER
FINEST (lowest value)
Thus don’t use the levels (Error – TRACE – DEBUG) of the slf4j api, they will not trigger any logging level. INFO and WARN are OK to use
As for EclipseLink, be aware that you are still tied to using the JUL configuration file logging.properties

You should enable the eclipselink logging by adding this in your persistent unit's properties in the persistence.xml file:
<property name="eclipselink.logging.level" value="DEBUG"/>
to enable a most detailed logging, or even 'ALL' instead of 'DEBUG' if not enough. But remove it when going to production or that line itself will make it slower.
Two common things that could make eclipse link slower are:
having this in in the persistence.xml when not needed:
<property name="eclipselink.ddl-generation" value="create-tables"/>
and NOT having this (if you declare de classes in the persistence.xml file. Set it to false if you do not!!):
<exclude-unlisted-classes>true</exclude-unlisted-classes>
as of the progress bar, I would say it will be very hard, and not precise since even eclipselink don't know the whole amount of classes it will process in he beginning, so I don't think it's worth the effort, but good luck if you find out a way to do it.

Related

Spring boot logging / Java logging - Tool to show config/setup

I'm used to using log4j and whenever there were setup/config problems I'd enable "-Dlog4j.debug" and all the config info would be dumped out at startup.
This was very useful on a number of occasions.
Now I'm working on a Spring boot application, which I've found uses:
Commons logging Logger statements in the client code
A bridge jar (jcl-over-slf4j-xxx.jar) which translates the commons logging calls into slf4j more info here
Finally slf4j uses "logback" as the underlying logging framework
I found it rather painful to figure all this out.
Is there an equivalent of -Dlog4j.debug which can show me how this is all hanging together at startup time?
This is the best/only option I've found so far, and it's logback specific.
Use this -D on the command line:
-Dlogback.statusListenerClass=ch.qos.logback.core.status.OnConsoleStatusListener
Taken from here
This essentially is the logback equivalent of log4j's -Dlog4j.debug.
It dumps the logback startup sequence to the console at startup time, as the logging system is initialised.
This is not a true answer as I'd like some messages to show before this to show why logback is being used, but I haven't found anything like that yet.
Aside: This may also be useful for Spring Boot:
-Ddebug
Taken from here and here
If you are using logback, I assume you are using the logback.xml file? Then if you start that file with <configuration debug="true"> then it should dump the status information. More information in the documentation under status data section.

How to enable debug logging in PostgreSQL JDBC/HikariCP?

I have Spring Boot 1.4.0, HikariCP 2.4.7, slf4j-api 1.7.21 and PostgreSQL JDBC 9.4.1208.
I want to see debug logs from PostgreSQL JDBC because I have some problems with HikariCP:
HikariPool-1 - Connection is not available, request timed out after 42734ms.
How can I enable debug logging to see what's going on?
I've tried:
-Adding:
org.postgresql.Driver.setLogLevel(Driver.DEBUG);
hikariDataSource = new HikariDataSource();
hikariDataSource.setLogWriter(new PrintWriter(System.out));
-Adding to VM options:
-Dorg.slf4j.simpleLogger.defaultLogLevel=debug
However, logs are the same as they were.
Few things to consider:
Consider logging to files
1) logging to sysout may cause you to miss updates
2) it's also slow and slows your app down
Consider keeping log config in slf4j config file instead.
Consider specific Hikari config:
-Dorg.slf4j.simpleLogger.log.com.zaxxer.hikari=error
Also, by default the log level for slf4j simple logger is info. So, if you're NOT seeing anything, I don't think it's config. It may be lack of some dependency (are you just using slf4j, or something else, like log4j as well?).
Finally, are you certain that your changes are picked up at all?
Since it's hard to say on this side, let me offer another side where logging can take place: Postgres.
Try changing PG logging config:
logging_collector = on # may be 'true' for older versions as well?
log_statement = all # 'true' for older versions
log_min_error_statement = error
First turns log collector on and makes logging not lose messages.
Second says everything interests you, even simple queries with syntax errors.
Third gives your error level.
Docs for Postgres will tell you more.

Configure log4j when using Weld CDI

I'd like to programmatically adjust my logging file locations. Thus I want to overwrite the default values in my log4j.properties file. This is not opposing any problems I am using LogManager.resetConfiguration() and PropertyConfigurator.configure(props) so that my file locations are updated (stored in props). This methodology works, logging files are from this point onward written to a new file location.
My problem occurs when using Weld. This is due the fact that Weld internally is using a logger as well, stated in my logging-file: 2014-08-13 12:55:15.589 [main:0] DEBUG Weld.java:84 Method: <clinit> - Logging Provider: org.jboss.logging.Log4jLoggerProvider.
Since I'm using org.jboss.weld.environment.se.StartMain as main class, I do not have any influence on the logging capabilities of Weld. I now end up with 3 logging files (as described in my log4j.properties) on 2 different locations. Whereas one contains some Weld debug information and the other contains all the logging information from initialization and onward.
Thus logically I'd like to end up with only 1 directory with logging files, thus that Weld adjusts to the new log4j file location. Or to have log4j to copy the old logging contents, create new logging files + with old content and to delete the old logging files.
I do not want to use VM arguments, since I need to programmatically assign the logging locations.
The solution in cases like this is to use slf4j. See bridging legacy apis.
Once you bridged all logging, you can use slf4j-to-log4j to direct all logging to your log4j settings.

OpenJPA logging into a separate file in Websphere

I've a problem with OpenJPA logging and Websphere (8).
For a few days I try to redirect the OpenJPA logging information into a separate file (instead of the SystemOut log file). This is what I tried:
Changing the persistence.xml with logging information (e.g. ). Though I learned that websphere is ignoring this entry. Can I assume that this is correct?
http://pic.dhe.ibm.com/infocenter/wasinfo/v8r0/topic/com.ibm.websphere.express.doc/info/exp/ae/tejb_loggingwjpa.html tells me the same
Also the wsjpa.log property did not help.
Specifying a handler for openjpa (or openjpa.Runtime, ...) in JSR-47 configuration file does not work either (other configurations worked). What I realized here is that there is actually no openjpa logger in the java logging (java.util.logging.LogManager.getLogManager().getLoggerNames()). Does that mean that OpenJPA is not logging to a dedicated logger but just writes to SystemOut which is then processed by websphere?
I searched through all the different loggers and traces in the websphere console and tried a few, but none of them contained any openjpa logs. Can I assume that there is no other location where openjpa logs to in websphere?
To conclude: It's not working and I cannot use a handler for the openjpa logs because there are no logs generated. OpenJPA in websphere is just printing to the SystemOut which is internally used for the tracing. Does anyone have an idea what to do?
Alternatives would be:
- Use HPEL
- Script to filter the trace.log
But actually I would rather have a file handler for OpenJPA in Websphere.
Thanks for your help and I can supply you with some more information if you need that.
You can use application logging system for this purpose based on 3d party logging library for example logback.
logback is very powerful library.

Turning off logging for Hibernate c3p0

I'm using Hibernate's c3p0 connection pooling and standard Java 1.4 java.util.logging. Upon startup, my app sets up it's logging properties (including formatter and log levels) in static block. Every time I start my app, I see the following:
2011-04-16 17-43-51 [com.mchange.v2.log.MLog] INFO: {MLog.<clinit>) MLog clients using java 1.4+ standard logging.
2011-04-16 17-43-51 [com.mchange.v2.c3p0.C3P0Registry] INFO: {C3P0Registry.banner) Initializing c3p0-0.9.1 [built 16-January-2007 14:46:42; debug? true; trace: 10]
2011-04-16 17-43-51 [com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource] INFO: {AbstractPoolBackedDataSource.getPoolManager)
...
I've tried
Logger.getLogger("com.mchange").setLevel(Level.WARNING);
com.mchange.v2.log.MLog.getLogger().setLevel(MLevel.WARNING);
System.setProperty("com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL", "WARNING");
but only way to prevent it that I found for now is
Logger.getLogger("").setLevel(Level.WARNING);
which affects everything - not a good side effect. Google didn't help. Could anyone help please?
The way I found is to set the system property
System.setProperty("com.mchange.v2.log.MLog", "com.mchange.v2.log.FallbackMLog");
in addition to
System.setProperty("com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL", "WARNING");
I thought, that absence of any other logging system wil make that optional, but it seems, that I was wrong.
P.S.
Damn those wheel-reinvented custom logging implementations, like the one used by c3p0...
The way I found for achieving this
Create in your classpath a file called mchange-log.properties and put into it properties suggested by Frozen Spider.
com.mchange.v2.log.MLog=com.mchange.v2.log.FallbackMLog
com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL=WARNING
Thats work fine even when you are not able to set system properties directly.
It appears that c3p0 logging defaults to DEBUG. That can result in a lot of noise.
By adding a line like this to log4j.properties, you are telling the logger not to bother you with c3p0 messages - unless it's something important:
log4j.logger.com.mchange.v2=WARN
Do you not want to see any c3p0 logging?
If so try:
Logger.getLogger("com.mchange.v2.c3p0").setLevel(Level.WARNING);
OR, if you don't even want to see the first line of the log:
Logger.getLogger("com.mchange.v2").setLevel(Level.WARNING);
This is probably really late, but according to the c3p0 project website it is possible to configure the logging inside the mchange-log.properties so that you can capture the information using slf4j or log4j (and thus also with Logback).
The link http://www.mchange.com/projects/c3p0/#configuring_logging provides this information that in your mchange-log.properties file set the property com.mchange.v2.log.MLog to equal com.mchange.v2.log.slf4j.Slf4jMLog then in your logback.xml you can provide a logger like this:
<logger name="com.mchange" level="warn" additivity="false">
<appender-ref ref="c3p0-log" />
</logger>
Note: you will need to create a logback appender called c3p0-log before you can use this exact piece of code.
create a file called log4j.properties in your root classpath
set the following in there,
# Configure the name of the file for the LOGGER appender
log4j.appender.LOGGER=org.apache.log4j.ConsoleAppender
log4j.appender.LOGGER.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGGER.layout.ConversionPattern=%d{MM-dd#HH:mm:ss} %-5p (%13F:%L) %3x - %m%n
log4j.appender.LOGGER.append=false
# this line logs everything from hibernate package at info level, you can refine this to include only some pachages like log4j.logger.org.hibernate.hql etc.,
log4j.logger.org.hibernate=INFO, LOGGER
log4j.logger.org.jboss.cache=INFO, LOGGER
this is a much better way of implementing the logging because if you set the logging strategy programmatically, then the config sometimes might not take effect at all (like in your case).. if you use the log4j.properties file ,the config is applied at application startup & everything works smoothly.
This only happens on older c3p0 version. So it might also be worth checking if you can just update to a newer version.

Categories