Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #9980 - add additional codes for CustomRequestLog #12322

Merged
merged 6 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@

import org.eclipse.jetty.http.HttpCookie;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.QuotedCSV;
import org.eclipse.jetty.http.pathmap.PathMappings;
import org.eclipse.jetty.util.DateCache;
import org.eclipse.jetty.util.NanoTime;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
Expand Down Expand Up @@ -201,7 +203,6 @@
* <p>The query string, prepended with a ? if a query string exists, otherwise an empty string.</p>
* </td>
* </tr>
* <!-- TODO ATTRIBUTE LOGGING -->
* <tr>
* <td>%r</td>
* <td>
Expand All @@ -214,13 +215,13 @@
* <p>The name of the Handler or Servlet generating the response (if any).</p>
* </td>
* </tr>
* <tr>
* <tr>
* <td>%s</td>
* <td>
* <p>The HTTP response status code.</p>
* </td>
* </tr>
* <tr>
* <tr>
* <td>%{format|timeZone|locale}t</td>
* <td>
* <p>The time at which the request was received.</p>
Expand Down Expand Up @@ -262,7 +263,7 @@
* <p>The URL path requested, not including any query string.</p>
* </td>
* </tr>
* <tr>
* <tr>
* <td>%X</td>
* <td>
* <p>The connection status when response is completed:</p>
Expand All @@ -288,6 +289,39 @@
* <p>The value of the VARNAME response trailer.</p>
* </td>
* </tr>
* <tr>
* <td>%{OPTION}uri</td>
* <td>
* <p>The request URI.</p>
* <p>The parameter is optional and may have the be one of the following options:</p>
* <dl>
* <dt>%uri</dt>
* <dd>The entire request URI.</dd>
* <dt>%{-query}uri</dt>
* <dd>The entire request URI without the query.</dd>
* <dt>%{-path,-query}uri</dt>
* <dd>The request URI without path or query (so just `scheme://authority`).</dd>
* <dt>%{scheme}uri</dt>
* <dd>The scheme of the request URI.</dd>
* <dt>%{authority}uri</dt>
* <dd>The authority of the request URI.</dd>
lachlan-roberts marked this conversation as resolved.
Show resolved Hide resolved
* <dt>%{path}uri</dt>
* <dd>The path of the request URI.</dd>
* <dt>%{query}uri</dt>
* <dd>The query of the request URI.</dd>
* <dt>%{host}uri</dt>
* <dd>The host of the request URI.</dd>
* <dt>%{port}uri</dt>
* <dd>The port of the request URI.</dd>
* </dl>
* </td>
* </tr>
* <tr>
* <td>%{attributeName}attr</td>
* <td>
* <p>The value of the request attribute with the given name.</p>
* </td>
* </tr>
* </table>
* <!-- end::documentation[] -->
*/
Expand All @@ -309,6 +343,7 @@ public record LogDetail(String handlerName, String realPath)
public static final String LOG_DETAIL = CustomRequestLog.class.getName() + ".logDetail";
private static final Logger LOG = LoggerFactory.getLogger(CustomRequestLog.class);
private static final ThreadLocal<StringBuilder> _buffers = ThreadLocal.withInitial(() -> new StringBuilder(256));
private static final Pattern PATTERN = Pattern.compile("^(?:%(?<MOD>!?[0-9,]+)?(?:\\{(?<ARG>[^}]+)})?(?<CODE>(?:(?:ti)|(?:to)|(?:uri)|(?:attr)|[a-zA-Z%]))|(?<LITERAL>[^%]+))(?<REMAINING>.*)", Pattern.DOTALL | Pattern.MULTILINE);

private final RequestLog.Writer _requestLogWriter;
private final MethodHandle _logHandle;
Expand Down Expand Up @@ -444,7 +479,7 @@ protected void doStart() throws Exception

