HDDS-198. Create AuditLogger mechanism to be used by OM, SCM and Datanode.
Contributed by Dinesh Chitlangia.
This commit is contained in:
parent
51654a3962
commit
c0ef7e7680
@ -31,6 +31,8 @@ http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<properties>
|
||||
<hadoop.component>hdds</hadoop.component>
|
||||
<is.hadoop.component>true</is.hadoop.component>
|
||||
<log4j2.version>2.11.0</log4j2.version>
|
||||
<disruptor.version>3.4.2</disruptor.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@ -81,6 +83,22 @@ http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<type>test-jar</type>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-api</artifactId>
|
||||
<version>${log4j2.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>${log4j2.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.lmax</groupId>
|
||||
<artifactId>disruptor</artifactId>
|
||||
<version>${disruptor.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to you 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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 org.apache.hadoop.ozone.audit;
|
||||
|
||||
/**
|
||||
* Interface to define AuditAction.
|
||||
*/
|
||||
public interface AuditAction {
|
||||
/**
|
||||
* Implementation must override.
|
||||
* @return String
|
||||
*/
|
||||
String getAction();
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.hadoop.ozone.audit;
|
||||
|
||||
/**
|
||||
* Enum to define AuditEventStatus values.
|
||||
*/
|
||||
public enum AuditEventStatus {
|
||||
SUCCESS("SUCCESS"),
|
||||
FAILURE("FAILURE");
|
||||
|
||||
private String status;
|
||||
|
||||
AuditEventStatus(String status){
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to you 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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 org.apache.hadoop.ozone.audit;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Marker;
|
||||
import org.apache.logging.log4j.message.StructuredDataMessage;
|
||||
import org.apache.logging.log4j.spi.ExtendedLogger;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Class to define Audit Logger for Ozone.
|
||||
*/
|
||||
public class AuditLogger {
|
||||
|
||||
private ExtendedLogger logger;
|
||||
|
||||
private static final String SUCCESS = AuditEventStatus.SUCCESS.getStatus();
|
||||
private static final String FAILURE = AuditEventStatus.FAILURE.getStatus();
|
||||
private static final String FQCN = AuditLogger.class.getName();
|
||||
private static final Marker WRITE_MARKER = AuditMarker.WRITE.getMarker();
|
||||
private static final Marker READ_MARKER = AuditMarker.READ.getMarker();
|
||||
|
||||
/**
|
||||
* Parametrized Constructor to initialize logger.
|
||||
* @param type
|
||||
*/
|
||||
public AuditLogger(AuditLoggerType type){
|
||||
initializeLogger(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the logger with specific type.
|
||||
* @param loggerType specified one of the values from enum AuditLoggerType.
|
||||
*/
|
||||
private void initializeLogger(AuditLoggerType loggerType){
|
||||
this.logger = LogManager.getContext(false).getLogger(loggerType.getType());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public ExtendedLogger getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
public void logWriteSuccess(AuditAction type, Map<String, String> data) {
|
||||
logWriteSuccess(type, data, Level.INFO);
|
||||
}
|
||||
|
||||
public void logWriteSuccess(AuditAction type, Map<String, String> data, Level
|
||||
level) {
|
||||
StructuredDataMessage msg = new StructuredDataMessage("", SUCCESS,
|
||||
type.getAction(), data);
|
||||
this.logger.logIfEnabled(FQCN, level, WRITE_MARKER, msg, null);
|
||||
}
|
||||
|
||||
|
||||
public void logWriteFailure(AuditAction type, Map<String, String> data) {
|
||||
logWriteFailure(type, data, Level.INFO, null);
|
||||
}
|
||||
|
||||
public void logWriteFailure(AuditAction type, Map<String, String> data, Level
|
||||
level) {
|
||||
logWriteFailure(type, data, level, null);
|
||||
}
|
||||
|
||||
public void logWriteFailure(AuditAction type, Map<String, String> data,
|
||||
Throwable exception) {
|
||||
logWriteFailure(type, data, Level.INFO, exception);
|
||||
}
|
||||
|
||||
public void logWriteFailure(AuditAction type, Map<String, String> data, Level
|
||||
level, Throwable exception) {
|
||||
StructuredDataMessage msg = new StructuredDataMessage("", FAILURE,
|
||||
type.getAction(), data);
|
||||
this.logger.logIfEnabled(FQCN, level, WRITE_MARKER, msg, exception);
|
||||
}
|
||||
|
||||
public void logReadSuccess(AuditAction type, Map<String, String> data) {
|
||||
logReadSuccess(type, data, Level.INFO);
|
||||
}
|
||||
|
||||
public void logReadSuccess(AuditAction type, Map<String, String> data, Level
|
||||
level) {
|
||||
StructuredDataMessage msg = new StructuredDataMessage("", SUCCESS,
|
||||
type.getAction(), data);
|
||||
this.logger.logIfEnabled(FQCN, level, READ_MARKER, msg, null);
|
||||
}
|
||||
|
||||
public void logReadFailure(AuditAction type, Map<String, String> data) {
|
||||
logReadFailure(type, data, Level.INFO, null);
|
||||
}
|
||||
|
||||
public void logReadFailure(AuditAction type, Map<String, String> data, Level
|
||||
level) {
|
||||
logReadFailure(type, data, level, null);
|
||||
}
|
||||
|
||||
public void logReadFailure(AuditAction type, Map<String, String> data,
|
||||
Throwable exception) {
|
||||
logReadFailure(type, data, Level.INFO, exception);
|
||||
}
|
||||
|
||||
public void logReadFailure(AuditAction type, Map<String, String> data, Level
|
||||
level, Throwable exception) {
|
||||
StructuredDataMessage msg = new StructuredDataMessage("", FAILURE,
|
||||
type.getAction(), data);
|
||||
this.logger.logIfEnabled(FQCN, level, READ_MARKER, msg, exception);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to you 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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 org.apache.hadoop.ozone.audit;
|
||||
|
||||
/**
|
||||
* Enumeration for defining types of Audit Loggers in Ozone.
|
||||
*/
|
||||
public enum AuditLoggerType {
|
||||
DNLOGGER("DNAudit"),
|
||||
OMLOGGER("OMAudit"),
|
||||
SCMLOGGER("SCMAudit");
|
||||
|
||||
private String type;
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
AuditLoggerType(String type){
|
||||
this.type = type;
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to you 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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 org.apache.hadoop.ozone.audit;
|
||||
|
||||
import org.apache.logging.log4j.Marker;
|
||||
import org.apache.logging.log4j.MarkerManager;
|
||||
|
||||
/**
|
||||
* Defines audit marker types.
|
||||
*/
|
||||
public enum AuditMarker {
|
||||
WRITE(MarkerManager.getMarker("WRITE")),
|
||||
READ(MarkerManager.getMarker("READ"));
|
||||
|
||||
private Marker marker;
|
||||
|
||||
AuditMarker(Marker marker){
|
||||
this.marker = marker;
|
||||
}
|
||||
|
||||
public Marker getMarker(){
|
||||
return marker;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to you 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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 org.apache.hadoop.ozone.audit;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Interface to make an entity auditable.
|
||||
*/
|
||||
public interface Auditable {
|
||||
/**
|
||||
* Must override in implementation.
|
||||
* @return Map<String, String> with values to be logged in audit.
|
||||
*/
|
||||
Map<String, String> toAuditMap();
|
||||
}
|
||||
|
@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to you 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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 org.apache.hadoop.ozone.audit;
|
||||
/**
|
||||
******************************************************************************
|
||||
* Important
|
||||
* 1. Any changes to classes in this package can render the logging
|
||||
* framework broken.
|
||||
* 2. The logger framework has been designed keeping in mind future
|
||||
* plans to build a log parser.
|
||||
* 3. Please exercise great caution when attempting changes in this package.
|
||||
******************************************************************************
|
||||
*
|
||||
*
|
||||
* This package lays the foundation for Audit logging in Ozone.
|
||||
* AuditLogging in Ozone has been built using log4j2 which brings in new
|
||||
* features that facilitate turning on/off selective audit events by using
|
||||
* MarkerFilter, checking for change in logging configuration periodically
|
||||
* and reloading the changes, use of disruptor framework for improved
|
||||
* Asynchronous logging.
|
||||
*
|
||||
* The log4j2 configurations can be specified in XML, YAML, JSON and
|
||||
* Properties file. For Ozone, we are using the Properties file due to sheer
|
||||
* simplicity, readability and ease of modification.
|
||||
*
|
||||
* log4j2 configuration file can be passed to startup command with option
|
||||
* -Dlog4j.configurationFile unlike -Dlog4j.configuration in log4j 1.x
|
||||
*
|
||||
******************************************************************************
|
||||
* Understanding the Audit Logging framework in Ozone.
|
||||
******************************************************************************
|
||||
* **** Auditable ***
|
||||
* This is an interface to mark an entity as auditable.
|
||||
* This interface must be implemented by entities requiring audit logging.
|
||||
* For example - KSMVolumeArgs, KSMBucketArgs.
|
||||
* The implementing class must override toAuditMap() to return an
|
||||
* instance of Map<Key, Value> where both Key and Value are String.
|
||||
*
|
||||
* Key: must not contain any spaces. If the key is multi word then use
|
||||
* camel case.
|
||||
* Value: if it is a collection/array, then it must be converted to a comma
|
||||
* delimited string
|
||||
*
|
||||
* *** AuditAction ***
|
||||
* This is an interface to define the various type of actions to be audited.
|
||||
* To ensure separation of concern, for each sub-component you must create an
|
||||
* Enum to implement AuditAction.
|
||||
* Structure of Enum can be referred from the test class DummyAction.
|
||||
*
|
||||
* For starters, we expect following 3 implementations of AuditAction:
|
||||
* OMAction - to define action types for Ozone Manager
|
||||
* SCMAction - to define action types for Storage Container manager
|
||||
* DNAction - to define action types for Datanode
|
||||
*
|
||||
* *** AuditEventStatus ***
|
||||
* Enum to define Audit event status like success and failure.
|
||||
* This is used in AuditLogger.logXXX() methods.
|
||||
*
|
||||
* * *** AuditLogger ***
|
||||
* This is where the audit logging magic unfolds.
|
||||
* The class has 2 Markers defined - READ and WRITE.
|
||||
* These markers are used to tag when logging events.
|
||||
*
|
||||
* *** AuditLoggerType ***
|
||||
* Enum to define the various AuditLoggers in Ozone
|
||||
*
|
||||
* *** AuditMarker ***
|
||||
* Enum to define various Audit Markers used in AuditLogging.
|
||||
*
|
||||
* ****************************************************************************
|
||||
* Usage
|
||||
* ****************************************************************************
|
||||
* Using the AuditLogger to log events:
|
||||
* 1. Get a logger by specifying the appropriate logger type
|
||||
* Example: ExtendedLogger AUDIT = new AuditLogger(AuditLoggerType.OMLogger)
|
||||
*
|
||||
* 2. Log Read/Write and Success/Failure event as needed.
|
||||
* Example
|
||||
* AUDIT.logWriteSuccess(AuditAction type, Map<String, String> data, Level
|
||||
* level)
|
||||
*
|
||||
* If logging is done without specifying Level, then Level implicitly
|
||||
* defaults to INFO
|
||||
* AUDIT.logWriteSuccess(AuditAction type, Map<String, String> data)
|
||||
*
|
||||
* See sample invocations in src/test in the following class:
|
||||
* org.apache.hadoop.ozone.audit.TestOzoneAuditLogger
|
||||
*
|
||||
* ****************************************************************************
|
||||
* Defining new Logger types
|
||||
* ****************************************************************************
|
||||
* New Logger type can be added with following steps:
|
||||
* 1. Update AuditLoggerType to add the new type
|
||||
* 2. Create new Enum by implementing AuditAction if needed
|
||||
* 3. Ensure the required entity implements Auditable
|
||||
*
|
||||
* ****************************************************************************
|
||||
* Defining new Marker types
|
||||
* ****************************************************************************
|
||||
* New Markers can be configured as follows:
|
||||
* 1. Define new markers in AuditMarker
|
||||
* 2. Get the Marker in AuditLogger for use in the log methods, example:
|
||||
* private static final Marker WRITE_MARKER = AuditMarker.WRITE.getMarker();
|
||||
* 3. Define log methods in AuditLogger to use the new Marker type
|
||||
* 4. Call these new methods from the required classes to audit with these
|
||||
* new markers
|
||||
* 5. The marker based filtering can be configured in log4j2 configurations
|
||||
* Refer log4j2.properties in src/test/resources for a sample.
|
||||
*/
|
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to you 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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 org.apache.hadoop.ozone.audit;
|
||||
|
||||
/**
|
||||
* Enum to define Dummy AuditAction Type for test.
|
||||
*/
|
||||
public enum DummyAction implements AuditAction {
|
||||
|
||||
CREATE_VOLUME("CREATE_VOLUME"),
|
||||
CREATE_BUCKET("CREATE_BUCKET"),
|
||||
CREATE_KEY("CREATE_KEY"),
|
||||
READ_VOLUME("READ_VOLUME"),
|
||||
READ_BUCKET("READ_BUCKET"),
|
||||
READ_KEY("READ_BUCKET"),
|
||||
UPDATE_VOLUME("UPDATE_VOLUME"),
|
||||
UPDATE_BUCKET("UPDATE_BUCKET"),
|
||||
UPDATE_KEY("UPDATE_KEY"),
|
||||
DELETE_VOLUME("DELETE_VOLUME"),
|
||||
DELETE_BUCKET("DELETE_BUCKET"),
|
||||
DELETE_KEY("DELETE_KEY"),
|
||||
SET_OWNER("SET_OWNER"),
|
||||
SET_QUOTA("SET_QUOTA");
|
||||
|
||||
private String action;
|
||||
|
||||
DummyAction(String action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAction() {
|
||||
return this.action;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to you 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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 org.apache.hadoop.ozone.audit;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* DummyEntity that implements Auditable for test purpose.
|
||||
*/
|
||||
public class DummyEntity implements Auditable {
|
||||
|
||||
private String key1;
|
||||
private String key2;
|
||||
|
||||
public DummyEntity(){
|
||||
this.key1 = "value1";
|
||||
this.key2 = "value2";
|
||||
}
|
||||
public String getKey1() {
|
||||
return key1;
|
||||
}
|
||||
|
||||
public void setKey1(String key1) {
|
||||
this.key1 = key1;
|
||||
}
|
||||
|
||||
public String getKey2() {
|
||||
return key2;
|
||||
}
|
||||
|
||||
public void setKey2(String key2) {
|
||||
this.key2 = key2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> toAuditMap() {
|
||||
Map<String, String> auditMap = new HashMap<>();
|
||||
auditMap.put("key1", this.key1);
|
||||
auditMap.put("key2", this.key2);
|
||||
return auditMap;
|
||||
}
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.hadoop.ozone.audit;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Test Ozone Audit Logger.
|
||||
*/
|
||||
public class TestOzoneAuditLogger {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger
|
||||
(TestOzoneAuditLogger.class.getName());
|
||||
private static AuditLogger AUDIT = new AuditLogger(AuditLoggerType.OMLOGGER);
|
||||
public DummyEntity auditableObj = new DummyEntity();
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp(){
|
||||
System.setProperty("log4j.configurationFile", "log4j2.properties");
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDown() {
|
||||
File file = new File("audit.log");
|
||||
if (FileUtils.deleteQuietly(file)) {
|
||||
LOG.info(file.getName() +
|
||||
" has been deleted as all tests have completed.");
|
||||
} else {
|
||||
LOG.info("audit.log could not be deleted.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures WriteSuccess events are logged @ INFO and above.
|
||||
*/
|
||||
@Test
|
||||
public void logInfoWriteSuccess() throws IOException {
|
||||
AUDIT.logWriteSuccess(DummyAction.CREATE_VOLUME, auditableObj.toAuditMap(), Level.INFO);
|
||||
String expected = "[INFO ] OMAudit - CREATE_VOLUME [ key1=\"value1\" " +
|
||||
"key2=\"value2\"] SUCCESS";
|
||||
verifyLog(expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to verify default log level is INFO
|
||||
*/
|
||||
@Test
|
||||
public void verifyDefaultLogLevel() throws IOException {
|
||||
AUDIT.logWriteSuccess(DummyAction.CREATE_VOLUME, auditableObj.toAuditMap());
|
||||
String expected = "[INFO ] OMAudit - CREATE_VOLUME [ key1=\"value1\" " +
|
||||
"key2=\"value2\"] SUCCESS";
|
||||
verifyLog(expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to verify WriteFailure events are logged as ERROR.
|
||||
*/
|
||||
@Test
|
||||
public void logErrorWriteFailure() throws IOException {
|
||||
AUDIT.logWriteFailure(DummyAction.CREATE_VOLUME, auditableObj.toAuditMap(), Level.ERROR);
|
||||
String expected = "[ERROR] OMAudit - CREATE_VOLUME [ key1=\"value1\" " +
|
||||
"key2=\"value2\"] FAILURE";
|
||||
verifyLog(expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to verify no READ event is logged.
|
||||
*/
|
||||
@Test
|
||||
public void notLogReadEvents() throws IOException {
|
||||
AUDIT.logReadSuccess(DummyAction.READ_VOLUME, auditableObj.toAuditMap(), Level.INFO);
|
||||
AUDIT.logReadFailure(DummyAction.READ_VOLUME, auditableObj.toAuditMap(), Level.INFO);
|
||||
AUDIT.logReadFailure(DummyAction.READ_VOLUME, auditableObj.toAuditMap(), Level.ERROR);
|
||||
AUDIT.logReadFailure(DummyAction.READ_VOLUME, auditableObj.toAuditMap(), Level.ERROR,
|
||||
new Exception("test"));
|
||||
verifyLog(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to ensure DEBUG level messages are not logged when INFO is enabled.
|
||||
*/
|
||||
@Test
|
||||
public void notLogDebugEvents() throws IOException {
|
||||
AUDIT.logWriteSuccess(DummyAction.CREATE_VOLUME, auditableObj.toAuditMap(), Level.DEBUG);
|
||||
AUDIT.logReadSuccess(DummyAction.READ_VOLUME, auditableObj.toAuditMap(), Level.DEBUG);
|
||||
verifyLog(null);
|
||||
}
|
||||
|
||||
public void verifyLog(String expected) throws IOException {
|
||||
File file = new File("audit.log");
|
||||
List<String> lines = FileUtils.readLines(file, (String)null);
|
||||
if(expected == null){
|
||||
// When no log entry is expected, the log file must be empty
|
||||
assertTrue(lines.size() == 0);
|
||||
} else {
|
||||
// When log entry is expected, the log file will contain one line and
|
||||
// that must be equal to the expected string
|
||||
assertTrue(expected.equalsIgnoreCase(lines.get(0)));
|
||||
//empty the file
|
||||
lines.remove(0);
|
||||
FileUtils.writeLines(file, lines, false);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you 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 org.apache.hadoop.ozone.audit;
|
||||
/**
|
||||
* Unit tests of Ozone Audit Logger.
|
||||
* For test purpose, the log4j2 configuration is loaded from file at:
|
||||
* src/test/resources/log4j2.properties
|
||||
*/
|
76
hadoop-hdds/common/src/test/resources/log4j2.properties
Normal file
76
hadoop-hdds/common/src/test/resources/log4j2.properties
Normal file
@ -0,0 +1,76 @@
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with this
|
||||
# work for additional information regarding copyright ownership. The ASF
|
||||
# licenses this file to you 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
|
||||
# <p>
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
# <p>
|
||||
# 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.
|
||||
#
|
||||
name=PropertiesConfig
|
||||
|
||||
# Checks for config change periodically and reloads
|
||||
monitorInterval=5
|
||||
|
||||
filter=read, write
|
||||
# filter.read.onMatch = DENY avoids logging all READ events
|
||||
# filter.read.onMatch = ACCEPT permits logging all READ events
|
||||
# The above two settings ignore the log levels in configuration
|
||||
# filter.read.onMatch = NEUTRAL permits logging of only those READ events
|
||||
# which are attempted at log level equal or greater than log level specified
|
||||
# in the configuration
|
||||
filter.read.type = MarkerFilter
|
||||
filter.read.marker = READ
|
||||
filter.read.onMatch = DENY
|
||||
filter.read.onMismatch = NEUTRAL
|
||||
|
||||
# filter.write.onMatch = DENY avoids logging all WRITE events
|
||||
# filter.write.onMatch = ACCEPT permits logging all WRITE events
|
||||
# The above two settings ignore the log levels in configuration
|
||||
# filter.write.onMatch = NEUTRAL permits logging of only those WRITE events
|
||||
# which are attempted at log level equal or greater than log level specified
|
||||
# in the configuration
|
||||
filter.write.type = MarkerFilter
|
||||
filter.write.marker = WRITE
|
||||
filter.write.onMatch = NEUTRAL
|
||||
filter.write.onMismatch = NEUTRAL
|
||||
|
||||
# Log Levels are organized from most specific to least:
|
||||
# OFF (most specific, no logging)
|
||||
# FATAL (most specific, little data)
|
||||
# ERROR
|
||||
# WARN
|
||||
# INFO
|
||||
# DEBUG
|
||||
# TRACE (least specific, a lot of data)
|
||||
# ALL (least specific, all data)
|
||||
|
||||
appenders = console, audit
|
||||
appender.console.type = Console
|
||||
appender.console.name = STDOUT
|
||||
appender.console.layout.type = PatternLayout
|
||||
appender.console.layout.pattern = [%-5level] %c{1} - %msg%n
|
||||
|
||||
appender.audit.type = File
|
||||
appender.audit.name = AUDITLOG
|
||||
appender.audit.fileName=audit.log
|
||||
appender.audit.layout.type=PatternLayout
|
||||
appender.audit.layout.pattern= [%-5level] %c{1} - %msg%n
|
||||
|
||||
loggers=audit
|
||||
logger.audit.type=AsyncLogger
|
||||
logger.audit.name=OMAudit
|
||||
logger.audit.level = INFO
|
||||
logger.audit.appenderRefs = audit
|
||||
logger.audit.appenderRef.file.ref = AUDITLOG
|
||||
|
||||
rootLogger.level = INFO
|
||||
rootLogger.appenderRefs = stdout
|
||||
rootLogger.appenderRef.stdout.ref = STDOUT
|
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to you 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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 org.apache.hadoop.ozone.audit;
|
||||
|
||||
/**
|
||||
* Enum to define OM Action types for Audit.
|
||||
*/
|
||||
public enum OMAction implements AuditAction {
|
||||
|
||||
CREATE_VOLUME("CREATE_VOLUME"),
|
||||
CREATE_BUCKET("CREATE_BUCKET"),
|
||||
CREATE_KEY("CREATE_KEY"),
|
||||
READ_VOLUME("READ_VOLUME"),
|
||||
READ_BUCKET("READ_BUCKET"),
|
||||
READ_KEY("READ_BUCKET"),
|
||||
UPDATE_VOLUME("UPDATE_VOLUME"),
|
||||
UPDATE_BUCKET("UPDATE_BUCKET"),
|
||||
UPDATE_KEY("UPDATE_KEY"),
|
||||
DELETE_VOLUME("DELETE_VOLUME"),
|
||||
DELETE_BUCKET("DELETE_BUCKET"),
|
||||
DELETE_KEY("DELETE_KEY"),
|
||||
SET_OWNER("SET_OWNER"),
|
||||
SET_QUOTA("SET_QUOTA");
|
||||
|
||||
private String action;
|
||||
|
||||
OMAction(String action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAction() {
|
||||
return this.action;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with this
|
||||
* work for additional information regarding copyright ownership. The ASF
|
||||
* licenses this file to you 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
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* 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 org.apache.hadoop.ozone.audit;
|
||||
/**
|
||||
* This package defines OMAction - an implementation of AuditAction
|
||||
* OMAction defines audit action types for various actions that will be
|
||||
* audited in OzoneManager.
|
||||
*/
|
Loading…
Reference in New Issue
Block a user