Github user Sssan520 commented on a diff in the pull request: https://github.com/apache/carbondata/pull/2885#discussion_r229671527 --- Diff: processing/src/main/java/org/apache/carbondata/processing/util/Auditor.java --- @@ -0,0 +1,216 @@ +/* + * 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.text.SimpleDateFormat; +import java.util.Date; +import java.util.Map; + +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.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 String username; + + static { + try { + username = UserGroupInformation.getCurrentUser().getShortUserName(); + } catch (IOException e) { + username = "unknown"; + } + } + + public static void logOperationStart(String opName, String opId) { + OpStartMessage message = new OpStartMessage(opName, opId); + Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + String json = gson.toJson(message); + LOGGER.log(AuditLevel.AUDIT, json); + } + + public static void logOperationSuccess(String opName, String opId, String table, + String opTime, Map<String, String> extraInfo) { + OpEndMessage message = new OpEndMessage(opName, opId, table, opTime, + OpStatus.SUCCESS, extraInfo); + Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + String json = gson.toJson(message); + LOGGER.log(AuditLevel.AUDIT, json); + } + + public static void logOperationFailed(String opName, String opId, String table, + String opTime, Map<String, String> extraInfo) { + OpEndMessage message = new OpEndMessage(opName, opId, table, opTime, + OpStatus.FAILED, extraInfo); + Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + 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) { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); --- End diff -- may use FastDateFormat
---