Right now my info logs only show sql queries with ? for values. Can you suggest me changes to log4j2.xml file to display values?
log4j2.xml:
<RollingRandomAccessFile name="SQLLOGFILE">
<PatternLayout>
<Pattern>%-5p:%d{dd-MMM-yyyy HH:mm:ss,SSS}: %-25t %c : %m%n</Pattern>
</PatternLayout>
</RollingRandomAccessFile>
<AsyncLogger name="jdbc.sqlonly" level="INFO">
<AppenderRef ref="LOGFILE" level="INFO"/>
</AsyncLogger>
<AsyncLogger name="jdbc.audit" level="off"></AsyncLogger>
<AsyncLogger name="jdbc.resultset" level="off"></AsyncLogger>
<AsyncLogger name="jdbc.connection" level="DEBUG">
<AppenderRef ref="CONNECTION"/>
</AsyncLogger>
If your ORM vendor is Hiberante, which is by default in Spring framework you can use the following properties inside log4j2.xml
<AsyncLogger name="org.hibernate.SQL" level="DEBUG">
<AppenderRef ref="LOGFILE"/>
</AsyncLogger>
<AsyncLogger name="org.hibernate.type" level="TRACE">
<AppenderRef ref="LOGFILE"/>
</AsyncLogger>
Those 2 above properties include all necessary classes for the SQLs to appear correctly in your logs, including the binded values inside ? placeholders.
More specifically in hibernate the responsible class for placing values inside ? is the org.hibernate.type.descriptor.sql.BasicBinder. Those 2 above properties include this class as well to the Trace level, so the binded values for ? are correctly appended.
Consider using the datasource proxy TTDDYY that logs the quires already at more convenient way
Related
I am currently working on tidying up the logs for an internal tool we have. I came across the use of ${sys:logger.out.type} inside the Loggers in log4j2.xml.
Here's a copy of our log4j2.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="OFF">
<Appenders>
<Console name="stdout" target="SYSTEM_OUT">..
<PatternLayout pattern="..."/>
</Console>
<RollingFile name="FILE" fileName="${sys:microservice.log}" filePattern="${sys:microservice.log}.%i">
<PatternLayout>
<Pattern>...</Pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="300 MB" />
</Policies>
<DefaultRolloverStrategy max="5" />
</RollingFile>
</Appenders>
<Loggers>
<Logger name="org.springframework" level="warn" additivity="false">
<appender-ref ref="${sys:logger.out.type}"/>
</Logger>
<Logger name="org.springframework.jdbc.core" level="off" additivity="false">
<appender-ref ref="${sys:logger.out.type}"/>
</Logger>
<Logger name="org.springframework.jdbc.core.StatementCreatorUtils" level="off" additivity="false">
<appender-ref ref="${sys:logger.out.type}"/>
</Logger>
<Logger name="com.myOrgName" level="trace" additivity="false">
<appender-ref ref="${sys:logger.out.type}"/>
</Logger>
<Root level="info" additivity="false">
<appender-ref ref="${sys:logger.out.type}"/>
</Root>
</Loggers>
</configuration>
In my previous StackOverflow question, a very kind user redirected me to the Log4j Property Substitution page to better understand the semantics of ${sys:logger.out.type}.
After reading through the documentation, I understand the sys Prefix is referring to a system property but don't quite understand what logger.out.type means?
Taking a stab here, is it referring to the output type of a Logger? Which could mean it's referring to the Console element named stdout?
Appreciate any insights & feedback from the community. Should any of my understanding be mistaken, please correct me, I am also learning :) Thank you!
A property like ${sys:logger.out.type} in a log4j 2.x configuration file resolves to the value of the Java system property named logger.out.type.
You set system properties by passing the command line argument -Dlogger.out.type=stdout (or more generally -D<property name>=<value>) to the JVM when you invoke the java command.
You can also provide defaults, so ${sys:logger.out.type:-FILE} would choose your FILE appender if no value was set for that system property.
I have a custom Scalar Valued function in SQL with the below details:
Name : fn_WorkDays
Returns : Int
Parameters : 1. StartDate (type - datetime) 2. EndDate (type - datetime)
I'm using Hibernate 5.4.6 to fetch some records from the database. I want to use the above function in the HQL (in the Where Clause), however currently facing issues.
Query<Device> query = session.createQuery("Select ud from Device ud where fn_WorkDays(ua.created, current_date())>2", Device.class);
After going through some posts, I understand that the custom function needs to be registered before using it, hence have created the below class:
public class MySQLServerDialect extends SQLServerDialect {
public MySQLServerDialect() {
super();
registerFunction("fn_WorkDays", new VarArgsSQLFunction(StandardBasicTypes.INTEGER, "fn_WorkDays(", ",", ")"));
}
}
Have updated the hibernate.cfg.xml with :
<property name="dialect">com.test.service.utils.MySQLServerDialect</property>
I dont seem to understand how the registerFunction should be done as im getting the below error:
ERROR SqlExceptionHelper:142 - 'fn_WorkDays' is not a recognized function name.
Log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<!-- Console Appender -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout
pattern="%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36}:%L - %msg%n" />
</Console>
</Appenders>
<Loggers>
<!-- Log everything in hibernate -->
<Logger name="org.hibernate" level="debug" additivity="false">
<AppenderRef ref="Console" />
</Logger>
<!-- Log SQL statements -->
<Logger name="org.hibernate.SQL" level="debug" additivity="false">
<AppenderRef ref="Console" />
</Logger>
<!-- Log JDBC bind parameters -->
<Logger name="org.hibernate.type.descriptor.sql" level="trace" additivity="false">
<AppenderRef ref="Console" />
</Logger>
<!-- Log custom packages -->
<Logger name="com.test.service" level="debug" additivity="false">
<AppenderRef ref="Console" />
</Logger>
<Root level="error">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
Any help to resolve the above will be greatly appreciated.
ERROR SqlExceptionHelper:142 - 'fn_WorkDays' is not a recognized function name.
The error already says what is wrong, the function does not exist in the database.
Try this:
registerFunction("fn_WorkDays", new VarArgsSQLFunction(StandardBasicTypes.INTEGER, "dbo.fn_WorkDays(", ",", ")"));
Functions that are not pre-defined in the JPQL/HQL are invoked like this:
`function('fn_WorkDays' , ua.created, current_date())`
This is later translated to fn_WorkDays(ua.created, current_date()) in the native query. You still need to have it registered by the dialect as you have.
I'm trying to redirect all Quartz logging to a separate file, but it still keeps logging into the console. What am I doing wrong in the configuration file?
Here's a simplified version of my log4j2.xml
<Configuration>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<!--stuff-->
</Console>
<RollingFile name="Quartz">
<!--stuff-->
</RollingFile>
</Appenders>
<Loggers>
<Logger name="org.quartz" level="ALL">
<AppenderRef ref="Quartz"/>
</Logger>
<Logger name="com.rotoplastyc" level="ALL">
<AppenderRef ref="Console" />
</Logger>
<Root level="OFF">
</Root>
</Loggers>
</Configuration>
Found out that, as #teppic suggested in the comments, I needed the log4j-slf4j-impl lib in order for it to work properly, I was currently using the slf4j-simple lib which only logs into the console.
Is that possible to use MemoryMappedFile with Policies to break the files until fixed sizes, for example 250MB? My log4j2.xml is like this but I want to break the log files to 250MB and I need to use MemoryMappedFile for IO performance.
<Configuration monitorInterval="30">
<Appenders>
<MemoryMappedFile name="MemoryMap" fileName="output/jscsi-out.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p [%t] %c{2} - %m%n(%L)" />
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="250 MB" />
</Policies>
</MemoryMappedFile>
</Appenders>
<Loggers>
<Logger name="br.com" level="debug" additivity="false">
<AppenderRef ref="MemoryMap" />
</Logger>
<Logger name="org.jscsi.target.TargetServer" level="debug"
additivity="false">
<AppenderRef ref="MemoryMap" />
</Logger>
<Logger name="org.jscsi.target.storage" level="info"
additivity="false">
<AppenderRef ref="MemoryMap" />
</Logger>
<Logger name="org.jscsi.service" level="debug" additivity="false">
<AppenderRef ref="MemoryMap" />
</Logger>
<Root level="error" includeLocation="true">
<AppenderRef ref="MemoryMap" />
</Root>
</Loggers>
</Configuration>
(Background: I am the author of the MemoryMappedFile appender as well as Async Loggers.)
In some sense the MemoryMappedFile appender is still a work in progress (as of Log4j 2.5). As you mention, there is no Rolling variant. Also, I haven't been able to do any significant performance testing. I made a start some time ago but other issues took priority.
Initial performance testing indicates that synchronous logging, even when using the MemoryMappedFile appender, is unlikely to be faster than asynchronous logging via Async Loggers.
Generally, if you need the rollover behaviour I would suggest you use Async Loggers in combination with the RollingRandomAccessFile appender for now.
I'd like my application to run at Debug level, except for Spring, which is producing a huge amount of logging statements, which makes it hard to read through the logs. I've currently configured my Log4j2 file like this:
<Configuration status="debug">
<Appenders>
<RollingFile name="systemLog" fileName="C:/test/logs/system.log" includeLocation="true"
filePattern=""C:/test/logs/system-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout pattern="%d{ISO8601} - %-5level [%t] %C %M %m%n" />
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="15 MB"/>
</Policies>
</RollingFile>
<Async name="systemAsyncAppender" includeLocation="true">
<AppenderRef ref="systemLog" />
</Async>
</Appenders>
<Loggers>
<SpringLogger name="org.springframework.*" level="error" additivity="false">
<AppenderRef ref="systemAsyncAppender" />
</SpringLogger>
<Root level="debug" includeLocation="true">
<AppenderRef ref="systemAsyncAppender" />
</Root>
</Loggers>
</Configuration>
I thought that setting up the SpringLogger would set Spring to only run at ERROR level and, and write to the same log as everything else, but I'm still seeing full Spring DEBUG output. I have vague memories of being able to do this very easily with the old log4j.properties files (I think it was as simple as log4j.category.org.springframework=ERROR), but I'm not sure how to do this with Log4J2.
(Using Log4J2 2.0.2, spring 3.2.11)
I don't think log4j2 has any special configuration for Spring, so <SpringLogger> doesn't seem appropriate here.
Instead, just declare a regular logger
<logger name="org.springframework" level="error" additivity="false">
...
</logger>
Also note the logger name. These are hierarchical. You don't need the * (and I think it actually breaks it).