Skip to content

Commit

Permalink
[WFCORE-671] : Using AuditLogHandler
Browse files Browse the repository at this point in the history
Providing an in-memory audit-logger to track configuration changes easily.
  • Loading branch information
ehsavoie committed Jul 21, 2015
1 parent 2071f31 commit 6a62f8b
Show file tree
Hide file tree
Showing 20 changed files with 2,291 additions and 899 deletions.
@@ -0,0 +1,185 @@
/*
* Copyright (C) 2015 Red Hat, inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.jboss.as.controller.audit;

import static org.jboss.as.controller.audit.AuditLogItemFormatter.TYPE_JMX;
import static org.jboss.as.controller.audit.JsonAuditLogItemFormatter.AS_VERSION;
import static org.jboss.as.controller.audit.JsonAuditLogItemFormatter.ERROR;
import static org.jboss.as.controller.audit.JsonAuditLogItemFormatter.METHOD_NAME;
import static org.jboss.as.controller.audit.JsonAuditLogItemFormatter.METHOD_PARAMETERS;
import static org.jboss.as.controller.audit.JsonAuditLogItemFormatter.METHOD_SIGNATURE;
import static org.jboss.as.controller.audit.JsonAuditLogItemFormatter.REMOTE_ADDRESS;
import static org.jboss.as.controller.audit.JsonAuditLogItemFormatter.TYPE;
import static org.jboss.as.controller.audit.JsonAuditLogItemFormatter.USER_ID;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ACCESS_MECHANISM;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DOMAIN_UUID;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.FAILED;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OPERATIONS;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OUTCOME;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.READ_ONLY;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SUCCESS;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.jboss.as.controller.OperationContext;
import org.jboss.dmr.ModelNode;

/**
*
* @author <a href="mailto:ehugonne@redhat.com">Emmanuel Hugonnet</a> (c) 2015 Red Hat, inc.
*/
public final class InMemoryAuditLogHander extends AuditLogHandler {

public static final String OPERATION_DATE = "operation-date";
private static final ModelNode UNDEFINED = new ModelNode();

static {
UNDEFINED.protect();
}
private static final String IN_MEMORY_FORMATTER_NAME = "in-memory-formatter";
private final List<ModelNode> items;
private final int maxHistory;
private final AuditLogItemFormatter myFormatter = new InMemoryFormatter();

public InMemoryAuditLogHander(String name, int maxHistory) {
super(name, IN_MEMORY_FORMATTER_NAME, maxHistory);
items = new ArrayList<>(maxHistory);
this.maxHistory = maxHistory;
setFormatter(myFormatter);
}

public List<ModelNode> getItems() {
return Collections.unmodifiableList(items);
}

@Override
void setFormatter(AuditLogItemFormatter formatter) {
if (formatter != null) {
super.setFormatter(formatter);
} else {
super.setFormatter(myFormatter);
}
}

public AuditLogItemFormatter getFormatter() {
return myFormatter;
}

@Override
boolean isDifferent(AuditLogHandler other) {
if (other instanceof InMemoryAuditLogHander == false) {
return true;
}
return getName().equals(other.getName());
}

private void addItem(ModelNode item) {
if (items.size() == maxHistory) {
items.remove(0);
}
items.add(item);
}

@Override
void initialize() {
}

@Override
void stop() {
items.clear();
}

@Override
void writeLogItem(String formattedItem) throws IOException {
}

private class InMemoryFormatter extends AuditLogItemFormatter {

public static final String BOOTING = "booting";

public InMemoryFormatter() {
super(IN_MEMORY_FORMATTER_NAME, true, "", "yyyy-MM-dd hh:mm:ss");
}

@Override
String formatAuditLogItem(AuditLogItem.ModelControllerAuditLogItem item) {
ModelNode entry = new ModelNode().setEmptyObject();
entry.get(TYPE).set(TYPE_CORE);
addCommonFields(entry, item);
entry.get(OUTCOME).set(item.getResultAction() == OperationContext.ResultAction.KEEP ? SUCCESS : FAILED);
if (item.getOperations() != null && !item.getOperations().isEmpty()) {
ModelNode operations = entry.get(OPERATIONS).setEmptyList();
item.getOperations().stream().forEach((op) -> {
operations.add(op);
});
}
addItem(entry);
return entry.asString();
}

@Override
String formatAuditLogItem(AuditLogItem.JmxAccessAuditLogItem item) {
ModelNode entry = new ModelNode();
entry.get(TYPE).set(TYPE_JMX);
addCommonFields(entry, item);
entry.get(METHOD_NAME).set(item.getMethodName());
entry.get(METHOD_SIGNATURE);
for (String sig : item.getMethodSignature()) {
entry.get(METHOD_SIGNATURE).add(sig);
}
entry.get(METHOD_PARAMETERS);
for (Object param : item.getMethodParams()) {
//TODO handle arrays better
entry.get(METHOD_PARAMETERS).add(param == null ? UNDEFINED : new ModelNode(param.toString()));
}
final Throwable throwable = item.getError();
if (throwable != null) {
//TODO include stack trace?
entry.get(ERROR).set(throwable.getMessage());
}
addItem(entry);
return entry.asString();
}

private void addCommonFields(ModelNode entry, AuditLogItem item) {
StringBuilder buffer = new StringBuilder(20);
appendDate(buffer, item);
entry.get(OPERATION_DATE).set(buffer.toString());
entry.get(READ_ONLY).set(item.isReadOnly());
entry.get(BOOTING).set(item.isBooting());
entry.get(AS_VERSION).set(item.getAsVersion());
if (item.getUserId() != null) {
entry.get(USER_ID).set(item.getUserId());
}
if (item.getDomainUUID() != null) {
entry.get(DOMAIN_UUID).set(item.getDomainUUID());
}
if (item.getAccessMechanism() != null) {
entry.get(ACCESS_MECHANISM).set(item.getAccessMechanism().toString());
}
if (item.getRemoteAddress() != null) {
entry.get(REMOTE_ADDRESS).set(item.getRemoteAddress().toString());
}
}
}
}
Expand Up @@ -205,6 +205,7 @@ public class ModelDescriptionConstants {
public static final String IGNORED_RESOURCES = "ignored-resources";
public static final String IGNORED_RESOURCE_TYPE = "ignored-resource-type";
public static final String IGNORE_UNUSED_CONFIG = "ignore-unused-configuration";
public static final String IN_MEMORY_HANDLER="in-memory-handler";
public static final String IN_SERIES = "in-series";
public static final String INCLUDE = "include";
public static final String INCLUDE_ALL = "include-all";
Expand Down
Expand Up @@ -32,6 +32,7 @@
*/
public enum Element {
// must be first
// must be first
UNKNOWN(null),

// Domain elements in alpha order
Expand Down Expand Up @@ -92,6 +93,7 @@ public enum Element {
HTTP_INTERFACE("http-interface"),

IGNORED_RESOURCE("ignored-resources"),
IN_MEMORY_HANDLER("in-memory-handler"),
INCLUDE("include"),
INSTANCE("instance"),
INET_ADDRESS("inet-address"),
Expand Down
Expand Up @@ -65,13 +65,15 @@
<syslog-handler name="syslog-tls-default" formatter="json-one">
<tls/>
</syslog-handler>
<in-memory-handler name="in-memory" max-history="10"/>
</handlers>
<logger log-boot="${config.log-boot:true}" log-read-only="${config.read-only:true}" enabled="${config.enabled:true}">
<handlers>
<handler name="file1"/>
<handler name="periodic-file2"/>
<handler name="size-file2"/>
<handler name="syslog-udp"/>
<handler name="in-memory"/>
</handlers>
</logger>
<server-logger log-boot="${config.log-boot:true}" log-read-only="${config.read-only:true}" enabled="${config.enabled:true}">
Expand All @@ -81,6 +83,7 @@
<handler name="size-file2"/>
<handler name="syslog-udp"/>
<handler name="syslog-tcp"/>
<handler name="in-memory"/>
</handlers>
</server-logger>
</audit-log>
Expand Down
Expand Up @@ -41,6 +41,7 @@
<syslog-handler name="syslog-tls-default" formatter="json-two" >
<tls/>
</syslog-handler>
<in-memory-handler name="in-memory" max-history="10"/>
</handlers>
<logger log-boot="${config.log-boot:true}" log-read-only="${config.read-only:true}" enabled="${config.enabled:true}">
<handlers>
Expand All @@ -51,6 +52,7 @@
<handler name="size-file1"/>
<handler name="size-file2"/>
<handler name="syslog-udp"/>
<handler name="in-memory"/>
</handlers>
</logger>
</audit-log>
Expand Down
Expand Up @@ -76,6 +76,7 @@ public void registerChildren(ManagementResourceRegistration resourceRegistration
resourceRegistration.registerSubModel(new PeriodicRotatingFileAuditLogHandlerResourceDefinition(auditLogger, pathManager));
resourceRegistration.registerSubModel(new SizeRotatingFileAuditLogHandlerResourceDefinition(auditLogger, pathManager));
resourceRegistration.registerSubModel(new SyslogAuditLogHandlerResourceDefinition(auditLogger, pathManager, environmentReader));
resourceRegistration.registerSubModel(new InMemoryAuditLogHandlerResourceDefinition(auditLogger));
resourceRegistration.registerSubModel(AuditLogLoggerResourceDefinition.createDefinition(auditLogger));
if (!environmentReader.isServer()){
resourceRegistration.registerSubModel(AuditLogLoggerResourceDefinition.createHostServerDefinition(auditLogger));
Expand Down
Expand Up @@ -22,6 +22,7 @@
package org.jboss.as.domain.management.audit;

import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.FILE_HANDLER;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.IN_MEMORY_HANDLER;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.PERIODIC_ROTATING_FILE_HANDLER;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.SIZE_ROTATING_FILE_HANDLER;
Expand Down Expand Up @@ -83,7 +84,7 @@ public class AuditLogHandlerResourceDefinition extends SimpleResourceDefinition

private static final AttributeDefinition[] RUNTIME_ATTRIBUTES = new AttributeDefinition[] {FAILURE_COUNT, DISABLED_DUE_TO_FAILURE};

static final String[] HANDLER_TYPES = new String[] {FILE_HANDLER, SYSLOG_HANDLER, PERIODIC_ROTATING_FILE_HANDLER, SIZE_ROTATING_FILE_HANDLER};
static final String[] HANDLER_TYPES = new String[] {FILE_HANDLER, SYSLOG_HANDLER, PERIODIC_ROTATING_FILE_HANDLER, SIZE_ROTATING_FILE_HANDLER, IN_MEMORY_HANDLER};

protected final ManagedAuditLogger auditLogger;
protected final PathManagerService pathManager;
Expand Down

0 comments on commit 6a62f8b

Please sign in to comment.