MDC Integration Help

Any other thing not listed below...

Moderator: admin

Post Reply
DEBAPRIYA
Posts: 3
Joined: Tue Aug 25, 2015 3:08 pm

MDC Integration Help

Post by DEBAPRIYA » Tue Aug 25, 2015 3:26 pm

Hi,

I am trying to develop a small application using springboot. I am using log4j for logging the info in catalina.out file.

I am trying to integrate MDC to display some information about a session in the log but its not happening. I have written a filter called MDCFilter and i can see that is being called at the first place when there is a request to my application. But i cant see those session details in the log which i am putting in MDC.

I am pretty sure i am doing something wrong related to the log4j.properties settings. I have added my log4j.properties in src/main/resources folder Can someone help me here ?

My log4j.properties
=================
# Tomcat log4j logging
log4j.rootLogger = WARN, CATALINA

# Define all the appenders
log4j.appender.CATALINA = org.apache.log4j.DailyRollingFileAppender
log4j.appender.CATALINA.File = ${catalina.base}/logs/catalina.log
log4j.appender.CATALINA.Append = true
log4j.appender.CATALINA.Encoding = UTF-8
# Roll-over the log once per day
log4j.appender.CATALINA.DatePattern = '.'yyyy-MM-dd'.log'
log4j.appender.CATALINA.layout = org.apache.log4j.PatternLayout
#log4j.appender.CATALINA.layout.ConversionPattern = %d [%t] %-5p %c- %m%n
log4j.appender.CATALINA.layout.ConversionPattern = %d [%t] %-5p %c [%X{fepId}->%X{bcId}:%X{userId}:%X{sessionId}] - %m%n

admin
Site Admin
Posts: 421
Joined: Sun Dec 17, 2006 10:30 pm

Re: MDC Integration Help

Post by admin » Tue Aug 25, 2015 6:45 pm

Hello,

Do you have trouble putting MDC in your log file, or do you have trouble displaying MDC in LogMX tool when opening your log file that contains MDC?
  • If you have trouble putting MDC in your log file: this forum is not the place to ask this question, but we can help... how do you tell Log4j where your Log4j configuration file is located?
  • If you have trouble displaying MDC in LogMX: what kind of LogParser are you using? How it is configured?
Xavier

DEBAPRIYA
Posts: 3
Joined: Tue Aug 25, 2015 3:08 pm

Re: MDC Integration Help

Post by DEBAPRIYA » Tue Aug 25, 2015 9:26 pm

First of all Sorry for putting the question in a wrong forum !!

But i would like to explain my problem which i am facing while integrating MDC in my application. I wanted to display some information in the pattern i have declared below in my log4j.properties file. Those key/values i am storing in MDC while any request comes in to my application. But i dont see those logging pattern in the log.

As i said earlier, my log4j.properties in places under /src/main/resources folder so i am not sure whether the application is picking up or not. But what i have read from the google is, if we are putting the log4j.properties in that folder application should pick that up.

Here is my Filter :
=================
/**
*
*/
package com.diginsite.microservices;

import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.MDC;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.intuit.ifs.afeLibrary.util.dto.DiId;
import com.intuit.ifs.afeLibrary.util.dto.RequestContext;
import com.intuit.ifs.afeLibrary.util.dto.SessionInfo;

/**
* @author dpatra
*
*/
public class MDCFilter implements Filter{

private static Logger logger = LoggerFactory.getLogger(MDCFilter.class.getName());
private FilterConfig filterConfig = null;

@Override
public void destroy() {
this.filterConfig = null;
}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse serletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) serletResponse;
MDC.clear();
//[V0000->03399:204290:XX-9d071451-4a6b-11e5-bc3a-005056a05b8d:173.63.55.234]
try {
// Get the parameter name/value map from request.
Map<String, String> parameterMap = getParameterMapFromRequest(request);
String bcId = getFiId(request);
String ipAddress = getClientIPAddress(request);
String fepId = parameterMap.get("FEPID");

if (StringUtils.isBlank(bcId)) {
logger.error("Required info (FI_ID) missing, will return HTTP 400");
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}

if(StringUtils.isBlank(fepId)) {
fepId = "V0000";
//logger.error("Required info (FEP_ID) missing, will return HTTP 400");
//response.sendError(HttpServletResponse.SC_BAD_REQUEST);
//return;
}

bcId = DiId.toNumericFormat(bcId);

MDC.put(RequestContext.IP_ADDRESS, ipAddress);
MDC.put(RequestContext.USER_ID, parameterMap.get("intuit_loginid"));
MDC.put(RequestContext.BC_ID, bcId);
MDC.put(RequestContext.FEP_ID, fepId);
//MDC.put(RequestContext.SESSION_ID, parameterMap.get("FISHTAG"));

// if(canonicalId != null){
// MDC.put(FMISConstants.BCINDEX_KEY, canonicalId.substring(canonicalId.length()-2));
// MDC.put(FMISConstants.CANONICAL_ID_KEY, canonicalId);
// }


SessionInfo sessionInfo = createSessionInfo(bcId, fepId, request, ipAddress, parameterMap);
request.setAttribute("sessionInfo", sessionInfo);

RequestContext.initialize(sessionInfo);

filterChain.doFilter(request, response);
}catch (Exception e) {
logger.error("Got Exception, will return HTTP 400: {}", e);
((HttpServletResponse) response).sendError(HttpServletResponse.SC_BAD_REQUEST);
return;

}finally{
MDC.clear();
}
}

@Override
public void init(FilterConfig filterConfig) throws ServletException {
logger.warn("Initiating MDC filter...");
this.filterConfig = filterConfig;
}

private final Map<String, String> getParameterMapFromRequest(HttpServletRequest request) {
Map<String, String> map = new HashMap<String, String>();
Enumeration<String> headerNames = request.getHeaderNames();
// looping through all the headerNames.
while(headerNames.hasMoreElements()) {
String key = (String)headerNames.nextElement();
String value = request.getHeader(key);
map.put(key, value);
}
return map;
}

private String getFiId(HttpServletRequest request) {
Pattern p = Pattern.compile("(?<=fis\\/)(.+?)(?=\\/)");
Matcher m = p.matcher(request.getRequestURI());

if (m.find()) {
String fiId = m.group();
return fiId;
} else {
return "default";
}
}

/**
* Helper method to get the client's IP addresses through various means. If no client IP address can be
* obtained, then 127.0.0.1 is set as the returned IP address.
* @param request
* @return
*/
public static String getClientIPAddress(HttpServletRequest request) {
logger.trace("Entering getClientIPAdress.");
String clientIpAddress = null; //default IP address

//If getting it from the request all fail, we'll hard code the IP to 127.0.0.1.
clientIpAddress = request.getHeader("".toString());
logger.debug("Trying to obtain IP address from x-forwarded-for: " + clientIpAddress);

if(clientIpAddress == null) {
clientIpAddress = request.getRemoteAddr();
logger.debug("Trying to obtain IP address from getRemoteAddr(): " + clientIpAddress);
}

if(clientIpAddress == null) {
clientIpAddress = "127.0.0.1";
logger.debug("No IP address found, setting to 127.0.0.1.");
}

//Check if the ip address that is being set contains more than 1 IP. If so we need to set only 1.
if(clientIpAddress.contains(",")) {
logger.debug("Multiple IP addresses found.");
String[] ipAddresses = clientIpAddress.split(",");
if(ipAddresses != null) {
logger.debug("Setting single IP address: " + ipAddresses[0]);
clientIpAddress = ipAddresses[0];
}
}

logger.trace("Exiting getClientIPAdress.");
return clientIpAddress;
}

private SessionInfo createSessionInfo(String bcId, String fepId,
HttpServletRequest req, String ipAddress, Map<String, String> parameterMap){

SessionInfo sessionInfo = new SessionInfo();

// String fishtag = parameterMap.get("FISHTAG");
// sessionInfo.setSessionId(fishtag);

sessionInfo.setFepId(fepId);
sessionInfo.setBcId(bcId);

String reqHost = req.getHeader("host");
sessionInfo.setHostName(reqHost);

sessionInfo.setIpAddress(ipAddress);

String userid = parameterMap.get("intuit_loginid");
sessionInfo.setUserId(userid);

sessionInfo.setTimezone("America/Los_Angeles");
return sessionInfo;
}


}

And this is how is my logging looks like:
===================================
2015-08-25 14:25:33.587 WARN 8797 --- [nio-8081-exec-1] m.d.s.BusinessBankingResourceServiceImpl : Find company
2015-08-25 14:25:34.007 WARN 8797 --- [nio-8081-exec-1] m.d.s.BusinessBankingResourceServiceImpl : Find the location to be updated
2015-08-25 14:25:34.127 WARN 8797 --- [nio-8081-exec-1] m.d.s.BusinessBankingResourceServiceImpl : Changing default location for a company
2015-08-25 14:25:34.127 WARN 8797 --- [nio-8081-exec-1] m.d.s.BusinessBankingResourceServiceImpl : Soft-delete a location for a company
2015-08-25 14:25:34.127 WARN 8797 --- [nio-8081-exec-1] m.d.s.BusinessBankingResourceServiceImpl : No changes were made to the location




I am expecting [V000->04715:achadmin:s3147daj134ka-f9873q] but thats what is not happening.

There are no errors but the expected result is not coming in the log.

Let me know if you have any solution for this.

Thanks a lot for your reply !

admin
Site Admin
Posts: 421
Joined: Sun Dec 17, 2006 10:30 pm

Re: MDC Integration Help

Post by admin » Tue Aug 25, 2015 9:48 pm

Since the format of your logs doesn't match the one you specified in your Log4j configuration file, it means that Log4j doesn't use this configuration file. The directory "src/main/resources" should be fine, but it depends how you compile/package your application... If your application is built as a JAR, you can simply check if your log4j config file is included in this JAR (a JAR file is a ZIP file, simply rename it ".zip" to open it). Then also make sure that you start your application with the option "-Dlog4j.configuration=<your-path-to-config-file>". See https://logging.apache.org/log4j/1.2/ma ... der_Tomcat for more information.

DEBAPRIYA
Posts: 3
Joined: Tue Aug 25, 2015 3:08 pm

Re: MDC Integration Help

Post by DEBAPRIYA » Tue Aug 25, 2015 10:22 pm

I am trying to run the application and test the log pattern in my Eclipse IDE . I have not yet deployed to the tomcat server yet. So not sure how i can test the logging pattern which i am expecting here.

Thanks,
Deba

admin
Site Admin
Posts: 421
Joined: Sun Dec 17, 2006 10:30 pm

Re: MDC Integration Help

Post by admin » Wed Aug 26, 2015 4:19 pm

If you're using Eclipse IDE, then you may look at the "Run configuration" you are using to start your application: depending on the "Nature" of your Eclipse project, you may want to look at:
  • "Arguments" / "VM arguments" to declare your option "-Dlog4j.configuration=<your-path-to-config-file>"

    and
  • "Classpath" to include "src/main/resources" in your classpath
If you need more help on this, you may want to ask a question on StackOverflow if it is not related to LogMX.

Post Reply