You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ha...@apache.org on 2022/12/20 06:52:59 UTC

[iotdb] branch rel/0.13 updated: [To rel/0.13][IOTDB-3662] upgrade audit log (#8491)

This is an automated email from the ASF dual-hosted git repository.

haonan pushed a commit to branch rel/0.13
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/rel/0.13 by this push:
     new 4f112d4985 [To rel/0.13][IOTDB-3662] upgrade audit log (#8491)
4f112d4985 is described below

commit 4f112d4985d4408b00a7e6474956a981831ffec4
Author: Zhijia Cao <ca...@126.com>
AuthorDate: Tue Dec 20 14:52:51 2022 +0800

    [To rel/0.13][IOTDB-3662] upgrade audit log (#8491)
---
 .../resources/conf/iotdb-engine.properties         |  30 ++++-
 .../apache/iotdb/db/audit/AuditLogOperation.java   |  30 +++++
 .../org/apache/iotdb/db/audit/AuditLogStorage.java |  29 +++++
 .../AuditLogUtils.java => audit/AuditLogger.java}  |  59 +++++----
 .../iotdb/db/auth/authorizer/BasicAuthorizer.java  |  43 +++++++
 .../iotdb/db/auth/role/BasicRoleManager.java       |  23 ++--
 .../iotdb/db/auth/user/BasicUserManager.java       |  16 ++-
 .../java/org/apache/iotdb/db/conf/IoTDBConfig.java |  49 ++++++--
 .../org/apache/iotdb/db/conf/IoTDBDescriptor.java  |  27 ++++-
 .../iotdb/db/protocol/mqtt/PublishHandler.java     |   1 +
 .../db/protocol/rest/impl/RestApiServiceImpl.java  |   2 +-
 .../apache/iotdb/db/qp/executor/PlanExecutor.java  | 132 +++++++++++++++++++--
 .../apache/iotdb/db/qp/physical/PhysicalPlan.java  |  10 ++
 .../iotdb/db/query/control/SessionManager.java     |   4 +-
 .../iotdb/db/service/basic/ServiceProvider.java    |  38 ++----
 .../db/service/thrift/impl/TSServiceImpl.java      | 132 +++------------------
 .../db/qp/physical/InsertTabletMultiPlanTest.java  |   3 +-
 17 files changed, 420 insertions(+), 208 deletions(-)

diff --git a/server/src/assembly/resources/conf/iotdb-engine.properties b/server/src/assembly/resources/conf/iotdb-engine.properties
index 6e44b96b59..83ba83c639 100644
--- a/server/src/assembly/resources/conf/iotdb-engine.properties
+++ b/server/src/assembly/resources/conf/iotdb-engine.properties
@@ -951,10 +951,30 @@ timestamp_precision=ms
 # Datatype: float
 # group_by_fill_cache_size_in_mb=1.0
 
-# determines whether audit logs are written to log files or IoTDB or not write.choice:LOGGER/IOTDB/NONE
+####################
+### Audit log Configuration
+####################
+
+# whether to enable the audit log.
+# Datatype: Boolean
+# enable_audit_log=false
+
+# Output location of audit logs
 # Datatype: String
-# audit_log_storage=NONE
+# IOTDB: the stored time series is: root.__system.audit.'user={user}'
+# LOGGER: log_audit.log in the log directory
+# audit_log_storage=IOTDB,LOGGER
 
-# determines whether audit logs record IoTDB write operation
-# Datatype: boolean
-# enable_auditLog_write=false
\ No newline at end of file
+# whether enable audit log for DML operation of data
+# whether enable audit log for DDL operation of schema
+# whether enable audit log for QUERY operation of data and schema
+# Datatype: String
+# audit_log_operation=DML,DDL,QUERY
+
+# whether the local write api records audit logs
+# Datatype: Boolean
+# This contains Session insert api: insertRecord(s), insertTablet(s),insertRecordsOfOneDevice
+# MQTT insert api
+# RestAPI insert api
+# This parameter will cover the DML in audit_log_operation
+# enable_audit_log_for_native_insert_api=true
\ No newline at end of file
diff --git a/server/src/main/java/org/apache/iotdb/db/audit/AuditLogOperation.java b/server/src/main/java/org/apache/iotdb/db/audit/AuditLogOperation.java
new file mode 100644
index 0000000000..689c2e2858
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/audit/AuditLogOperation.java
@@ -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
+ *
+ *     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.iotdb.db.audit;
+
+public enum AuditLogOperation {
+  DDL,
+  DML,
+  QUERY;
+
+  @Override
+  public String toString() {
+    return name();
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/audit/AuditLogStorage.java b/server/src/main/java/org/apache/iotdb/db/audit/AuditLogStorage.java
new file mode 100644
index 0000000000..1645a72913
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/audit/AuditLogStorage.java
@@ -0,0 +1,29 @@
+/*
+ * 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.iotdb.db.audit;
+
+public enum AuditLogStorage {
+  IOTDB,
+  LOGGER;
+
+  @Override
+  public String toString() {
+    return name();
+  }
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/utils/AuditLogUtils.java b/server/src/main/java/org/apache/iotdb/db/audit/AuditLogger.java
similarity index 66%
rename from server/src/main/java/org/apache/iotdb/db/utils/AuditLogUtils.java
rename to server/src/main/java/org/apache/iotdb/db/audit/AuditLogger.java
index 78002f6c42..981e3f564d 100644
--- a/server/src/main/java/org/apache/iotdb/db/utils/AuditLogUtils.java
+++ b/server/src/main/java/org/apache/iotdb/db/audit/AuditLogger.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.iotdb.db.utils;
+package org.apache.iotdb.db.audit;
 
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBConstant;
@@ -34,8 +34,10 @@ import org.apache.iotdb.db.service.IoTDB;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class AuditLogUtils {
-  private static final Logger logger = LoggerFactory.getLogger(AuditLogUtils.class);
+import java.util.List;
+
+public class AuditLogger {
+  private static final Logger logger = LoggerFactory.getLogger(AuditLogger.class);
   private static final Logger AUDIT_LOGGER =
       LoggerFactory.getLogger(IoTDBConstant.AUDIT_LOGGER_NAME);
 
@@ -43,28 +45,27 @@ public class AuditLogUtils {
   public static final String USERNAME = "username";
   public static final String ADDRESS = "address";
   public static final String AUDIT_LOG_DEVICE = "root.__system.audit.'%s'";
-  public static final String LOG_LEVEL_IOTDB = "IOTDB";
-  public static final String LOG_LEVEL_LOGGER = "LOGGER";
-  public static final String LOG_LEVEL_NONE = "NONE";
 
-  public static void writeAuditLog(String log) {
-    writeAuditLog(log, false);
-  }
+  public static final IoTDBConfig config = IoTDBDescriptor.getInstance().getConfig();
+
+  public static final List<AuditLogStorage> auditLogStorageList = config.getAuditLogStorage();
 
-  public static void writeAuditLog(String log, boolean enableWrite) {
-    IoTDBConfig config = IoTDBDescriptor.getInstance().getConfig();
-    String auditLogStorage = config.getAuditLogStorage();
+  public static final List<AuditLogOperation> auditLogOperationList = config.getAuditLogOperation();
+
+  public static void log(String log, AuditLogOperation operation) {
     IClientSession currSession = SessionManager.getInstance().getCurrSession();
-    if (currSession == null) {
-      return;
+    String username = "";
+    String address = "";
+    if (currSession != null) {
+      ClientSession clientSession = (ClientSession) currSession;
+      String clientAddress = clientSession.getClientAddress();
+      int clientPort = ((ClientSession) currSession).getClientPort();
+      address = String.format("%s:%s", clientAddress, clientPort);
+      username = currSession.getUsername();
     }
-    ClientSession clientSession = (ClientSession) currSession;
-    String clientAddress = clientSession.getClientAddress();
-    int clientPort = ((ClientSession) currSession).getClientPort();
-    String address = String.format("%s:%s", clientAddress, clientPort);
-    String username = currSession.getUsername();
-    if (clientSession.isEnableAudit() || enableWrite) {
-      if (LOG_LEVEL_IOTDB.equals(auditLogStorage)) {
+
+    if (auditLogOperationList.contains(operation)) {
+      if (auditLogStorageList.contains(AuditLogStorage.IOTDB)) {
         try {
           InsertRowPlan insertRowPlan =
               new InsertRowPlan(
@@ -72,13 +73,27 @@ public class AuditLogUtils {
                   DateTimeUtils.currentTime(),
                   new String[] {LOG, USERNAME, ADDRESS},
                   new String[] {log, username, address});
+          if (IoTDB.serviceProvider == null) {
+            return;
+          }
           IoTDB.serviceProvider.getExecutor().insert(insertRowPlan);
         } catch (IllegalPathException | QueryProcessException e) {
           logger.error("write audit log series error,", e);
         }
-      } else if (LOG_LEVEL_LOGGER.equals(auditLogStorage)) {
+      }
+      if (auditLogStorageList.contains(AuditLogStorage.LOGGER)) {
         AUDIT_LOGGER.info("user:{},address:{},log:{}", username, address, log);
       }
     }
   }
+
+  public static void log(String log, AuditLogOperation operation, boolean isNativeApi) {
+    if (isNativeApi) {
+      if (config.isEnableAuditLogForNativeInsertApi()) {
+        log(log, operation);
+      }
+    } else {
+      log(log, operation);
+    }
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/auth/authorizer/BasicAuthorizer.java b/server/src/main/java/org/apache/iotdb/db/auth/authorizer/BasicAuthorizer.java
index 23af06c395..53a2082a2f 100644
--- a/server/src/main/java/org/apache/iotdb/db/auth/authorizer/BasicAuthorizer.java
+++ b/server/src/main/java/org/apache/iotdb/db/auth/authorizer/BasicAuthorizer.java
@@ -18,6 +18,7 @@
  */
 package org.apache.iotdb.db.auth.authorizer;
 
+import org.apache.iotdb.db.audit.AuditLogger;
 import org.apache.iotdb.db.auth.AuthException;
 import org.apache.iotdb.db.auth.entity.PrivilegeType;
 import org.apache.iotdb.db.auth.entity.Role;
@@ -40,6 +41,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import static org.apache.iotdb.db.audit.AuditLogOperation.DDL;
+
 public abstract class BasicAuthorizer implements IAuthorizer, IService {
 
   private static final Logger logger = LoggerFactory.getLogger(BasicAuthorizer.class);
@@ -47,6 +50,9 @@ public abstract class BasicAuthorizer implements IAuthorizer, IService {
   private static final String NO_SUCH_ROLE_EXCEPTION = "No such role : %s";
   private static final String NO_SUCH_USER_EXCEPTION = "No such user : %s";
 
+  private static final boolean enableAuditLog =
+      IoTDBDescriptor.getInstance().getConfig().isEnableAuditLog();
+
   static {
     ADMIN_PRIVILEGES = new HashSet<>();
     for (int i = 0; i < PrivilegeType.values().length; i++) {
@@ -141,6 +147,13 @@ public abstract class BasicAuthorizer implements IAuthorizer, IService {
           String.format(
               "User %s already has %s on %s", username, PrivilegeType.values()[privilegeId], path));
     }
+    if (enableAuditLog) {
+      AuditLogger.log(
+          String.format(
+              "grant privilege to user,username %s ,path: %s,privilegeId:%s",
+              username, path, privilegeId),
+          DDL);
+    }
   }
 
   @Override
@@ -159,6 +172,13 @@ public abstract class BasicAuthorizer implements IAuthorizer, IService {
               "User %s does not have %s on %s",
               username, PrivilegeType.values()[privilegeId], path));
     }
+    if (enableAuditLog) {
+      AuditLogger.log(
+          String.format(
+              "revoke privilege from user,username:%s,path:%s,privilegeId:%s",
+              username, path, privilegeId),
+          DDL);
+    }
   }
 
   @Override
@@ -174,6 +194,9 @@ public abstract class BasicAuthorizer implements IAuthorizer, IService {
     if (!success) {
       throw new AuthException(String.format("Role %s does not exist", roleName));
     } else {
+      if (enableAuditLog) {
+        AuditLogger.log(String.format("role %s is deleted", roleName), DDL);
+      }
       // proceed to revoke the role in all users
       List<String> users = userManager.listAllUsers();
       for (String user : users) {
@@ -202,6 +225,10 @@ public abstract class BasicAuthorizer implements IAuthorizer, IService {
           String.format(
               "Role %s already has %s on %s", roleName, PrivilegeType.values()[privilegeId], path));
     }
+    if (enableAuditLog) {
+      AuditLogger.log(
+          String.format("role %s is granted,privilegeId: %s", roleName, privilegeId), DDL);
+    }
   }
 
   @Override
@@ -217,6 +244,13 @@ public abstract class BasicAuthorizer implements IAuthorizer, IService {
               "Role %s does not have %s on %s",
               roleName, PrivilegeType.values()[privilegeId], path));
     }
+    if (enableAuditLog) {
+      AuditLogger.log(
+          String.format(
+              "revoke privilege from role,role name:%s,path:%s,privilegeId:%s",
+              roleName, path, privilegeId),
+          DDL);
+    }
   }
 
   @Override
@@ -232,6 +266,11 @@ public abstract class BasicAuthorizer implements IAuthorizer, IService {
       if (role == null) {
         throw new AuthException(String.format(NO_SUCH_ROLE_EXCEPTION, roleName));
       }
+      if (enableAuditLog) {
+        AuditLogger.log(
+            String.format("grant role to user,role name %s ,username: %s", roleName, username),
+            DDL);
+      }
     } else {
       throw new AuthException(String.format("User %s already has role %s", username, roleName));
     }
@@ -246,6 +285,10 @@ public abstract class BasicAuthorizer implements IAuthorizer, IService {
     if (!userManager.revokeRoleFromUser(roleName, username)) {
       throw new AuthException(String.format("User %s does not have role %s", username, roleName));
     }
+    if (enableAuditLog) {
+      AuditLogger.log(
+          String.format("revoke role from user,role name:%s,username:%s", roleName, username), DDL);
+    }
   }
 
   @Override
diff --git a/server/src/main/java/org/apache/iotdb/db/auth/role/BasicRoleManager.java b/server/src/main/java/org/apache/iotdb/db/auth/role/BasicRoleManager.java
index 8ac726cd56..a9f29c2f77 100644
--- a/server/src/main/java/org/apache/iotdb/db/auth/role/BasicRoleManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/auth/role/BasicRoleManager.java
@@ -18,9 +18,12 @@
  */
 package org.apache.iotdb.db.auth.role;
 
+import org.apache.iotdb.db.audit.AuditLogOperation;
+import org.apache.iotdb.db.audit.AuditLogger;
 import org.apache.iotdb.db.auth.AuthException;
 import org.apache.iotdb.db.auth.entity.Role;
 import org.apache.iotdb.db.concurrent.HashLock;
+import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.utils.AuthUtils;
 
 import java.io.IOException;
@@ -37,6 +40,8 @@ import java.util.Set;
  */
 public abstract class BasicRoleManager implements IRoleManager {
 
+  private static final boolean enableAuditLog =
+      IoTDBDescriptor.getInstance().getConfig().isEnableAuditLog();
   private Map<String, Role> roleMap;
   private IRoleAccessor accessor;
   private HashLock lock;
@@ -67,23 +72,25 @@ public abstract class BasicRoleManager implements IRoleManager {
   }
 
   @Override
-  public boolean createRole(String rolename) throws AuthException {
-    AuthUtils.validateRolename(rolename);
-
-    Role role = getRole(rolename);
+  public boolean createRole(String roleName) throws AuthException {
+    AuthUtils.validateRolename(roleName);
+    if (enableAuditLog) {
+      AuditLogger.log(String.format("the role %s is created ", roleName), AuditLogOperation.DDL);
+    }
+    Role role = getRole(roleName);
     if (role != null) {
       return false;
     }
-    lock.writeLock(rolename);
+    lock.writeLock(roleName);
     try {
-      role = new Role(rolename);
+      role = new Role(roleName);
       accessor.saveRole(role);
-      roleMap.put(rolename, role);
+      roleMap.put(roleName, role);
       return true;
     } catch (IOException e) {
       throw new AuthException(e);
     } finally {
-      lock.writeUnlock(rolename);
+      lock.writeUnlock(roleName);
     }
   }
 
diff --git a/server/src/main/java/org/apache/iotdb/db/auth/user/BasicUserManager.java b/server/src/main/java/org/apache/iotdb/db/auth/user/BasicUserManager.java
index 9a5a261244..bc1fb5167c 100644
--- a/server/src/main/java/org/apache/iotdb/db/auth/user/BasicUserManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/auth/user/BasicUserManager.java
@@ -18,6 +18,8 @@
  */
 package org.apache.iotdb.db.auth.user;
 
+import org.apache.iotdb.db.audit.AuditLogOperation;
+import org.apache.iotdb.db.audit.AuditLogger;
 import org.apache.iotdb.db.auth.AuthException;
 import org.apache.iotdb.db.auth.entity.User;
 import org.apache.iotdb.db.concurrent.HashLock;
@@ -44,6 +46,9 @@ public abstract class BasicUserManager implements IUserManager {
   private static final Logger logger = LoggerFactory.getLogger(BasicUserManager.class);
   private static final String NO_SUCH_USER_ERROR = "No such user %s";
 
+  private static final boolean enableAuditLog =
+      IoTDBDescriptor.getInstance().getConfig().isEnableAuditLog();
+
   private Map<String, User> userMap;
   private IUserAccessor accessor;
   private HashLock lock;
@@ -107,7 +112,9 @@ public abstract class BasicUserManager implements IUserManager {
   public boolean createUser(String username, String password) throws AuthException {
     AuthUtils.validateUsername(username);
     AuthUtils.validatePassword(password);
-
+    if (enableAuditLog) {
+      AuditLogger.log(String.format("user %s is created", username), AuditLogOperation.DDL);
+    }
     User user = getUser(username);
     if (user != null) {
       return false;
@@ -130,6 +137,9 @@ public abstract class BasicUserManager implements IUserManager {
     lock.writeLock(username);
     try {
       if (accessor.deleteUser(username)) {
+        if (enableAuditLog) {
+          AuditLogger.log(String.format("user %s is deleted", username), AuditLogOperation.DDL);
+        }
         userMap.remove(username);
         return true;
       } else {
@@ -203,7 +213,9 @@ public abstract class BasicUserManager implements IUserManager {
       logger.debug("An illegal password detected ", e);
       return false;
     }
-
+    if (enableAuditLog) {
+      AuditLogger.log("password is updated", AuditLogOperation.DDL);
+    }
     lock.writeLock(username);
     try {
       User user = getUser(username);
diff --git a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
index b6b9efa343..b195d3df55 100644
--- a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
+++ b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
@@ -18,6 +18,8 @@
  */
 package org.apache.iotdb.db.conf;
 
+import org.apache.iotdb.db.audit.AuditLogOperation;
+import org.apache.iotdb.db.audit.AuditLogStorage;
 import org.apache.iotdb.db.conf.directories.DirectoryManager;
 import org.apache.iotdb.db.engine.compaction.constant.CompactionPriority;
 import org.apache.iotdb.db.engine.compaction.cross.CrossCompactionStrategy;
@@ -27,7 +29,6 @@ import org.apache.iotdb.db.exception.LoadConfigurationException;
 import org.apache.iotdb.db.metadata.MManager;
 import org.apache.iotdb.db.service.thrift.impl.InfluxDBServiceImpl;
 import org.apache.iotdb.db.service.thrift.impl.TSServiceImpl;
-import org.apache.iotdb.db.utils.AuditLogUtils;
 import org.apache.iotdb.rpc.RpcTransportFactory;
 import org.apache.iotdb.rpc.RpcUtils;
 import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
@@ -40,6 +41,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.File;
+import java.util.Arrays;
+import java.util.List;
 import java.util.Properties;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -874,11 +877,19 @@ public class IoTDBConfig {
   /** number of threads given to archiving tasks */
   private int archivingThreadNum = 2;
 
-  // determines whether audit logs are written to log files or IoTDB
-  private String auditLogStorage = AuditLogUtils.LOG_LEVEL_NONE;
+  /** whether to enable the audit log * */
+  private boolean enableAuditLog = false;
 
-  // determines whether audit logs record IoTDB write operation
-  private boolean enableAuditLogWrite = false;
+  /** Output location of audit logs * */
+  private List<AuditLogStorage> auditLogStorage =
+      Arrays.asList(AuditLogStorage.IOTDB, AuditLogStorage.LOGGER);
+
+  /** Indicates the category collection of audit logs * */
+  private List<AuditLogOperation> auditLogOperation =
+      Arrays.asList(AuditLogOperation.DML, AuditLogOperation.DDL, AuditLogOperation.QUERY);
+
+  /** whether the local write api records audit logs * */
+  private boolean enableAuditLogForNativeInsertApi = true;
 
   // customizedProperties, this should be empty by default.
   private Properties customizedProperties = new Properties();
@@ -2828,19 +2839,35 @@ public class IoTDBConfig {
     this.patternMatchingThreshold = patternMatchingThreshold;
   }
 
-  public String getAuditLogStorage() {
+  public boolean isEnableAuditLog() {
+    return enableAuditLog;
+  }
+
+  public void setEnableAuditLog(boolean enableAuditLog) {
+    this.enableAuditLog = enableAuditLog;
+  }
+
+  public List<AuditLogStorage> getAuditLogStorage() {
     return auditLogStorage;
   }
 
-  public void setAuditLogStorage(String auditLogStorage) {
+  public void setAuditLogStorage(List<AuditLogStorage> auditLogStorage) {
     this.auditLogStorage = auditLogStorage;
   }
 
-  public boolean isEnableAuditLogWrite() {
-    return enableAuditLogWrite;
+  public List<AuditLogOperation> getAuditLogOperation() {
+    return auditLogOperation;
+  }
+
+  public void setAuditLogOperation(List<AuditLogOperation> auditLogOperation) {
+    this.auditLogOperation = auditLogOperation;
+  }
+
+  public boolean isEnableAuditLogForNativeInsertApi() {
+    return enableAuditLogForNativeInsertApi;
   }
 
-  public void setEnableAuditLogWrite(boolean enableAuditLogWrite) {
-    this.enableAuditLogWrite = enableAuditLogWrite;
+  public void setEnableAuditLogForNativeInsertApi(boolean enableAuditLogForNativeInsertApi) {
+    this.enableAuditLogForNativeInsertApi = enableAuditLogForNativeInsertApi;
   }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
index d12c871780..1526260ce7 100644
--- a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
+++ b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
@@ -18,6 +18,8 @@
  */
 package org.apache.iotdb.db.conf;
 
+import org.apache.iotdb.db.audit.AuditLogOperation;
+import org.apache.iotdb.db.audit.AuditLogStorage;
 import org.apache.iotdb.db.conf.directories.DirectoryManager;
 import org.apache.iotdb.db.engine.StorageEngine;
 import org.apache.iotdb.db.engine.compaction.constant.CompactionPriority;
@@ -48,8 +50,10 @@ import java.net.InetAddress;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.UnknownHostException;
+import java.util.Arrays;
 import java.util.Properties;
 import java.util.ServiceLoader;
+import java.util.stream.Collectors;
 
 public class IoTDBDescriptor {
 
@@ -891,12 +895,29 @@ public class IoTDBDescriptor {
             properties.getProperty(
                 "schema_query_fetch_size", String.valueOf(conf.getSchemaQueryFetchSize()))));
 
-    conf.setAuditLogStorage(properties.getProperty("audit_log_storage", conf.getAuditLogStorage()));
+    conf.setEnableAuditLog(
+        Boolean.parseBoolean(
+            properties.getProperty("enable_audit_log", String.valueOf(conf.isEnableAuditLog()))));
+
+    if (properties.getProperty("audit_log_storage") != null) {
+      conf.setAuditLogStorage(
+          Arrays.stream(properties.getProperty("audit_log_storage").split(","))
+              .map(AuditLogStorage::valueOf)
+              .collect(Collectors.toList()));
+    }
+
+    if (properties.getProperty("audit_log_operation") != null) {
+      conf.setAuditLogOperation(
+          Arrays.stream(properties.getProperty("audit_log_operation").split(","))
+              .map(AuditLogOperation::valueOf)
+              .collect(Collectors.toList()));
+    }
 
-    conf.setEnableAuditLogWrite(
+    conf.setEnableAuditLogForNativeInsertApi(
         Boolean.parseBoolean(
             properties.getProperty(
-                "enable_auditLog_write", String.valueOf(conf.isEnableAuditLogWrite()))));
+                "enable_audit_log_for_native_insert_api",
+                String.valueOf(conf.isEnableAuditLogForNativeInsertApi()))));
 
     // At the same time, set TSFileConfig
     TSFileDescriptor.getInstance()
diff --git a/server/src/main/java/org/apache/iotdb/db/protocol/mqtt/PublishHandler.java b/server/src/main/java/org/apache/iotdb/db/protocol/mqtt/PublishHandler.java
index 8c6a1d9ad5..25a9887cd0 100644
--- a/server/src/main/java/org/apache/iotdb/db/protocol/mqtt/PublishHandler.java
+++ b/server/src/main/java/org/apache/iotdb/db/protocol/mqtt/PublishHandler.java
@@ -135,6 +135,7 @@ public class PublishHandler extends AbstractInterceptHandler {
                 event.getTimestamp(),
                 event.getMeasurements().toArray(new String[0]),
                 event.getValues().toArray(new String[0]));
+        plan.setNativeInsertApi(true);
         TSStatus tsStatus = serviceProvider.checkAuthority(plan, session);
         if (tsStatus != null) {
           LOG.warn(tsStatus.message);
diff --git a/server/src/main/java/org/apache/iotdb/db/protocol/rest/impl/RestApiServiceImpl.java b/server/src/main/java/org/apache/iotdb/db/protocol/rest/impl/RestApiServiceImpl.java
index 80cc36b4d3..12ce9140b3 100644
--- a/server/src/main/java/org/apache/iotdb/db/protocol/rest/impl/RestApiServiceImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/protocol/rest/impl/RestApiServiceImpl.java
@@ -190,7 +190,7 @@ public class RestApiServiceImpl extends RestApiService {
 
       InsertTabletPlan insertTabletPlan =
           PhysicalPlanConstructionHandler.constructInsertTabletPlan(insertTabletRequest);
-
+      insertTabletPlan.setNativeInsertApi(true);
       Response response = authorizationHandler.checkAuthority(securityContext, insertTabletPlan);
       if (response != null) {
         return response;
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
index ad26411834..32fbe387ed 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
@@ -18,6 +18,7 @@
  */
 package org.apache.iotdb.db.qp.executor;
 
+import org.apache.iotdb.db.audit.AuditLogger;
 import org.apache.iotdb.db.auth.AuthException;
 import org.apache.iotdb.db.auth.AuthorityChecker;
 import org.apache.iotdb.db.auth.authorizer.BasicAuthorizer;
@@ -152,7 +153,6 @@ import org.apache.iotdb.db.query.udf.service.UDFRegistrationService;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.db.service.SettleService;
 import org.apache.iotdb.db.tools.TsFileRewriteTool;
-import org.apache.iotdb.db.utils.AuditLogUtils;
 import org.apache.iotdb.db.utils.AuthUtils;
 import org.apache.iotdb.db.utils.FileLoaderUtils;
 import org.apache.iotdb.db.utils.TypeInferenceUtils;
@@ -202,6 +202,8 @@ import java.util.Set;
 import java.util.concurrent.Future;
 import java.util.concurrent.ThreadPoolExecutor;
 
+import static org.apache.iotdb.db.audit.AuditLogOperation.DDL;
+import static org.apache.iotdb.db.audit.AuditLogOperation.DML;
 import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_ARCHIVING_START_TIME;
 import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_ARCHIVING_STATUS;
 import static org.apache.iotdb.db.conf.IoTDBConstant.COLUMN_ARCHIVING_TARGET_DIRECTORY;
@@ -243,6 +245,7 @@ import static org.apache.iotdb.db.conf.IoTDBConstant.FUNCTION_TYPE_NATIVE;
 import static org.apache.iotdb.db.conf.IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD;
 import static org.apache.iotdb.db.conf.IoTDBConstant.QUERY_ID;
 import static org.apache.iotdb.db.conf.IoTDBConstant.STATEMENT;
+import static org.apache.iotdb.db.conf.IoTDBConstant.SYSTEM_STORAGE_GROUP;
 import static org.apache.iotdb.rpc.TSStatusCode.INTERNAL_SERVER_ERROR;
 import static org.apache.iotdb.tsfile.common.constant.TsFileConstant.TSFILE_SUFFIX;
 
@@ -250,8 +253,7 @@ public class PlanExecutor implements IPlanExecutor {
 
   private static final Logger logger = LoggerFactory.getLogger(PlanExecutor.class);
   private static boolean enableAuditLog =
-      !AuditLogUtils.LOG_LEVEL_NONE.equals(
-          IoTDBDescriptor.getInstance().getConfig().getAuditLogStorage());
+      IoTDBDescriptor.getInstance().getConfig().isEnableAuditLog();
 
   private static final Logger DEBUG_LOGGER = LoggerFactory.getLogger("QUERY_DEBUG");
   // for data query
@@ -452,6 +454,9 @@ public class PlanExecutor implements IPlanExecutor {
       throws QueryProcessException {
     try {
       IoTDB.metaManager.createSchemaTemplate(createTemplatePlan);
+      if (enableAuditLog) {
+        AuditLogger.log(String.format("create template %s", createTemplatePlan.getName()), DDL);
+      }
     } catch (MetadataException e) {
       throw new QueryProcessException(e);
     }
@@ -461,6 +466,9 @@ public class PlanExecutor implements IPlanExecutor {
   private boolean dropTemplate(DropTemplatePlan dropTemplatePlan) throws QueryProcessException {
     try {
       IoTDB.metaManager.dropSchemaTemplate(dropTemplatePlan);
+      if (enableAuditLog) {
+        AuditLogger.log(String.format("drop template %s", dropTemplatePlan.getName()), DDL);
+      }
     } catch (MetadataException e) {
       throw new QueryProcessException(e);
     }
@@ -470,6 +478,9 @@ public class PlanExecutor implements IPlanExecutor {
   private boolean appendTemplate(AppendTemplatePlan plan) throws QueryProcessException {
     try {
       IoTDB.metaManager.appendSchemaTemplate(plan);
+      if (enableAuditLog) {
+        AuditLogger.log(String.format("append template %s", plan.getName()), DDL);
+      }
     } catch (MetadataException e) {
       throw new QueryProcessException(e);
     }
@@ -479,6 +490,9 @@ public class PlanExecutor implements IPlanExecutor {
   private boolean pruneTemplate(PruneTemplatePlan plan) throws QueryProcessException {
     try {
       IoTDB.metaManager.pruneSchemaTemplate(plan);
+      if (enableAuditLog) {
+        AuditLogger.log(String.format("prune template %s", plan.getName()), DDL);
+      }
     } catch (MetadataException e) {
       throw new QueryProcessException(e);
     }
@@ -488,6 +502,9 @@ public class PlanExecutor implements IPlanExecutor {
   private boolean setTemplate(SetTemplatePlan setTemplatePlan) throws QueryProcessException {
     try {
       IoTDB.metaManager.setSchemaTemplate(setTemplatePlan);
+      if (enableAuditLog) {
+        AuditLogger.log(String.format("set template %s", setTemplatePlan.getTemplateName()), DDL);
+      }
     } catch (MetadataException e) {
       throw new QueryProcessException(e);
     }
@@ -498,6 +515,10 @@ public class PlanExecutor implements IPlanExecutor {
       throws QueryProcessException {
     try {
       IoTDB.metaManager.setUsingSchemaTemplate(activateTemplatePlan);
+      if (enableAuditLog) {
+        AuditLogger.log(
+            String.format("active template in %s", activateTemplatePlan.getPaths()), DML);
+      }
     } catch (MetadataException e) {
       throw new QueryProcessException(e);
     }
@@ -536,7 +557,7 @@ public class PlanExecutor implements IPlanExecutor {
 
       // delete related data
       if (enableAuditLog) {
-        AuditLogUtils.writeAuditLog(String.format("delete timeseries %s", pathToDelete));
+        AuditLogger.log(String.format("delete timeseries %s", pathToDelete), DDL);
       }
       DeleteTimeSeriesPlan dtsp = new DeleteTimeSeriesPlan(pathToDelete);
       for (PartialPath path : pathToDelete) {
@@ -561,6 +582,10 @@ public class PlanExecutor implements IPlanExecutor {
   private boolean unsetTemplate(UnsetTemplatePlan unsetTemplatePlan) throws QueryProcessException {
     try {
       IoTDB.metaManager.unsetSchemaTemplate(unsetTemplatePlan);
+      if (enableAuditLog) {
+        AuditLogger.log(
+            String.format("unset template %s", unsetTemplatePlan.getTemplateName()), DML);
+      }
     } catch (MetadataException e) {
       throw new QueryProcessException(e);
     }
@@ -569,33 +594,54 @@ public class PlanExecutor implements IPlanExecutor {
 
   private boolean operateCreateFunction(CreateFunctionPlan plan) throws UDFRegistrationException {
     UDFRegistrationService.getInstance().register(plan.getUdfName(), plan.getClassName(), true);
+    if (enableAuditLog) {
+      AuditLogger.log(
+          String.format(
+              "create function,udf name: %s,class name:%s", plan.getUdfName(), plan.getClassName()),
+          DDL);
+    }
     return true;
   }
 
   private boolean operateDropFunction(DropFunctionPlan plan) throws UDFRegistrationException {
     UDFRegistrationService.getInstance().deregister(plan.getUdfName());
+    if (enableAuditLog) {
+      AuditLogger.log(String.format("drop function,udf name: %s", plan.getUdfName()), DDL);
+    }
     return true;
   }
 
   private boolean operateCreateTrigger(CreateTriggerPlan plan)
       throws TriggerManagementException, TriggerExecutionException {
     TriggerRegistrationService.getInstance().register(plan);
+    if (enableAuditLog) {
+      AuditLogger.log(String.format("create trigger %s", plan.getTriggerName()), DDL);
+    }
     return true;
   }
 
   private boolean operateDropTrigger(DropTriggerPlan plan) throws TriggerManagementException {
     TriggerRegistrationService.getInstance().deregister(plan);
+    if (enableAuditLog) {
+      AuditLogger.log(String.format("drop trigger %s", plan.getTriggerName()), DDL);
+    }
     return true;
   }
 
   private boolean operateStartTrigger(StartTriggerPlan plan)
       throws TriggerManagementException, TriggerExecutionException {
     TriggerRegistrationService.getInstance().activate(plan);
+    if (enableAuditLog) {
+      AuditLogger.log(String.format("start trigger %s", plan.getTriggerName()), DML);
+    }
     return true;
   }
 
   private boolean operateStopTrigger(StopTriggerPlan plan) throws TriggerManagementException {
     TriggerRegistrationService.getInstance().inactivate(plan);
+    if (enableAuditLog) {
+      AuditLogger.log(String.format("stop trigger %s", plan.getTriggerName()), DML);
+    }
     return true;
   }
 
@@ -611,6 +657,9 @@ public class PlanExecutor implements IPlanExecutor {
 
   private void operateCreateSnapshot() {
     IoTDB.metaManager.createMTreeSnapshot();
+    if (enableAuditLog) {
+      AuditLogger.log("create snapshot", DDL);
+    }
   }
 
   private void operateKillQuery(KillQueryPlan killQueryPlan) throws QueryIdNotExsitException {
@@ -1395,12 +1444,13 @@ public class PlanExecutor implements IPlanExecutor {
   @Override
   public void delete(DeletePlan deletePlan) throws QueryProcessException {
     if (enableAuditLog) {
-      AuditLogUtils.writeAuditLog(
+      AuditLogger.log(
           String.format(
               "delete data from %s in [%s,%s]",
               deletePlan.getPaths(),
               deletePlan.getDeleteStartTime(),
-              deletePlan.getDeleteEndTime()));
+              deletePlan.getDeleteEndTime()),
+          DML);
     }
 
     for (PartialPath path : deletePlan.getPaths()) {
@@ -1419,6 +1469,9 @@ public class PlanExecutor implements IPlanExecutor {
       throw new QueryProcessException(
           String.format("File path '%s' doesn't exists.", file.getPath()));
     }
+    if (enableAuditLog) {
+      AuditLogger.log(String.format("load files from %s ", file.getPath()), DDL);
+    }
     if (file.isDirectory()) {
       loadDir(file, plan);
     } else {
@@ -1681,6 +1734,10 @@ public class PlanExecutor implements IPlanExecutor {
         throw new QueryProcessException(
             String.format("File '%s' doesn't exist.", plan.getFile().getAbsolutePath()));
       }
+      if (enableAuditLog) {
+        AuditLogger.log(
+            String.format("remove file from %s ", plan.getFile().getAbsolutePath()), DDL);
+      }
     } catch (StorageEngineException | IllegalPathException e) {
       throw new QueryProcessException(
           String.format("Cannot remove file because %s", e.getMessage()));
@@ -1698,6 +1755,10 @@ public class PlanExecutor implements IPlanExecutor {
         throw new QueryProcessException(
             String.format("File '%s' doesn't exist.", plan.getFile().getAbsolutePath()));
       }
+      if (enableAuditLog) {
+        AuditLogger.log(
+            String.format("unload file from %s ", plan.getFile().getAbsolutePath()), DDL);
+      }
     } catch (StorageEngineException | IllegalPathException e) {
       throw new QueryProcessException(
           String.format(
@@ -1915,6 +1976,15 @@ public class PlanExecutor implements IPlanExecutor {
                   insertRowPlan.getValues()[i], insertRowPlan.isNeedInferType());
         }
       }
+      if (!insertRowPlan.getDevicePath().getFullPath().startsWith(SYSTEM_STORAGE_GROUP)
+          && enableAuditLog) {
+        AuditLogger.log(
+            String.format(
+                "insert into %s , paths: %s,time: %s ",
+                insertRowPlan.getDevicePath(), insertRowPlan.getPaths(), insertRowPlan.getTime()),
+            DML,
+            insertRowPlan.isNativeInsertApi());
+      }
 
       StorageEngine.getInstance().insert(insertRowPlan);
 
@@ -1931,6 +2001,17 @@ public class PlanExecutor implements IPlanExecutor {
   @Override
   public void insertTablet(InsertMultiTabletPlan insertMultiTabletPlan)
       throws QueryProcessException {
+    if (enableAuditLog) {
+      AuditLogger.log(
+          String.format(
+              "insert into %s,paths:%s,time start: %s,time end: %s ",
+              insertMultiTabletPlan.getDevicePath(),
+              insertMultiTabletPlan.getPaths(),
+              insertMultiTabletPlan.getMinTime(),
+              insertMultiTabletPlan.getMaxTime()),
+          DML,
+          insertMultiTabletPlan.isNativeInsertApi());
+    }
     if (insertMultiTabletPlan.isEnableMultiThreading()) {
       insertTabletParallel(insertMultiTabletPlan);
     } else {
@@ -2030,7 +2111,17 @@ public class PlanExecutor implements IPlanExecutor {
     try {
       insertTabletPlan.setMeasurementMNodes(
           new IMeasurementMNode[insertTabletPlan.getMeasurements().length]);
-
+      if (enableAuditLog) {
+        AuditLogger.log(
+            String.format(
+                "insert into %s , paths: %s , time start: %s ,time end: %s ",
+                insertTabletPlan.getDevicePath(),
+                insertTabletPlan.getPaths(),
+                insertTabletPlan.getTimes()[0],
+                insertTabletPlan.getTimes()[insertTabletPlan.getTimes().length - 1]),
+            DML,
+            insertTabletPlan.isNativeInsertApi());
+      }
       StorageEngine.getInstance().insertTablet(insertTabletPlan);
 
       if (insertTabletPlan.getFailedMeasurements() != null) {
@@ -2119,6 +2210,10 @@ public class PlanExecutor implements IPlanExecutor {
       throws QueryProcessException {
     try {
       IoTDB.metaManager.createTimeseries(createTimeSeriesPlan);
+      if (enableAuditLog) {
+        AuditLogger.log(
+            String.format("create time series %s", createTimeSeriesPlan.getPaths()), DDL);
+      }
     } catch (MetadataException e) {
       throw new QueryProcessException(e);
     }
@@ -2129,6 +2224,11 @@ public class PlanExecutor implements IPlanExecutor {
       throws QueryProcessException {
     try {
       IoTDB.metaManager.createAlignedTimeSeries(createAlignedTimeSeriesPlan);
+      if (enableAuditLog) {
+        AuditLogger.log(
+            String.format("create aligned time series %s", createAlignedTimeSeriesPlan.getPaths()),
+            DDL);
+      }
     } catch (MetadataException e) {
       throw new QueryProcessException(e);
     }
@@ -2171,8 +2271,7 @@ public class PlanExecutor implements IPlanExecutor {
   protected boolean deleteTimeSeries(DeleteTimeSeriesPlan deleteTimeSeriesPlan)
       throws QueryProcessException {
     if (enableAuditLog) {
-      AuditLogUtils.writeAuditLog(
-          String.format("delete timeseries %s", deleteTimeSeriesPlan.getPaths()));
+      AuditLogger.log(String.format("delete time series %s", deleteTimeSeriesPlan.getPaths()), DDL);
     }
     List<PartialPath> deletePathList = deleteTimeSeriesPlan.getPaths();
     for (int i = 0; i < deletePathList.size(); i++) {
@@ -2212,6 +2311,13 @@ public class PlanExecutor implements IPlanExecutor {
       throws QueryProcessException {
     PartialPath path = alterTimeSeriesPlan.getPath();
     Map<String, String> alterMap = alterTimeSeriesPlan.getAlterMap();
+    if (enableAuditLog) {
+      AuditLogger.log(
+          String.format(
+              "alter time series %s,alter type:%s",
+              alterTimeSeriesPlan.getPaths(), alterTimeSeriesPlan.getAlterType()),
+          DDL);
+    }
     try {
       switch (alterTimeSeriesPlan.getAlterType()) {
         case RENAME:
@@ -2253,8 +2359,8 @@ public class PlanExecutor implements IPlanExecutor {
   public boolean setStorageGroup(SetStorageGroupPlan setStorageGroupPlan)
       throws QueryProcessException {
     if (enableAuditLog) {
-      AuditLogUtils.writeAuditLog(
-          String.format("set storage group to %s", setStorageGroupPlan.getPaths()));
+      AuditLogger.log(
+          String.format("set storage group to %s", setStorageGroupPlan.getPaths()), DDL);
     }
     PartialPath path = setStorageGroupPlan.getPath();
     try {
@@ -2268,8 +2374,8 @@ public class PlanExecutor implements IPlanExecutor {
   protected boolean deleteStorageGroups(DeleteStorageGroupPlan deleteStorageGroupPlan)
       throws QueryProcessException {
     if (enableAuditLog) {
-      AuditLogUtils.writeAuditLog(
-          String.format("set storage group to %s", deleteStorageGroupPlan.getPaths()));
+      AuditLogger.log(
+          String.format("set storage group to %s", deleteStorageGroupPlan.getPaths()), DDL);
     }
     List<PartialPath> deletePathList = new ArrayList<>();
     try {
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/PhysicalPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/PhysicalPlan.java
index 443561c703..8e2a36cd1e 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/PhysicalPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/PhysicalPlan.java
@@ -114,6 +114,8 @@ public abstract class PhysicalPlan {
    */
   private boolean isPrefixMatch = false;
 
+  protected boolean isNativeInsertApi = false;
+
   /** whether the plan can be split into more than one Plans. Only used in the cluster mode. */
   public boolean canBeSplit() {
     return canBeSplit;
@@ -589,4 +591,12 @@ public abstract class PhysicalPlan {
   public void setPrefixMatch(boolean prefixMatch) {
     isPrefixMatch = prefixMatch;
   }
+
+  public boolean isNativeInsertApi() {
+    return isNativeInsertApi;
+  }
+
+  public void setNativeInsertApi(boolean nativeInsertApi) {
+    this.isNativeInsertApi = nativeInsertApi;
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/query/control/SessionManager.java b/server/src/main/java/org/apache/iotdb/db/query/control/SessionManager.java
index 6169405bf1..5fd4dfbd2a 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/control/SessionManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/control/SessionManager.java
@@ -140,8 +140,7 @@ public class SessionManager implements SessionManagerMBean {
       IClientSession session,
       String username,
       String zoneId,
-      IoTDBConstant.ClientVersion clientVersion,
-      boolean enableAudit) {
+      IoTDBConstant.ClientVersion clientVersion) {
     session.setId(sessionIdGenerator.incrementAndGet());
     session.setUsername(username);
     ZoneId curZoneId;
@@ -154,7 +153,6 @@ public class SessionManager implements SessionManagerMBean {
     session.setClientVersion(clientVersion);
     session.setLogin(true);
     session.setLogInTime(System.currentTimeMillis());
-    session.setEnableAudit(enableAudit);
   }
 
   /**
diff --git a/server/src/main/java/org/apache/iotdb/db/service/basic/ServiceProvider.java b/server/src/main/java/org/apache/iotdb/db/service/basic/ServiceProvider.java
index 65e153d812..11c488e55c 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/basic/ServiceProvider.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/basic/ServiceProvider.java
@@ -19,6 +19,8 @@
 
 package org.apache.iotdb.db.service.basic;
 
+import org.apache.iotdb.db.audit.AuditLogOperation;
+import org.apache.iotdb.db.audit.AuditLogger;
 import org.apache.iotdb.db.auth.AuthException;
 import org.apache.iotdb.db.auth.AuthorityChecker;
 import org.apache.iotdb.db.auth.authorizer.BasicAuthorizer;
@@ -43,7 +45,6 @@ import org.apache.iotdb.db.query.control.SessionManager;
 import org.apache.iotdb.db.query.control.SessionTimeoutManager;
 import org.apache.iotdb.db.query.control.clientsession.IClientSession;
 import org.apache.iotdb.db.query.control.tracing.TracingManager;
-import org.apache.iotdb.db.utils.AuditLogUtils;
 import org.apache.iotdb.rpc.RpcUtils;
 import org.apache.iotdb.rpc.TSStatusCode;
 import org.apache.iotdb.service.rpc.thrift.TSProtocolVersion;
@@ -83,8 +84,7 @@ public abstract class ServiceProvider {
 
   public static SessionManager SESSION_MANAGER = SessionManager.getInstance();
 
-  private static final boolean enableAuditLog =
-      !AuditLogUtils.LOG_LEVEL_NONE.equals(CONFIG.getAuditLogStorage());
+  public static final boolean enableAuditLog = CONFIG.isEnableAuditLog();
 
   private final Planner planner;
   protected final IPlanExecutor executor;
@@ -175,8 +175,7 @@ public abstract class ServiceProvider {
       String password,
       String zoneId,
       TSProtocolVersion tsProtocolVersion,
-      IoTDBConstant.ClientVersion clientVersion,
-      boolean enableAudit)
+      IoTDBConstant.ClientVersion clientVersion)
       throws TException {
     BasicOpenSessionResp openSessionResp = new BasicOpenSessionResp();
 
@@ -209,12 +208,13 @@ public abstract class ServiceProvider {
       openSessionResp.setCode(TSStatusCode.SUCCESS_STATUS.getStatusCode());
       openSessionResp.setMessage("Login successfully");
 
-      SESSION_MANAGER.supplySession(session, username, zoneId, clientVersion, enableAudit);
+      SESSION_MANAGER.supplySession(session, username, zoneId, clientVersion);
       if (enableAuditLog) {
-        AuditLogUtils.writeAuditLog(
+        AuditLogger.log(
             String.format(
                 "%s: Login status: %s. User : %s, opens Session-%s",
-                IoTDBConstant.GLOBAL_DB_NAME, openSessionResp.getMessage(), username, session));
+                IoTDBConstant.GLOBAL_DB_NAME, openSessionResp.getMessage(), username, session),
+            AuditLogOperation.QUERY);
       }
 
     } else {
@@ -222,9 +222,9 @@ public abstract class ServiceProvider {
       openSessionResp.setCode(TSStatusCode.WRONG_LOGIN_PASSWORD_ERROR.getStatusCode());
       session.setUsername(username);
       if (enableAuditLog) {
-        AuditLogUtils.writeAuditLog(
+        AuditLogger.log(
             String.format("User %s opens Session failed with an incorrect password", username),
-            true);
+            AuditLogOperation.QUERY);
       }
       // TODO we should close this connection ASAP, otherwise there will be DDoS.
     }
@@ -240,19 +240,10 @@ public abstract class ServiceProvider {
       TSProtocolVersion tsProtocolVersion)
       throws TException {
     return login(
-        session,
-        username,
-        password,
-        zoneId,
-        tsProtocolVersion,
-        IoTDBConstant.ClientVersion.V_0_12,
-        false);
+        session, username, password, zoneId, tsProtocolVersion, IoTDBConstant.ClientVersion.V_0_12);
   }
 
   public boolean closeSession(IClientSession session) {
-    if (enableAuditLog) {
-      AuditLogUtils.writeAuditLog(String.format("Session-%s is closing", session));
-    }
     return SessionTimeoutManager.getInstance().unregister(session);
   }
 
@@ -270,12 +261,7 @@ public abstract class ServiceProvider {
     if (checkSessionTimeout(session)) {
       return RpcUtils.getStatus(TSStatusCode.SESSION_TIMEOUT, "Session timeout");
     }
-    if (enableAuditLog) {
-      AuditLogUtils.writeAuditLog(
-          String.format(
-              "%s: receive close operation from Session %s",
-              IoTDBConstant.GLOBAL_DB_NAME, session));
-    }
+
     try {
       if (haveStatementId) {
         if (haveSetQueryId) {
diff --git a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/TSServiceImpl.java b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/TSServiceImpl.java
index 47176a83ba..20984d4459 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/TSServiceImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/TSServiceImpl.java
@@ -18,6 +18,7 @@
  */
 package org.apache.iotdb.db.service.thrift.impl;
 
+import org.apache.iotdb.db.audit.AuditLogger;
 import org.apache.iotdb.db.auth.AuthException;
 import org.apache.iotdb.db.auth.AuthorityChecker;
 import org.apache.iotdb.db.auth.authorizer.BasicAuthorizer;
@@ -78,7 +79,6 @@ import org.apache.iotdb.db.service.metrics.MetricService;
 import org.apache.iotdb.db.service.metrics.enums.Operation;
 import org.apache.iotdb.db.tools.watermark.GroupedLSBWatermarkEncoder;
 import org.apache.iotdb.db.tools.watermark.WatermarkEncoder;
-import org.apache.iotdb.db.utils.AuditLogUtils;
 import org.apache.iotdb.db.utils.QueryDataSetUtils;
 import org.apache.iotdb.metrics.config.MetricConfigDescriptor;
 import org.apache.iotdb.metrics.utils.MetricLevel;
@@ -159,9 +159,9 @@ import java.util.concurrent.Callable;
 import java.util.concurrent.Future;
 import java.util.stream.Collectors;
 
+import static org.apache.iotdb.db.audit.AuditLogOperation.QUERY;
 import static org.apache.iotdb.db.conf.IoTDBConstant.AUTH_ENABLE_AUDIT;
 import static org.apache.iotdb.db.conf.IoTDBConstant.CONSTANT_VERSION;
-import static org.apache.iotdb.db.conf.IoTDBConstant.SYSTEM_STORAGE_GROUP;
 import static org.apache.iotdb.db.service.basic.ServiceProvider.CONFIG;
 import static org.apache.iotdb.db.service.basic.ServiceProvider.CURRENT_RPC_VERSION;
 import static org.apache.iotdb.db.service.basic.ServiceProvider.QUERY_FREQUENCY_RECORDER;
@@ -169,6 +169,7 @@ import static org.apache.iotdb.db.service.basic.ServiceProvider.QUERY_TIME_MANAG
 import static org.apache.iotdb.db.service.basic.ServiceProvider.SESSION_MANAGER;
 import static org.apache.iotdb.db.service.basic.ServiceProvider.SLOW_SQL_LOGGER;
 import static org.apache.iotdb.db.service.basic.ServiceProvider.TRACING_MANAGER;
+import static org.apache.iotdb.db.service.basic.ServiceProvider.enableAuditLog;
 import static org.apache.iotdb.db.utils.ErrorHandlingUtils.onIoTDBException;
 import static org.apache.iotdb.db.utils.ErrorHandlingUtils.onNPEOrUnexpectedException;
 import static org.apache.iotdb.db.utils.ErrorHandlingUtils.onNonQueryException;
@@ -180,11 +181,6 @@ public class TSServiceImpl implements TSIService.Iface {
   private static final boolean isEnableOperationSync =
       IoTDBDescriptor.getInstance().getConfig().isEnableOperationSync();
 
-  private static final IoTDBConfig conf = IoTDBDescriptor.getInstance().getConfig();
-
-  private static final boolean enableAuditLog =
-      !AuditLogUtils.LOG_LEVEL_NONE.equals(conf.getAuditLogStorage());
-
   protected class QueryTask implements Callable<TSExecuteStatementResp> {
 
     private PhysicalPlan plan;
@@ -229,10 +225,6 @@ public class TSServiceImpl implements TSIService.Iface {
       plan.setLoginUserName(username);
 
       QUERY_FREQUENCY_RECORDER.incrementAndGet();
-      if (enableAuditLog) {
-        AuditLogUtils.writeAuditLog(
-            String.format("Session %s execute Query: %s", session, statement));
-      }
       final long queryId = SESSION_MANAGER.requestQueryId(statementId, true);
       QueryContext context =
           serviceProvider.genQueryContext(
@@ -341,8 +333,7 @@ public class TSServiceImpl implements TSIService.Iface {
             req.password,
             req.zoneId,
             req.client_protocol,
-            clientVersion,
-            enableAudit);
+            clientVersion);
     TSStatus tsStatus = RpcUtils.getStatus(openSessionResp.getCode(), openSessionResp.getMessage());
     TSOpenSessionResp resp = new TSOpenSessionResp(tsStatus, CURRENT_RPC_VERSION);
     return resp.setSessionId(openSessionResp.getSessionId());
@@ -652,11 +643,11 @@ public class TSServiceImpl implements TSIService.Iface {
           serviceProvider
               .getPlanner()
               .parseSQLToPhysicalPlan(statement, session.getZoneId(), session.getClientVersion());
-      if (enableAuditLog) {
-        AuditLogUtils.writeAuditLog(req.getStatement());
-      }
 
       if (physicalPlan.isQuery()) {
+        if (enableAuditLog) {
+          AuditLogger.log(req.getStatement(), QUERY);
+        }
         return submitQueryTask(session, physicalPlan, startTime, req);
       } else {
         return executeUpdateStatement(
@@ -687,10 +678,11 @@ public class TSServiceImpl implements TSIService.Iface {
           serviceProvider
               .getPlanner()
               .parseSQLToPhysicalPlan(statement, session.getZoneId(), session.getClientVersion());
-      if (enableAuditLog) {
-        AuditLogUtils.writeAuditLog(statement);
-      }
+
       if (physicalPlan.isQuery()) {
+        if (enableAuditLog) {
+          AuditLogger.log(req.getStatement(), QUERY);
+        }
         return submitQueryTask(session, physicalPlan, startTime, req);
       } else {
         return RpcUtils.getTSExecuteStatementResp(
@@ -971,10 +963,6 @@ public class TSServiceImpl implements TSIService.Iface {
     final QueryPlan queryPlan = selectIntoPlan.getQueryPlan();
 
     QUERY_FREQUENCY_RECORDER.incrementAndGet();
-    if (enableAuditLog) {
-      AuditLogUtils.writeAuditLog(
-          String.format("Session %s execute select into: %s", session, statement));
-    }
 
     if (queryPlan.isEnableTracing()) {
       TRACING_MANAGER.setSeriesPathNum(queryId, queryPlan.getPaths().size());
@@ -1227,13 +1215,6 @@ public class TSServiceImpl implements TSIService.Iface {
       return loginStatus;
     }
 
-    if (conf.isEnableAuditLogWrite() && enableAuditLog) {
-      AuditLogUtils.writeAuditLog(
-          String.format(
-              "Session %s insertRecords, first device %s, first time %s",
-              session, req.prefixPaths.get(0), req.getTimestamps().get(0)));
-    }
-
     boolean allCheckSuccess = true;
     InsertRowsPlan insertRowsPlan = new InsertRowsPlan();
     for (int i = 0; i < req.prefixPaths.size(); i++) {
@@ -1245,6 +1226,7 @@ public class TSServiceImpl implements TSIService.Iface {
                 req.getMeasurementsList().get(i).toArray(new String[0]),
                 req.valuesList.get(i),
                 req.isAligned);
+        plan.setNativeInsertApi(true);
         TSStatus status = serviceProvider.checkAuthority(plan, session);
         if (status != null) {
           insertRowsPlan.getResults().put(i, status);
@@ -1316,13 +1298,6 @@ public class TSServiceImpl implements TSIService.Iface {
       return loginStatus;
     }
 
-    if (conf.isEnableAuditLogWrite() && enableAuditLog) {
-      AuditLogUtils.writeAuditLog(
-          String.format(
-              "Session %s insertRecords, device %s, first time %s",
-              session, req.prefixPath, req.getTimestamps().get(0)));
-    }
-
     List<TSStatus> statusList = new ArrayList<>();
     try {
       InsertRowsOfOneDevicePlan plan =
@@ -1332,6 +1307,7 @@ public class TSServiceImpl implements TSIService.Iface {
               req.getMeasurementsList(),
               req.getValuesList(),
               req.isAligned);
+      plan.setNativeInsertApi(true);
       TSStatus status = serviceProvider.checkAuthority(plan, session);
       statusList.add(status != null ? status : executeNonQueryPlan(plan));
     } catch (IoTDBException e) {
@@ -1363,13 +1339,6 @@ public class TSServiceImpl implements TSIService.Iface {
       return loginStatus;
     }
 
-    if (conf.isEnableAuditLogWrite() && enableAuditLog) {
-      AuditLogUtils.writeAuditLog(
-          String.format(
-              "Session %s insertRecords, device %s, first time %s",
-              session, req.prefixPath, req.getTimestamps().get(0)));
-    }
-
     boolean allCheckSuccess = true;
     InsertRowsPlan insertRowsPlan = new InsertRowsPlan();
     for (int i = 0; i < req.timestamps.size(); i++) {
@@ -1381,6 +1350,7 @@ public class TSServiceImpl implements TSIService.Iface {
         plan.setDataTypes(new TSDataType[plan.getMeasurements().length]);
         plan.setNeedInferType(true);
         plan.setAligned(req.isAligned);
+        plan.setNativeInsertApi(true);
         TSStatus status = serviceProvider.checkAuthority(plan, session);
 
         if (status != null) {
@@ -1422,13 +1392,6 @@ public class TSServiceImpl implements TSIService.Iface {
       return loginStatus;
     }
 
-    if (conf.isEnableAuditLogWrite() && enableAuditLog) {
-      AuditLogUtils.writeAuditLog(
-          String.format(
-              "Session %s insertRecords, first device %s, first time %s",
-              session, req.prefixPaths.get(0), req.getTimestamps().get(0)));
-    }
-
     boolean allCheckSuccess = true;
     InsertRowsPlan insertRowsPlan = new InsertRowsPlan();
     for (int i = 0; i < req.prefixPaths.size(); i++) {
@@ -1536,14 +1499,6 @@ public class TSServiceImpl implements TSIService.Iface {
       if (isStatusNotSuccess(loginStatus)) {
         return loginStatus;
       }
-      if (!req.getPrefixPath().startsWith(SYSTEM_STORAGE_GROUP)
-          && conf.isEnableAuditLogWrite()
-          && enableAuditLog) {
-        AuditLogUtils.writeAuditLog(
-            String.format(
-                "Session %s insertRecord, device %s, time %s",
-                session, req.getPrefixPath(), req.getTimestamp()));
-      }
 
       InsertRowPlan plan =
           new InsertRowPlan(
@@ -1552,6 +1507,7 @@ public class TSServiceImpl implements TSIService.Iface {
               req.getMeasurements().toArray(new String[0]),
               req.values,
               req.isAligned);
+      plan.setNativeInsertApi(true);
       TSStatus status = serviceProvider.checkAuthority(plan, session);
 
       if (status != null) {
@@ -1575,12 +1531,6 @@ public class TSServiceImpl implements TSIService.Iface {
       if (isStatusNotSuccess(loginStatus)) {
         return loginStatus;
       }
-      if (conf.isEnableAuditLogWrite() && enableAuditLog) {
-        AuditLogUtils.writeAuditLog(
-            String.format(
-                "Session %s insertRecord, device %s, time %s",
-                session, req.getPrefixPath(), req.getTimestamp()));
-      }
 
       InsertRowPlan plan = new InsertRowPlan();
       plan.setDevicePath(new PartialPath(req.getPrefixPath()));
@@ -1590,6 +1540,7 @@ public class TSServiceImpl implements TSIService.Iface {
       plan.setValues(req.getValues().toArray(new Object[0]));
       plan.setNeedInferType(true);
       plan.setAligned(req.isAligned);
+      plan.setNativeInsertApi(true);
       TSStatus status = serviceProvider.checkAuthority(plan, session);
 
       if (status != null) {
@@ -1652,6 +1603,7 @@ public class TSServiceImpl implements TSIService.Iface {
       insertTabletPlan.setRowCount(req.size);
       insertTabletPlan.setDataTypes(req.types);
       insertTabletPlan.setAligned(req.isAligned);
+      insertTabletPlan.setNativeInsertApi(true);
       TSStatus status = serviceProvider.checkAuthority(insertTabletPlan, session);
 
       if (status != null) {
@@ -1721,6 +1673,7 @@ public class TSServiceImpl implements TSIService.Iface {
     InsertMultiTabletPlan insertMultiTabletPlan = new InsertMultiTabletPlan();
     for (int i = 0; i < req.prefixPaths.size(); i++) {
       InsertTabletPlan insertTabletPlan = constructInsertTabletPlan(req, i);
+      insertTabletPlan.setNativeInsertApi(true);
       TSStatus status = serviceProvider.checkAuthority(insertTabletPlan, session);
       if (status != null) {
         // not authorized
@@ -1786,10 +1739,6 @@ public class TSServiceImpl implements TSIService.Iface {
       if (isStatusNotSuccess(loginStatus)) {
         return loginStatus;
       }
-      if (enableAuditLog) {
-        AuditLogUtils.writeAuditLog(
-            String.format("Session-%s create timeseries %s", session, req.getPath()));
-      }
 
       CreateTimeSeriesPlan plan =
           new CreateTimeSeriesPlan(
@@ -1819,12 +1768,6 @@ public class TSServiceImpl implements TSIService.Iface {
       if (isStatusNotSuccess(loginStatus)) {
         return loginStatus;
       }
-      if (enableAuditLog) {
-        AuditLogUtils.writeAuditLog(
-            String.format(
-                "Session-%s create aligned timeseries %s.%s",
-                session, req.getPrefixPath(), req.getMeasurements()));
-      }
 
       List<TSDataType> dataTypes = new ArrayList<>();
       for (int dataType : req.dataTypes) {
@@ -1866,12 +1809,6 @@ public class TSServiceImpl implements TSIService.Iface {
       if (isStatusNotSuccess(loginStatus)) {
         return loginStatus;
       }
-      if (enableAuditLog) {
-        AuditLogUtils.writeAuditLog(
-            String.format(
-                "Session-%s create %s timeseries, the first is %s",
-                session, req.getPaths().size(), req.getPaths().get(0)));
-      }
 
       CreateMultiTimeSeriesPlan multiPlan = new CreateMultiTimeSeriesPlan();
       List<PartialPath> paths = new ArrayList<>(req.paths.size());
@@ -1983,10 +1920,6 @@ public class TSServiceImpl implements TSIService.Iface {
       if (isStatusNotSuccess(loginStatus)) {
         return loginStatus;
       }
-      if (enableAuditLog) {
-        AuditLogUtils.writeAuditLog(
-            String.format("Session-%s create schema template %s", session, req.getName()));
-      }
 
       CreateTemplatePlan plan;
       // Construct plan from serialized request
@@ -2089,12 +2022,6 @@ public class TSServiceImpl implements TSIService.Iface {
     if (isStatusNotSuccess(loginStatus)) {
       return loginStatus;
     }
-    if (enableAuditLog) {
-      AuditLogUtils.writeAuditLog(
-          String.format(
-              "Session-%s set device template %s.%s",
-              session, req.getTemplateName(), req.getPrefixPath()));
-    }
 
     try {
       SetTemplatePlan plan = new SetTemplatePlan(req.templateName, req.prefixPath);
@@ -2112,12 +2039,7 @@ public class TSServiceImpl implements TSIService.Iface {
     if (isStatusNotSuccess(loginStatus)) {
       return loginStatus;
     }
-    if (enableAuditLog) {
-      AuditLogUtils.writeAuditLog(
-          String.format(
-              "Session-%s unset schema template %s.%s",
-              session, req.getPrefixPath(), req.getTemplateName()));
-    }
+
     try {
       UnsetTemplatePlan plan = new UnsetTemplatePlan(req.prefixPath, req.templateName);
       TSStatus status = serviceProvider.checkAuthority(plan, session);
@@ -2135,12 +2057,6 @@ public class TSServiceImpl implements TSIService.Iface {
     if (isStatusNotSuccess(loginStatus)) {
       return loginStatus;
     }
-    if (enableAuditLog) {
-      AuditLogUtils.writeAuditLog(
-          String.format(
-              "Session-%s unset using schema template %s on %s",
-              session, templateName, prefixPath));
-    }
 
     try {
       DeactivateTemplatePlan plan =
@@ -2159,12 +2075,6 @@ public class TSServiceImpl implements TSIService.Iface {
     if (isStatusNotSuccess(loginStatus)) {
       return loginStatus;
     }
-    if (enableAuditLog) {
-      AuditLogUtils.writeAuditLog(
-          String.format(
-              "Session-%s create timeseries of schema template on path %s",
-              session, req.getDstPath()));
-    }
 
     try {
       ActivateTemplatePlan plan = new ActivateTemplatePlan(new PartialPath(req.getDstPath()));
@@ -2182,10 +2092,6 @@ public class TSServiceImpl implements TSIService.Iface {
     if (isStatusNotSuccess(loginStatus)) {
       return loginStatus;
     }
-    if (enableAuditLog) {
-      AuditLogUtils.writeAuditLog(
-          String.format("Session-%s drop schema template %s.", session, req.getTemplateName()));
-    }
 
     DropTemplatePlan plan = new DropTemplatePlan(req.templateName);
     TSStatus status = serviceProvider.checkAuthority(plan, session);
diff --git a/server/src/test/java/org/apache/iotdb/db/qp/physical/InsertTabletMultiPlanTest.java b/server/src/test/java/org/apache/iotdb/db/qp/physical/InsertTabletMultiPlanTest.java
index 429fb02e12..32f0e40df1 100644
--- a/server/src/test/java/org/apache/iotdb/db/qp/physical/InsertTabletMultiPlanTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/qp/physical/InsertTabletMultiPlanTest.java
@@ -187,7 +187,8 @@ public class InsertTabletMultiPlanTest extends InsertTabletPlanTest {
     Assert.assertTrue(insertMultiTabletPlan.isEnableMultiThreading());
     executor.insertTablet(insertMultiTabletPlan);
 
-    QueryPlan queryPlan = (QueryPlan) processor.parseSQLToPhysicalPlan("select * from root.**");
+    QueryPlan queryPlan =
+        (QueryPlan) processor.parseSQLToPhysicalPlan("select * from root.multi*.**");
     QueryDataSet dataSet = executor.processQuery(queryPlan, EnvironmentUtils.TEST_QUERY_CONTEXT);
     Assert.assertEquals(160, dataSet.getPaths().size());
     while (dataSet.hasNext()) {