Showing posts with label logback. Show all posts
Showing posts with label logback. Show all posts

February 3, 2011

Part 5: Setting up Logging

If you've followed Part 4 of this tutorial, we're about to setup logging for the ModelingAgency webapp in order to learn how to use MySQL, MyBatis and Tomcat togather.

If you're familiar with Log4J you can use that library. However for the ModelingAgency webapp we're going to setup the Logback library, which is the new Log4J.

You have probably already downloaded the Logback jars in Part 1. If not, you can download all of the jars required for the ModelingAgency app here.

Configuring Logback

Configuring Logback with a Java web application is relatively simple. Once you have the required jars in /WEB-INF/lib, create a file called logback.xml and put it under your project's /src folder.

Here is the logback.xml file we we will use for this project:

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" debug="false" > <!-- set debug to true to dump logback status info when library is loaded -->
 
  <contextName>ModelingAgency</contextName>
  
  <!-- APPENDERS -->
  
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">    
    <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder> 
      <pattern>[%contextName] %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>
  
  <appender name="SQLDUMP" class="ch.qos.logback.core.FileAppender">
    <file>sql.log</file>
    <append>false</append>
    <encoder>
      <!-- <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern> -->
      <pattern>[%contextName] [%c] [%d{dd MMM yyyy - hh:mm:ss}] %5p - %m %n</pattern>      
    </encoder>
  </appender>
  
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>application.log</file>
    <encoder>
      <!-- <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern> -->
      <pattern>[%contextName] [%c] [%d{dd MMM yyyy - hh:mm:ss}] %5p - %m %n</pattern>      
    </encoder>
  </appender>
  
  <appender name="OUT" class="ch.qos.logback.core.ConsoleAppender">    
    <encoder>
    <pattern>[%contextName] [%c] [%d{dd MMM yyyy - hh:mm:ss}] %5p - %m %n</pattern>        
    </encoder>
  </appender>
  
   <appender name="OUT_SIMPLE" class="ch.qos.logback.core.ConsoleAppender">    
    <encoder>
    <pattern>[%c] %5p - %m %n</pattern>        
    </encoder>
  </appender>
        
  <!-- LOGGERS -->  
    
  <!--  loggers inherit the appender from their parent ( the root logger ) -->
  <logger name="java.sql" level="DEBUG" additivity="false"> 
   <appender-ref ref="SQLDUMP" /> 
  </logger>
   
  <logger name="org.apache.ibatis.datasource" level="WARN"/> <!-- removes datasoure debug info from logs --> 
       
  <root level="debug"> <!-- can set level to OFF-->
    <appender-ref ref="OUT" />
  </root>
  
</configuration>

Adding logging to TestServlet

To make sure logback works properly, let's add some simple logging code to the TestServlet we created in Part 4

Add the following logging code to the TestServlet.java file:


package com.modelingagency.servlets;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestServlet  extends HttpServlet{
 
 private static Logger log = LoggerFactory.getLogger(TestServlet.class);
 
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
 {
  HttpSession session = request.getSession();   
  ServletContext sc = getServletContext();
  
  request.setAttribute("message","This is a message from the TestServlet. It works!");
  log.info("The message attribute has been set");
             
  RequestDispatcher view = request.getRequestDispatcher("index.jsp");
  view.forward(request, response); 
 }
 
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  doPost(request,response);
 }
 
}

Restart your project now, by right clicking on the index.jsp file and selecting Run on server.

If you access the TestServlet's url on your local server now, http://localhost:8080/ModelingAgency/test.do you should get an output like this:

[ModelingAgency] [com.modelingagency.servlets.TestServlet] [03 Feb 2011 - 10:38:26] INFO - The message attribute has been set

If you got this far, it means you have setup Logback logging for the ModelingAgency webapp.

Now the fun part,

Part 6: Creating the java pojo model

Part 1: The Setup

Installing Eclipse

Chances are you already have Eclipse installed by now. Just make sure you have the Java EE version of Eclipse or at least the Web Tools Project installed.

