0

I am implementing Custom logging in Jetty11 and getting the null pointer exception for the below code while fetching anything from the request object. I know the reason but do not the solution to it. The reason is: calling the request object methods before setting it. I know, there should be another way to do it. My use case is to set the int and string attributes to the logger. In this example, I am calling request.getMethod() but I also have to call other methods as well

import org.eclipse.jetty.server.CustomRequestLog;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;

    public class JettyCustomLogger extends CustomRequestLog
    {
        private static Request request;
    
        @Override
        public void log(Request request, Response response)
        {
            this.request = request;
            super.log(request, response);
        }
    
        public JettyCustomLogger(Writer writer, String logStr)
        {
            super(writer, setCustomAttributesToLog(logStr));
        }
    
        private static String setCustomAttributesToLog(String logStr)
        {
    
            String method = request.getMethod();
            StringBuilder logBuffer = new StringBuilder(logStr);
            logBuffer.append(method);
            logBuffer.append("Ashish");
            logBuffer.append(" ");
            logBuffer.append("Goyanka");
            logBuffer.append(" ");
            logBuffer.append("absgdh");
            logBuffer.append(" ");
    
            return logBuffer.toString();
        }
    
    }

Note: this code works fine if I don't call request object methods.

Update: the reason to create setCustomAttributesToLog() is that I need to fetch the string parameters from other methods on runtime but here, I have given hardcoded string for code readability

Ashish Goyanka
  • 207
  • 3
  • 11

1 Answers1

0

The log(request, response) method is called for every request response pair, this method is expected to produce some formatted log string and then give it to the RequestLogWriter. You should not be using setCustomAttributesToLog() in the constructor as there is no request yet, and you should not be storing the request as a static field. All your logic to convert produce the log string based on the request must be done in the log() method.

For your current implementation, there should be no reason you cannot use the standard CustomRequestLog. If you read the javadoc on this class there is the concept of the format string. The format string is generic and takes % codes to be replaced with information from an actual request/response.

To get what you're trying to achieve here you could do something like

CustomRequestLog requestLog = new CustomRequestLog(writer, "%m Ashnish Goyanka absgdh ")

Then for each request the %m will be replaced with the request method, then this string will be given to the writer.


If you do not wish to use the format string functionality of CustomRequestLog I would suggest you implement the RequestLog interface directly instead of extending CustomRequestLog.

Lachlan
  • 356
  • 1
  • 7
  • I do not understand this point - All your logic to convert produce the log string based on the request must be done in the log() method - I can not do that because we don't have Writer writer, String logStr objects in the log(request, response) method. Can you please explain more if it is possible. – Ashish Goyanka Aug 27 '21 at 08:47
  • Just save the Writer as a field in the constructor. You can't log a request in the constructor because there is no Request to log. The request/response pairs to log are given to you in the log() method. – Lachlan Aug 28 '21 at 09:06
  • There is actually a getWriter() method on CustomRequestLog which you can call to get the Writer, so you don't need to save it as a field yourself. – Lachlan Aug 28 '21 at 09:10