Extract the object o string rendering engine Refactor the generation of audit string entries: extract the rendering interface (AuditEvent to String) and put the current logic into a Csv rendering which is bound by default. Change-Id: Icbb1b30ca23a095c92f51c31d6aa509fd6cd11bd
diff --git a/src/main/java/com/googlesource/gerrit/plugins/auditsl4j/AuditFormatters.java b/src/main/java/com/googlesource/gerrit/plugins/auditsl4j/AuditFormatters.java new file mode 100644 index 0000000..4e3798b --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/auditsl4j/AuditFormatters.java
@@ -0,0 +1,51 @@ +// Copyright (C) 2018 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.googlesource.gerrit.plugins.auditsl4j; + +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +class AuditFormatters { + private static final SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss.SSSS"); + + @SuppressWarnings("serial") + private static final Map<Class<?>, AuditFormatter<?>> AUDIT_FORMATTERS = + Collections.unmodifiableMap( + new HashMap<Class<?>, AuditFormatter<? extends Object>>() { + { + put(HttpAuditEventFormat.CLASS, new HttpAuditEventFormat()); + put(RpcAuditEventFormat.CLASS, new RpcAuditEventFormat()); + put(SshAuditEventFormat.CLASS, new SshAuditEventFormat()); + put(AuditEventFormat.CLASS, new AuditEventFormat()); + } + }); + + public static <T> String getFormattedAuditSingle(T result) { + if (result == null) return ""; + + @SuppressWarnings("unchecked") + AuditFormatter<T> fmt = (AuditFormatter<T>) AUDIT_FORMATTERS.get(result.getClass()); + if (fmt == null) return result.toString(); + + return fmt.format(result); + } + + public static synchronized String getFormattedTS(long when) { + return dateFmt.format(new Date(when)); + } +}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/auditsl4j/AuditRenderer.java b/src/main/java/com/googlesource/gerrit/plugins/auditsl4j/AuditRenderer.java new file mode 100644 index 0000000..f89046e --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/auditsl4j/AuditRenderer.java
@@ -0,0 +1,24 @@ +// Copyright (C) 2018 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.googlesource.gerrit.plugins.auditsl4j; + +import com.google.gerrit.audit.AuditEvent; +import com.google.inject.ImplementedBy; + +@ImplementedBy(AuditRendererToCsv.class) +public interface AuditRenderer { + + String render(AuditEvent auditEvent); +}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/auditsl4j/AuditRendererToCsv.java b/src/main/java/com/googlesource/gerrit/plugins/auditsl4j/AuditRendererToCsv.java new file mode 100644 index 0000000..4f2a6e3 --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/auditsl4j/AuditRendererToCsv.java
@@ -0,0 +1,84 @@ +// Copyright (C) 2018 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.googlesource.gerrit.plugins.auditsl4j; + +import static com.googlesource.gerrit.plugins.auditsl4j.AuditFormatters.getFormattedAuditSingle; +import static com.googlesource.gerrit.plugins.auditsl4j.AuditFormatters.getFormattedTS; + +import com.google.common.collect.Multimap; +import com.google.gerrit.audit.AuditEvent; +import java.util.Collection; +import java.util.Set; +import java.util.TreeSet; + +public class AuditRendererToCsv implements AuditRenderer { + + @Override + public String render(AuditEvent auditEvent) { + return String.format( + "%1$s | %2$s | %3$s | %4$s | %5$s | %6$s | %7$s | %8$s | %9$s | %10$s", + auditEvent.uuid.uuid(), + getFormattedTS(auditEvent.when), + auditEvent.sessionId, + getFormattedAuditSingle(auditEvent.who), + getFormattedAuditSingle(auditEvent), + auditEvent.what, + getFormattedAuditList(auditEvent.params), + getFormattedAuditSingle(auditEvent.result), + getFormattedTS(auditEvent.timeAtStart), + auditEvent.elapsed); + } + + private Object getFormattedAuditList(Multimap<String, ?> params) { + if (params == null || params.size() == 0) { + return "[]"; + } + + StringBuilder formattedOut = new StringBuilder("["); + + Set<String> paramNames = new TreeSet<>(params.keySet()); + + int numParams = 0; + for (String paramName : paramNames) { + if (numParams++ > 0) { + formattedOut.append(","); + } + formattedOut.append(paramName); + formattedOut.append("="); + formattedOut.append(getFormattedAudit(params.get(paramName))); + } + + formattedOut.append(']'); + + return formattedOut.toString(); + } + + private Object getFormattedAudit(Collection<? extends Object> values) { + StringBuilder out = new StringBuilder(); + int numValues = 0; + for (Object object : values) { + if (numValues > 0) { + out.append(","); + } + out.append(getFormattedAuditSingle(object)); + numValues++; + } + + if (numValues > 1) { + return "[" + out.toString() + "]"; + } + return out.toString(); + } +}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/auditsl4j/LoggerAudit.java b/src/main/java/com/googlesource/gerrit/plugins/auditsl4j/LoggerAudit.java index bca501e..54e004d 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/auditsl4j/LoggerAudit.java +++ b/src/main/java/com/googlesource/gerrit/plugins/auditsl4j/LoggerAudit.java
@@ -14,44 +14,25 @@ package com.googlesource.gerrit.plugins.auditsl4j; -import com.google.common.collect.Multimap; import com.google.gerrit.audit.AuditEvent; import com.google.gerrit.audit.AuditListener; import com.google.gerrit.extensions.registration.DynamicSet; import com.google.inject.AbstractModule; import com.google.inject.Inject; import com.google.inject.Singleton; -import java.text.SimpleDateFormat; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; @Singleton public class LoggerAudit implements AuditListener { - private final SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss.SSSS"); private final AuditWriter auditWriter; + private final AuditRenderer auditRenderer; public static final String AUDIT_LOGGER_NAME = LoggerAudit.class.getName(); - @SuppressWarnings("serial") - private static final Map<Class<?>, AuditFormatter<?>> AUDIT_FORMATTERS = - Collections.unmodifiableMap( - new HashMap<Class<?>, AuditFormatter<? extends Object>>() { - { - put(HttpAuditEventFormat.CLASS, new HttpAuditEventFormat()); - put(RpcAuditEventFormat.CLASS, new RpcAuditEventFormat()); - put(SshAuditEventFormat.CLASS, new SshAuditEventFormat()); - put(AuditEventFormat.CLASS, new AuditEventFormat()); - } - }); - @Inject - LoggerAudit(AuditWriter auditWriter) { + LoggerAudit(AuditWriter auditWriter, AuditRenderer auditRenderer) { this.auditWriter = auditWriter; + this.auditRenderer = auditRenderer; + writeHeaders(auditWriter); } @@ -68,77 +49,8 @@ } @Override - public void onAuditableAction(AuditEvent action) { - auditWriter.write(getFormattedAudit(action)); - } - - private String getFormattedAudit(AuditEvent action) { - return String.format( - "%1$s | %2$s | %3$s | %4$s | %5$s | %6$s | %7$s | %8$s | %9$s | %10$s", - action.uuid.uuid(), - getFormattedTS(action.when), - action.sessionId, - getFormattedAuditSingle(action.who), - getFormattedAuditSingle(action), - action.what, - getFormattedAuditList(action.params), - getFormattedAuditSingle(action.result), - getFormattedTS(action.timeAtStart), - action.elapsed); - } - - private Object getFormattedAuditList(Multimap<String, ?> params) { - if (params == null || params.size() == 0) { - return "[]"; - } - - StringBuilder formattedOut = new StringBuilder("["); - - Set<String> paramNames = new TreeSet<>(params.keySet()); - - int numParams = 0; - for (String paramName : paramNames) { - if (numParams++ > 0) { - formattedOut.append(","); - } - formattedOut.append(paramName); - formattedOut.append("="); - formattedOut.append(getFormattedAudit(params.get(paramName))); - } - - formattedOut.append(']'); - - return formattedOut.toString(); - } - - private Object getFormattedAudit(Collection<? extends Object> values) { - StringBuilder out = new StringBuilder(); - int numValues = 0; - for (Object object : values) { - if (numValues > 0) { - out.append(","); - } - out.append(getFormattedAuditSingle(object)); - numValues++; - } - - if (numValues > 1) { - return "[" + out.toString() + "]"; - } - return out.toString(); - } - - private <T> String getFormattedAuditSingle(T result) { - if (result == null) return ""; - - @SuppressWarnings("unchecked") - AuditFormatter<T> fmt = (AuditFormatter<T>) AUDIT_FORMATTERS.get(result.getClass()); - if (fmt == null) return result.toString(); - - return fmt.format(result); - } - - private synchronized String getFormattedTS(long when) { - return dateFmt.format(new Date(when)); + public void onAuditableAction(AuditEvent auditEvent) { + String auditString = auditRenderer.render(auditEvent); + auditWriter.write(auditString); } }