private static void append(StringBuilder buf, String s)
{
if (s == null || s.length() == 0)
if (s == null || s.isEmpty())
buf.append('-');
else
buf.append(s);
Expand Down Expand Up @@ -489,8 +524,6 @@ private static List<Token> getTokens(String formatString)
{PARAM} is an optional string parameter to the percent code.
CODE is a 1 to 2 character string corresponding to a format code.
*/
final Pattern PATTERN = Pattern.compile("^(?:%(?<MOD>!?[0-9,]+)?(?:\\{(?<ARG>[^}]+)})?(?<CODE>(?:(?:ti)|(?:to)|[a-zA-Z%]))|(?<LITERAL>[^%]+))(?<REMAINING>.*)", Pattern.DOTALL | Pattern.MULTILINE);

List<Token> tokens = new ArrayList<>();
String remaining = formatString;
while (remaining.length() > 0)
Expand Down Expand Up @@ -788,6 +821,32 @@ else if ("d".equals(arg))

yield lookup.findStatic(CustomRequestLog.class, "logResponseTrailer", logTypeArg).bindTo(arg);
}
case "uri" ->
{
if (arg == null)
arg = "";
String method = switch (arg)
{
case "" -> "logRequestHttpUri";
case "-query" -> "logRequestHttpUriWithoutQuery";
case "-path,-query" -> "logRequestHttpUriWithoutPathQuery";
case "scheme" -> "logRequestScheme";
case "authority" -> "logRequestAuthority";
case "path" -> "logUrlRequestPath";
case "query" -> "logQueryString";
case "host" -> "logRequestHttpUriHost";
case "port" -> "logRequestHttpUriPort";
default -> throw new IllegalArgumentException("Invalid arg for %uri");
};

yield lookup.findStatic(CustomRequestLog.class, method, logType);
}
case "attr" ->
{
MethodType logRequestAttribute = methodType(void.class, String.class, StringBuilder.class, Request.class, Response.class);
yield lookup.findStatic(CustomRequestLog.class, "logRequestAttribute", logRequestAttribute).bindTo(arg);
}

default -> throw new IllegalArgumentException("Unsupported code %" + code);
};

Expand Down Expand Up @@ -1139,4 +1198,74 @@ private static void logResponseTrailer(String arg, StringBuilder b, Request requ
else
b.append('-');
}

@SuppressWarnings("unused")
private static void logRequestAuthority(StringBuilder b, Request request, Response response)
{
HttpURI httpURI = request.getHttpURI();
if (httpURI.hasAuthority())
append(b, httpURI.getAuthority());
else
b.append('-');
}

@SuppressWarnings("unused")
private static void logRequestScheme(StringBuilder b, Request request, Response response)
{
append(b, request.getHttpURI().getScheme());
}

@SuppressWarnings("unused")
private static void logRequestHttpUri(StringBuilder b, Request request, Response response)
{
append(b, request.getHttpURI().toString());
}

@SuppressWarnings("unused")
private static void logRequestHttpUriWithoutQuery(StringBuilder b, Request request, Response response)
{
HttpURI.Mutable uri = HttpURI.build(request.getHttpURI()).query(null);
append(b, uri.toString());
}

@SuppressWarnings("unused")
private static void logRequestHttpUriWithoutPathQuery(StringBuilder b, Request request, Response response)
{
// HttpURI doesn't support null path so we do this manually.
HttpURI httpURI = request.getHttpURI();
if (httpURI.getScheme() != null)
b.append(httpURI.getScheme()).append(':');
if (httpURI.getHost() != null)
{
b.append("//");
if (httpURI.getUser() != null)
b.append(httpURI.getUser()).append('@');
b.append(httpURI.getHost());
}
int normalizedPort = URIUtil.normalizePortForScheme(httpURI.getScheme(), httpURI.getPort());
if (normalizedPort > 0)
b.append(':').append(normalizedPort);
}

@SuppressWarnings("unused")
private static void logRequestHttpUriHost(StringBuilder b, Request request, Response response)
{
append(b, request.getHttpURI().getHost());
}

@SuppressWarnings("unused")
private static void logRequestHttpUriPort(StringBuilder b, Request request, Response response)
{
b.append(request.getHttpURI().getPort());
}

@SuppressWarnings("unused")
private static void logRequestAttribute(String arg, StringBuilder b, Request request, Response response)
{
Object attribute = request.getAttribute(arg);
if (attribute != null)
append(b, attribute.toString());
else
b.append('-');
}
}
Loading
Loading