Issue #113 - CustomRequestLog
update logHandle directly rather than creating list of tokens Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
parent
012d412ccb
commit
4be4b4e7b4
|
@ -22,8 +22,6 @@ import java.io.IOException;
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@ -286,18 +284,16 @@ public class CustomRequestLog extends AbstractLifeCycle implements RequestLog
|
||||||
private String _logTimeZone = "GMT";
|
private String _logTimeZone = "GMT";
|
||||||
|
|
||||||
private final MethodHandle _logHandle;
|
private final MethodHandle _logHandle;
|
||||||
private final String _format;
|
|
||||||
|
|
||||||
public CustomRequestLog(String formatString)
|
public CustomRequestLog(String formatString)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_format = formatString;
|
|
||||||
_logHandle = getLogHandle(formatString);
|
_logHandle = getLogHandle(formatString);
|
||||||
}
|
}
|
||||||
catch (Throwable t)
|
catch (Throwable t)
|
||||||
{
|
{
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -549,119 +545,71 @@ public class CustomRequestLog extends AbstractLifeCycle implements RequestLog
|
||||||
b.append(request.getRemoteAddr());
|
b.append(request.getRemoteAddr());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) throws Throwable
|
|
||||||
{
|
|
||||||
Request request = new Request(null, null);
|
|
||||||
|
|
||||||
|
|
||||||
String formatString = "clientIP: %a | ";
|
|
||||||
MethodHandle logHandle = getLogHandle(formatString);
|
|
||||||
|
|
||||||
|
|
||||||
StringBuilder b = new StringBuilder();
|
|
||||||
logHandle.invoke(b, request);
|
|
||||||
System.err.println(b.toString());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static MethodHandle getLogHandle(String formatString) throws NoSuchMethodException, IllegalAccessException
|
|
||||||
{
|
|
||||||
//TODO add response to signature
|
//TODO add response to signature
|
||||||
MethodType logType = methodType(Void.TYPE, StringBuilder.class, Request.class);
|
private static final MethodType LOG_TYPE = methodType(Void.TYPE, StringBuilder.class, Request.class);
|
||||||
|
|
||||||
|
private MethodHandle getLogHandle(String formatString) throws Throwable
|
||||||
|
{
|
||||||
MethodHandle append = MethodHandles.lookup().findStatic(CustomRequestLog.class, "append", methodType(Void.TYPE, String.class, StringBuilder.class));
|
MethodHandle append = MethodHandles.lookup().findStatic(CustomRequestLog.class, "append", methodType(Void.TYPE, String.class, StringBuilder.class));
|
||||||
MethodHandle logHandle = dropArguments(append.bindTo("\n"), 1, Request.class);
|
MethodHandle logHandle = dropArguments(append.bindTo("\n"), 1, Request.class);
|
||||||
|
|
||||||
for (Token s : tokenize(formatString))
|
|
||||||
{
|
|
||||||
if (s.isLiteralString())
|
|
||||||
{
|
|
||||||
logHandle = foldArguments(logHandle, dropArguments(append.bindTo(s.literal), 1, Request.class));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (s.code)
|
|
||||||
{
|
|
||||||
|
|
||||||
case "a":
|
|
||||||
{
|
|
||||||
String method = "logClientIP";
|
|
||||||
MethodHandle specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, logType);
|
|
||||||
logHandle = foldArguments(logHandle, specificHandle);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return logHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Token> tokenize(String value)
|
|
||||||
{
|
|
||||||
List<Token> tokens = new ArrayList<>();
|
|
||||||
|
|
||||||
final Pattern PERCENT_CODE = Pattern.compile("(?<remaining>.*)%(?:\\{(?<arg>[^{}]+)})?(?<code>[a-zA-Z%])");
|
final Pattern PERCENT_CODE = Pattern.compile("(?<remaining>.*)%(?:\\{(?<arg>[^{}]+)})?(?<code>[a-zA-Z%])");
|
||||||
final Pattern LITERAL = Pattern.compile("(?<remaining>.*%(?:\\{[^{}]+})?[a-zA-Z%])(?<literal>.*)");
|
final Pattern LITERAL = Pattern.compile("(?<remaining>.*%(?:\\{[^{}]+})?[a-zA-Z%])(?<literal>.*)");
|
||||||
|
|
||||||
while(value.length()>0)
|
String remaining = formatString;
|
||||||
|
while(remaining.length()>0)
|
||||||
{
|
{
|
||||||
Matcher m = PERCENT_CODE.matcher(value);
|
Matcher m = PERCENT_CODE.matcher(remaining);
|
||||||
Matcher m2 = LITERAL.matcher(value);
|
|
||||||
if (m.matches())
|
if (m.matches())
|
||||||
{
|
{
|
||||||
String code = m.group("code");
|
String code = m.group("code");
|
||||||
String arg = m.group("arg");
|
String arg = m.group("arg");
|
||||||
|
|
||||||
tokens.add(new Token(code, arg));
|
logHandle = updateLogHandle(logHandle, code, arg);
|
||||||
value = m.group("remaining");
|
remaining = m.group("remaining");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Matcher m2 = LITERAL.matcher(remaining);
|
||||||
String literal;
|
String literal;
|
||||||
if (m2.matches())
|
if (m2.matches())
|
||||||
{
|
{
|
||||||
literal = m2.group("literal");
|
literal = m2.group("literal");
|
||||||
value = m2.group("remaining");
|
remaining = m2.group("remaining");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
literal = value;
|
literal = remaining;
|
||||||
value = "";
|
remaining = "";
|
||||||
|
}
|
||||||
|
logHandle = updateLogHandle(logHandle, append, literal);
|
||||||
}
|
}
|
||||||
tokens.add(new Token(literal));
|
|
||||||
|
|
||||||
}
|
return logHandle;
|
||||||
return tokens;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private MethodHandle updateLogHandle(MethodHandle logHandle, MethodHandle append, String literal)
|
||||||
|
|
||||||
private static class Token
|
|
||||||
{
|
{
|
||||||
public boolean isLiteralString()
|
return foldArguments(logHandle, dropArguments(append.bindTo(literal), 1, Request.class));
|
||||||
{
|
|
||||||
return(literal != null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPercentCode()
|
|
||||||
|
private MethodHandle updateLogHandle(MethodHandle logHandle, String code, String arg) throws Throwable
|
||||||
{
|
{
|
||||||
return(code != null);
|
switch (code)
|
||||||
|
{
|
||||||
|
case "a":
|
||||||
|
{
|
||||||
|
String method = "logClientIP";
|
||||||
|
MethodHandle specificHandle = MethodHandles.lookup().findStatic(CustomRequestLog.class, method, LOG_TYPE);
|
||||||
|
return foldArguments(logHandle, specificHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String code = null;
|
default:
|
||||||
public String arg = null;
|
LOG.warn("Unsupported code %{}", code);
|
||||||
public String literal = null;
|
return logHandle;
|
||||||
|
|
||||||
public Token(String code, String arg)
|
|
||||||
{
|
|
||||||
this.code = code;
|
|
||||||
this.arg = arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Token(String literal)
|
|
||||||
{
|
|
||||||
this.literal = literal;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue