On Thu, Jan 21, 2021 at 03:28:12PM +0100, Romain Manni-Bucau wrote:
> Hi
Hi,
> Why cant it be added as element earlier at pattern parsing time? Would
> avoid to have two particular cases and keep current pattern/impl.
> A %java or so sounds more natural no?
Mhh, maybe I just share my idea of the concrete implementation, so you see
what I want to do:
Premise: The JUL logging is configured to log all below to an own handler.
public class LoggingAccessLogValve extends AbstractAccessLogValve {
private static final Log log =
LogFactory.getLog(LoggingAccessLogValve.class);
private Map writers = new
WeakHashMap<>();
@Override
protected void log(CharArrayWriter message) {
if(log.isInfoEnabled()) {
log.info(message);
}
}
protected void preLogAddElement(CharArrayWriter result) {
JsonGenerator jsonWriter = Json.createGenerator(result);
synchronized (this) {
writers.put(result,jsonWriter);
}
jsonWriter.writeStartObject();
}
protected void postLogAddElement(CharArrayWriter result) {
JsonGenerator jsonWriter = null;
synchronized (this) {
jsonWriter = writers.remove(result);
}
if(jsonWriter != null) {
jsonWriter.writeEnd();
jsonWriter.close();
}
}
private class JsonAccessLogElementWrapper implements AccessLogElement {
private final String jsonAttributeName;
private final AccessLogElement delegate;
public JsonAccessLogElementWrapper(AccessLogElement e, String
name) {
delegate = e;
jsonAttributeName = name;
}
@Override
public void addElement(CharArrayWriter buf, Date date, Request
request, Response response, long time) {
JsonGenerator jsonWriter = null;
synchronized (this) {
jsonWriter = writers.get(buf);
}
if(jsonWriter == null) {
// TODO: add warn
return;
}
// TODO: maybe even use stack/cache of CharyArrayWriter
here, too
CharArrayWriter writer = new CharArrayWriter();
delegate.addElement(writer, date, request, response,
time);
jsonWriter.write(jsonAttributeName, writer.toString());
}
}
@Override
protected AccessLogElement createAccessLogElement(String name, char
pattern) {
AccessLogElement e = super.createAccessLogElement(name,
pattern);
return new JsonAccessLogElementWrapper(e, mapName(e) + '-' +
name);
}
@Override
protected AccessLogElement createAccessLogElement(char pattern) {
AccessLogElement e = super.createAccessLogElement(pattern);
return new JsonAccessLogElementWrapper(e, mapName(e));
}
private String mapName(AccessLogElement e) {
if(e instanceof RemoteAddrElement) {
return "remoteAddr";
} else if(e instanceof HostElement) {
return "host";
// TODO: finish
}
throw new IllegalArgumentException();
}
}
so what do you think about this approach?
mfg
thomas
>
> Le jeu. 21 janv. 2021 à 13:59, Thomas Meyer a écrit :
>
> > a sub class can extend before and after the addElement loop to
> > establish a context via thread-dependend CharArrayWriter object.
> > ---
> > java/org/apache/catalina/valves/AbstractAccessLogValve.java | 5 +
> > 1 file changed, 5 insertions(+)
> >
> > diff --git a/java/org/apache/catalina/valves/AbstractAccessLogValve.java
> > b/java/org/apache/catalina/valves/AbstractAccessLogValve.java
> > index e23f49d3a5..5e774c2320 100644
> > --- a/java/org/apache/catalina/valves/AbstractAccessLogValve.java
> > +++ b/java/org/apache/catalina/valves/AbstractAccessLogValve.java
> > @@ -685,9 +685,11 @@ public abstract class AbstractAccessLogValve extends
> > ValveBase implements Access
> > result = new CharArrayWriter(128);
> > }
> >
> > +preLogAddElement(result);
> > for (int i = 0; i < logElements.length; i++) {
> > logElements[i].addElement(result, date, request, response,
> > time);
> >