For this tutorial I used Java EE Eclipse (Helios) SR1

If you are installing eclipse for the first time use this link: Download Java EE Eclipse Helios

Installing Tomcat 6

Go to: http://tomcat.apache.org/index.html and download the appropriate Tomcat distribution you need.
Tomcat 5.5 or 6 should both work with this tutorial.

For this tutorial I used Tomcat 6.0.29.
You can download this version here.

Installing MySQL

It's assumed at this point that you have a working MySQL database instance setup already. Ideally MySQL version 5.1 or above. If you already have the MySQL driver setup with your Tomcat server you can skip this section, if not, read on.

To use MySQL from your Java web application you will first need to download the MySQL Java Driver, also known as the JDBC Driver for MySQL (Connector/J)

1) Go to: http://www.mysql.com/downloads/connector/j/ and download JDBC Driver for MySQL (Connector/J) zip archive.

2) Extract the driver .jar file into your Tomcat installation:

CATALINA_HOME/common/lib folder (Tomcat 5) or CATALINA_HOME/lib (Tomcat 6)

For this tutorial I used the mysql-connector-java-5.1.13-bin.jar but any version above that should also work.

Tip: Avoid putting your MySQL driver jar under WEB-INF/lib as it may cause issues down the road when you want to use mysql with other webapps. You'll probably forget about it and it will cause class path conflicts. So the best bet is to leave it in the shared libraries folder of your Tomcat server. That way all webapps will have access to it.

Jar libraries for this tutorial

To make things quicker for you, you can download all the jar files you will need for this tutorial here. Once we setup the eclipse project in Part 3: Creating the ModelingAgency project in Eclipse, you can just extract all the jars here under the /WEB-INF/lib folder

However if you want to do it manually follow the rest of this tutorial.

Installing MyBatis

Go to: http://www.mybatis.org/java.html.
Click on Download the Persistence Framework and download the zipped archive mybatis-3.0.4-bundle.zip (direct link)

Once we have setup the ModelingAgency web application in Eclipse in Part 3: Creating the ModelingAgency project in Eclipse, you will extract the mybatis-3.0.4.jar to the /WEB-INF/lib folder of your application. Don't worry, I'll remind you about that later.

