http://git-wip-us.apache.org/repos/asf/carbondata/blob/a160dfb6/processing/src/main/java/org/apache/carbondata/processing/util/Auditor.java ---------------------------------------------------------------------- diff --git a/processing/src/main/java/org/apache/carbondata/processing/util/Auditor.java b/processing/src/main/java/org/apache/carbondata/processing/util/Auditor.java new file mode 100644 index 0000000..e811c59 --- /dev/null +++ b/processing/src/main/java/org/apache/carbondata/processing/util/Auditor.java @@ -0,0 +1,222 @@ +/* + * 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.carbondata.processing.util; + +import java.io.IOException; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import org.apache.carbondata.common.annotations.InterfaceAudience; +import org.apache.carbondata.common.logging.impl.AuditLevel; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.apache.commons.lang3.time.FastDateFormat; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.log4j.Logger; + +/** + * Audit logger. + * User can configure log4j to log to a separate file. For example + * + * log4j.logger.carbon.audit=DEBUG, audit + * log4j.appender.audit=org.apache.log4j.FileAppender + * log4j.appender.audit.File=/opt/logs/audit.out + * log4j.appender.audit.Threshold=AUDIT + * log4j.appender.audit.Append=false + * log4j.appender.audit.layout=org.apache.log4j.PatternLayout + * log4j.appender.audit.layout.ConversionPattern=%m%n + */ +@InterfaceAudience.Internal +public class Auditor { + private static final Logger LOGGER = Logger.getLogger("carbon.audit"); + private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + private static String username; + + static { + try { + username = UserGroupInformation.getCurrentUser().getShortUserName(); + } catch (IOException e) { + username = "unknown"; + } + } + + /** + * call this method to record audit log when operation is triggered + * @param opName operation name + * @param opId operation unique id + */ + public static void logOperationStart(String opName, String opId) { + Objects.requireNonNull(opName); + Objects.requireNonNull(opId); + OpStartMessage message = new OpStartMessage(opName, opId); + Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + String json = gson.toJson(message); + LOGGER.log(AuditLevel.AUDIT, json); + } + + /** + * call this method to record audit log when operation finished + * @param opName operation name + * @param opId operation unique id + * @param success true if operation success + * @param table carbon dbName and tableName + * @param opTime elapse time in Ms for this operation + * @param extraInfo extra information to include in the audit log + */ + public static void logOperationEnd(String opName, String opId, boolean success, String table, + String opTime, Map<String, String> extraInfo) { + Objects.requireNonNull(opName); + Objects.requireNonNull(opId); + Objects.requireNonNull(opTime); + OpEndMessage message = new OpEndMessage(opName, opId, table, opTime, + success ? OpStatus.SUCCESS : OpStatus.FAILED, + extraInfo != null ? extraInfo : new HashMap<String, String>()); + String json = gson.toJson(message); + LOGGER.log(AuditLevel.AUDIT, json); + } + + private enum OpStatus { + // operation started + START, + + // operation succeed + SUCCESS, + + // operation failed + FAILED + } + + // log message for operation start, it is written as a JSON record in the audit log + private static class OpStartMessage { + private String time; + private String username; + private String opName; + private String opId; + private OpStatus opStatus; + + OpStartMessage(String opName, String opId) { + FastDateFormat format = + FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.LONG); + this.time = format.format(new Date()); + this.username = Auditor.username; + this.opName = opName; + this.opId = opId; + this.opStatus = OpStatus.START; + } + + // No one actually invoke this, it is only for findbugs + public String getTime() { + return time; + } + + // No one actually invoke this, it is only for findbugs + public String getUsername() { + return username; + } + + // No one actually invoke this, it is only for findbugs + public String getOpName() { + return opName; + } + + // No one actually invoke this, it is only for findbugs + public String getOpId() { + return opId; + } + + // No one actually invoke this, it is only for findbugs + public OpStatus getOpStatus() { + return opStatus; + } + } + + // log message for operation end, it is written as a JSON record in the audit log + private static class OpEndMessage { + private String time; + private String username; + private String opName; + private String opId; + private OpStatus opStatus; + private String opTime; + private String table; + private Map<String, String> extraInfo; + + OpEndMessage(String opName, String opId, String table, String opTime, + OpStatus opStatus, Map<String, String> extraInfo) { + FastDateFormat format = + FastDateFormat.getDateTimeInstance(FastDateFormat.LONG, FastDateFormat.LONG); + this.time = format.format(new Date()); + this.username = Auditor.username; + this.opName = opName; + if (table != null) { + this.table = table; + } else { + this.table = "NA"; + } + this.opTime = opTime; + this.opId = opId; + this.opStatus = opStatus; + this.extraInfo = extraInfo; + } + + // No one actually invoke this, it is only for findbugs + public String getTime() { + return time; + } + + // No one actually invoke this, it is only for findbugs + public String getUsername() { + return username; + } + + // No one actually invoke this, it is only for findbugs + public String getOpName() { + return opName; + } + + // No one actually invoke this, it is only for findbugs + public String getOpId() { + return opId; + } + + // No one actually invoke this, it is only for findbugs + public OpStatus getOpStatus() { + return opStatus; + } + + // No one actually invoke this, it is only for findbugs + public String getTable() { + return table; + } + + // No one actually invoke this, it is only for findbugs + public String getOpTime() { + return opTime; + } + + // No one actually invoke this, it is only for findbugs + public Map<String, String> getExtraInfo() { + return extraInfo; + } + } + + +}
http://git-wip-us.apache.org/repos/asf/carbondata/blob/a160dfb6/store/sdk/src/test/java/org/apache/carbondata/sdk/file/CarbonReaderTest.java ---------------------------------------------------------------------- diff --git a/store/sdk/src/test/java/org/apache/carbondata/sdk/file/CarbonReaderTest.java b/store/sdk/src/test/java/org/apache/carbondata/sdk/file/CarbonReaderTest.java index c176f06..0767264 100644 --- a/store/sdk/src/test/java/org/apache/carbondata/sdk/file/CarbonReaderTest.java +++ b/store/sdk/src/test/java/org/apache/carbondata/sdk/file/CarbonReaderTest.java @@ -26,7 +26,6 @@ import org.apache.avro.generic.GenericData; import org.apache.carbondata.common.exceptions.sql.InvalidLoadOptionException; import org.apache.log4j.Logger; import org.apache.carbondata.common.logging.LogServiceFactory; -import org.apache.carbondata.common.logging.impl.Audit; import org.apache.carbondata.core.constants.CarbonCommonConstants; import org.apache.carbondata.core.datamap.DataMapStoreManager; import org.apache.carbondata.core.datastore.impl.FileFactory; @@ -908,7 +907,6 @@ public class CarbonReaderTest extends TestCase { e.printStackTrace(); Assert.fail(e.getMessage()); } - Audit.log(LOGGER, "Bad record location:" + storeLocation); File folder = new File(path); Assert.assertTrue(folder.exists()); http://git-wip-us.apache.org/repos/asf/carbondata/blob/a160dfb6/store/search/src/main/java/org/apache/carbondata/store/worker/SearchRequestHandler.java ---------------------------------------------------------------------- diff --git a/store/search/src/main/java/org/apache/carbondata/store/worker/SearchRequestHandler.java b/store/search/src/main/java/org/apache/carbondata/store/worker/SearchRequestHandler.java index b1e87ce..6492a9b 100644 --- a/store/search/src/main/java/org/apache/carbondata/store/worker/SearchRequestHandler.java +++ b/store/search/src/main/java/org/apache/carbondata/store/worker/SearchRequestHandler.java @@ -26,7 +26,6 @@ import java.util.Objects; import org.apache.carbondata.common.annotations.InterfaceAudience; import org.apache.carbondata.common.logging.LogServiceFactory; -import org.apache.carbondata.common.logging.impl.Audit; import org.apache.carbondata.core.datamap.DataMapChooser; import org.apache.carbondata.core.datamap.DataMapDistributable; import org.apache.carbondata.core.datamap.Segment; @@ -78,7 +77,7 @@ public class SearchRequestHandler { List<CarbonRow> rows = handleRequest(request); LOG.info(String.format("[SearchId:%d] sending success response", request.searchId())); return createSuccessResponse(request, rows); - } catch (IOException | InterruptedException e) { + } catch (IOException e) { LOG.error(e); LOG.info(String.format("[SearchId:%d] sending failure response", request.searchId())); return createFailureResponse(request, e); @@ -95,22 +94,16 @@ public class SearchRequestHandler { private DataMapExprWrapper chooseFGDataMap( CarbonTable table, - FilterResolverIntf filterInterface) { - DataMapChooser chooser = null; - try { - chooser = new DataMapChooser(table); - return chooser.chooseFGDataMap(filterInterface); - } catch (IOException e) { - Audit.log(LOG, e.getMessage()); - return null; - } + FilterResolverIntf filterInterface) throws IOException { + DataMapChooser chooser = new DataMapChooser(table); + return chooser.chooseFGDataMap(filterInterface); } /** * Builds {@link QueryModel} and read data from files */ private List<CarbonRow> handleRequest(SearchRequest request) - throws IOException, InterruptedException { + throws IOException { CarbonTaskInfo carbonTaskInfo = new CarbonTaskInfo(); carbonTaskInfo.setTaskId(CarbonUtil.generateUUID()); ThreadLocalTaskInfo.setCarbonTaskInfo(carbonTaskInfo);