Tip:Before you go any futher, I would strongly suggest you go through the very well written MyBatis documentation before you continue with this tutorial (Especially if you've never used iBatis or MyBatis). It will take about 30 minutes to skim through it, and will give you an excellent foundation of the basics.

download the documentation

Installing JSTL/EL

One last thing. In our project we are going to use the JSTL library to make things easier a bit. With a combination of the JSP Expression Language and the JSTL library you should almost never need to write 'java' code inside your jsp files anymore. To learn more about this read The Evolution of Servlets and JSP.

To make use of Java's JSTL library and the JSP Expression Language in our project, you will need to download jstl.jar and standard.jar from the Jakarta Taglibs Project extract them to the /WEB-INF/lib folder of your application. Don't worry, I'll remind you about this later as well..

These jars can be found here:

Go to: http://jakarta.apache.org/site/downloads/downloads_taglibs-standard.cgi and download the 1.1.2.zip binary.
For direct link click here.

Installing LogBack (the new Log4j)

If you want to be able to log things to the console for this project you should also install LogBack, the successor of Log4J

Download logback-0.9.28.zip. You will need to extract the following files to the /WEB-INF/lib folder of the webapp we will setup in Part 3: Creating the ModelingAgency project in Eclipse.

  • logback-core-0.9.28.jar
  • logback-classic-0.9.28.jar

There is also an additional depndency which logback needs, which you can download from here: slf4j-api-1.6.1.jar

If you feel like everything here is setup correctly, let's move on to

Part 2: The ModelingAgency Application

July 13, 2010

Logback or Log4j Additivity Explained

If you have come across the notion of additivity, while trying to figure out how to stop Logback or Log4j from dumping too much or too little data to the console or a file, but don't quite understand how it works, here is a quick explanation.

First, the very basics

Logback and Log4j have 3 main items that you should understand:

  1. Loggers - objects that log something
  2. Appenders - each logger has one or more. An appender is an output destination (eg. the console or a file)
  3. Layouts - each appender has a layout. A layout is the format of the stuff being logged.

Also

  • A logger can have a parent based on what name you give it (using the . notation). For example, a logger called bob is a parent of a logger called bob.stuff or bob.stuff.foo
  • The root logger is always the parent of every other logger.

So what is aditivity

When a method like log.debug() or log.info() is called on a logger X.Y.Z, it is forwarded to all appenders associated with logger X.Y.Z, as well as all appenders associated with X's parents (such as logger X.Y and logger X). The message is also forwarded to all appenders of the root logger.

For example, if the root logger has an appender for a standard console output, and you have another logger X which has a file appender, calling x.debug() on logger x, will log both to the console (the root logger's appender) and to the file (the X logger's file appender).

If the aditivity flag of logger X however is set to false, or disabled, then calling x.debug() will only log to the file. In other words disabling additivity for a logger, prevents parents of that logger from using their appenders to display the message.

Hope that makes sense.

If you are just starting out with Logback

If you're just starting out with Logback or Log4j, and don't quite understand the naming convention used by these logging frameworks for naming the loggers, keep in mind the following quote from Logback's official documentation:

"Logback makes it easy to name loggers by software component. This can be accomplished by instantiating a logger in each class, with the logger name equal to the fully qualified name of the class. This is a useful and straightforward method of defining loggers. As the log output bears the name of the generating logger, this naming strategy makes it easy to identify the origin of a log message. However, this is only one possible, albeit common, strategy for naming loggers. Logback does not restrict the possible set of loggers. As a developer, you are free to name loggers as you wish."

So hopefully now when you see the following line of code, which defines a logger in a class, you understand what it does:

//get the logger called "com.foo.SomeClassName"
private static Logger log = LoggerFactory.getLogger(SomeClassName.class);  

July 10, 2010

Dumping MyBatis SQL Statements To Console using Logback

By default the root logger in LogBack is set to the debug level.

This means if you use MyBatis, MyBatis will dump statements from the java.sql.* package to the standard console (assuming your root logger is configured in a more or less standard way with a ConsoleAppender or a default configuration).

For example:

Having a root logger configured like this in logback.xml:

<root level="debug">
   <appender-ref ref="OUT" />
</root>

and associated with a console appender like the one below for example:


<appender name="OUT" class="ch.qos.logback.core.ConsoleAppender">    
    <encoder>
   <pattern>[%c] [%d{dd MMM yyyy - hh:mm:ss}] %5p - %m %n</pattern>        
    </encoder>
</appender>

You will see a dump of MyBatis debug statements for package java.sql.* as your application runs.

If you want this, that's great.

But if not, you have some options for disabling the MyBatis SQL logging dump to the console. Choose one:

  1. Set the logging level for the java.sql.* package to WARN.

    Add the following <logger> element to logback.xml
        <logger name="java.sql" level="WARN"></logger>
    
  2. Turn off the root logger.

    <root level="OFF">
       <appender-ref ref="OUT" />
    </root>
    

    If you have another logger configured to display other information, turning the root logger off will also prevent java.sql.* statements from being logged, since calling the log.debug() method passes the message to any appenders of that logger and any appenders of its parent loggers (including in this case the root logger).

  3. Set the additivity flag to false.

    <logger name="java.sql" additivity="false"/>
    

    Setting additivity="false" on any logger, ensures that logging doesn't occur on any other appenders that belong to the logger's parents (in this case the root logger). That combined with the fact that there is no appender specified for the logger named "java.sql" will essentially prevent any log.debug() statements from dumping mybatis sql results to the console.

Displaying MyBatis SQL Statements to the Console

If your root logger however is set to another level like INFO, and you actually want to display MyBatis debug info on the console, then you can just add a simple logger element to the logback.xml configuration file:

 <logger name="java.sql" level="DEBUG">
    <appender-ref ref="OUT"/> 
    <!-- see the appender named OUT defined above -->
 </logger>