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 4acc508d27 [To rel/0.13] [IOTDB-3662] add audit log. (#7717)
4acc508d27 is described below

commit 4acc508d27fb13ee141d3c5f7fdfde898f36e5f0
Author: Zhijia Cao <[email protected]>
AuthorDate: Fri Oct 28 18:35:04 2022 +0800

    [To rel/0.13] [IOTDB-3662] add audit log. (#7717)
    
    Co-authored-by: Haonan <[email protected]>
---
 .../org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4   |  1 +
 .../server/basic/ClusterServiceProvider.java       |  5 ++
 .../resources/conf/iotdb-engine.properties         | 10 ++-
 .../java/org/apache/iotdb/db/conf/IoTDBConfig.java | 23 ++++++
 .../org/apache/iotdb/db/conf/IoTDBDescriptor.java  |  7 ++
 .../iotdb/db/service/basic/ServiceProvider.java    |  3 +
 .../service/basic/StandaloneServiceProvider.java   |  6 +-
 .../db/service/thrift/impl/TSServiceImpl.java      |  3 +-
 .../org/apache/iotdb/db/utils/AuditLogUtils.java   | 83 ++++++++++++++++++++++
 9 files changed, 138 insertions(+), 3 deletions(-)

diff --git a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 
b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
index 7996345033..e4905bb8fd 100644
--- a/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
+++ b/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
@@ -745,6 +745,7 @@ nodeName
     | wildcard? INTEGER_LITERAL wildcard?
     | QUTOED_ID_IN_NODE_NAME
     | STRING_LITERAL
+    | SYSTEM
     ;
 
 nodeNameWithoutWildcard
diff --git 
a/cluster/src/main/java/org/apache/iotdb/cluster/server/basic/ClusterServiceProvider.java
 
b/cluster/src/main/java/org/apache/iotdb/cluster/server/basic/ClusterServiceProvider.java
index be515775f4..37d579e21b 100644
--- 
a/cluster/src/main/java/org/apache/iotdb/cluster/server/basic/ClusterServiceProvider.java
+++ 
b/cluster/src/main/java/org/apache/iotdb/cluster/server/basic/ClusterServiceProvider.java
@@ -32,6 +32,7 @@ import org.apache.iotdb.db.qp.physical.sys.FlushPlan;
 import org.apache.iotdb.db.qp.physical.sys.SetSystemModePlan;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.service.basic.ServiceProvider;
+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.TSStatus;
@@ -89,6 +90,10 @@ public class ClusterServiceProvider extends ServiceProvider {
 
   @Override
   public boolean executeNonQuery(PhysicalPlan plan) {
+    AuditLogUtils.writeAuditLog(
+        plan.getOperatorName(),
+        String.format(
+            "measurements size:%s", plan.getPaths() == null ? 0 : 
plan.getPaths().size()));
     TSStatus tsStatus = executeNonQueryPlan(plan);
     return tsStatus.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode();
   }
diff --git a/server/src/assembly/resources/conf/iotdb-engine.properties 
b/server/src/assembly/resources/conf/iotdb-engine.properties
index f8267b9c38..6e44b96b59 100644
--- a/server/src/assembly/resources/conf/iotdb-engine.properties
+++ b/server/src/assembly/resources/conf/iotdb-engine.properties
@@ -949,4 +949,12 @@ timestamp_precision=ms
 ### Group By Fill Configuration
 ####################
 # Datatype: float
-# group_by_fill_cache_size_in_mb=1.0
\ No newline at end of file
+# 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
+# Datatype: String
+# audit_log_storage=NONE
+
+# determines whether audit logs record IoTDB write operation
+# Datatype: boolean
+# enable_auditLog_write=false
\ No newline at end of file
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 c305c49cf4..50d9486a3e 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
@@ -27,6 +27,7 @@ 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;
@@ -873,6 +874,12 @@ 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;
+
+  // determines whether audit logs record IoTDB write operation
+  private boolean enableAuditLogWrite = false;
+
   // customizedProperties, this should be empty by default.
   private Properties customizedProperties = new Properties();
 
@@ -2806,4 +2813,20 @@ public class IoTDBConfig {
   public void setPatternMatchingThreshold(int patternMatchingThreshold) {
     this.patternMatchingThreshold = patternMatchingThreshold;
   }
+
+  public String getAuditLogStorage() {
+    return auditLogStorage;
+  }
+
+  public void setAuditLogStorage(String auditLogStorage) {
+    this.auditLogStorage = auditLogStorage;
+  }
+
+  public boolean isEnableAuditLogWrite() {
+    return enableAuditLogWrite;
+  }
+
+  public void setEnableAuditLogWrite(boolean enableAuditLogWrite) {
+    this.enableAuditLogWrite = enableAuditLogWrite;
+  }
 }
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 3ed1f5e726..d12c871780 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
@@ -891,6 +891,13 @@ public class IoTDBDescriptor {
             properties.getProperty(
                 "schema_query_fetch_size", 
String.valueOf(conf.getSchemaQueryFetchSize()))));
 
+    conf.setAuditLogStorage(properties.getProperty("audit_log_storage", 
conf.getAuditLogStorage()));
+
+    conf.setEnableAuditLogWrite(
+        Boolean.parseBoolean(
+            properties.getProperty(
+                "enable_auditLog_write", 
String.valueOf(conf.isEnableAuditLogWrite()))));
+
     // At the same time, set TSFileConfig
     TSFileDescriptor.getInstance()
         .getConfig()
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 3b37af1ae7..630e8d3dad 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
@@ -43,6 +43,7 @@ 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;
@@ -219,6 +220,7 @@ public abstract class ServiceProvider {
       // TODO we should close this connection ASAP, otherwise there will be 
DDoS.
     }
     SessionTimeoutManager.getInstance().register(session);
+    AuditLogUtils.writeAuditLog(AuditLogUtils.TYPE_LOGIN, "user login");
     return openSessionResp.sessionId(session == null ? -1 : session.getId());
   }
 
@@ -235,6 +237,7 @@ public abstract class ServiceProvider {
 
   public boolean closeSession(IClientSession session) {
     AUDIT_LOGGER.info("Session-{} is closing", session);
+    AuditLogUtils.writeAuditLog(AuditLogUtils.TYPE_LOGOUT, "user logout");
     return SessionTimeoutManager.getInstance().unregister(session);
   }
 
diff --git 
a/server/src/main/java/org/apache/iotdb/db/service/basic/StandaloneServiceProvider.java
 
b/server/src/main/java/org/apache/iotdb/db/service/basic/StandaloneServiceProvider.java
index a931ffe27b..8ad1f16e60 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/service/basic/StandaloneServiceProvider.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/service/basic/StandaloneServiceProvider.java
@@ -28,6 +28,7 @@ import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.sys.FlushPlan;
 import org.apache.iotdb.db.qp.physical.sys.SetSystemModePlan;
 import org.apache.iotdb.db.query.context.QueryContext;
+import org.apache.iotdb.db.utils.AuditLogUtils;
 
 public class StandaloneServiceProvider extends ServiceProvider {
 
@@ -50,7 +51,10 @@ public class StandaloneServiceProvider extends 
ServiceProvider {
         && IoTDBDescriptor.getInstance().getConfig().isReadOnly()) {
       throw new StorageEngineReadonlyException();
     }
-
+    AuditLogUtils.writeAuditLog(
+        plan.getOperatorName(),
+        String.format(
+            "measurements size:%s", plan.getPaths() == null ? 0 : 
plan.getPaths().size()));
     return executor.processNonQuery(plan);
   }
 }
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 eefc352bc3..3f98f7a06d 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
@@ -78,6 +78,7 @@ 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;
@@ -779,7 +780,7 @@ public class TSServiceImpl implements TSIService.Iface {
     if (status != null) {
       return new TSExecuteStatementResp(status);
     }
-
+    AuditLogUtils.writeAuditLog(AuditLogUtils.TYPE_QUERY, req.getStatement());
     QueryTask queryTask =
         new QueryTask(
             physicalPlan,
diff --git a/server/src/main/java/org/apache/iotdb/db/utils/AuditLogUtils.java 
b/server/src/main/java/org/apache/iotdb/db/utils/AuditLogUtils.java
new file mode 100644
index 0000000000..41786e9303
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/utils/AuditLogUtils.java
@@ -0,0 +1,83 @@
+/*
+ * 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.utils;
+
+import org.apache.iotdb.db.conf.IoTDBConfig;
+import org.apache.iotdb.db.conf.IoTDBConstant;
+import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.exception.metadata.IllegalPathException;
+import org.apache.iotdb.db.exception.query.QueryProcessException;
+import org.apache.iotdb.db.metadata.path.PartialPath;
+import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
+import org.apache.iotdb.db.qp.utils.DateTimeUtils;
+import org.apache.iotdb.db.query.control.SessionManager;
+import org.apache.iotdb.db.query.control.clientsession.IClientSession;
+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);
+  private static final Logger AUDIT_LOGGER =
+      LoggerFactory.getLogger(IoTDBConstant.AUDIT_LOGGER_NAME);
+
+  public static final String LOG = "log";
+  public static final String TYPE = "type";
+  public static final String AUDIT_LOG_DEVICE = "root.system.audit.'%s'";
+  public static final String TYPE_QUERY = "QUERY";
+  public static final String TYPE_LOGIN = "LOGIN";
+  public static final String TYPE_LOGOUT = "LOGOUT";
+  public static final String TYPE_INSERT = "INSERT";
+  public static final String TYPE_DELETE = "DELETE";
+  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 type, String log) {
+    IoTDBConfig config = IoTDBDescriptor.getInstance().getConfig();
+    String auditLogStorage = config.getAuditLogStorage();
+    IClientSession currSession = SessionManager.getInstance().getCurrSession();
+    if (currSession == null) {
+      return;
+    }
+    String username = currSession.getUsername();
+    if (LOG_LEVEL_IOTDB.equals(auditLogStorage)) {
+      try {
+        InsertRowPlan insertRowPlan =
+            new InsertRowPlan(
+                new PartialPath(String.format(AUDIT_LOG_DEVICE, username)),
+                DateTimeUtils.currentTime(),
+                new String[] {TYPE, LOG},
+                new String[] {type, log});
+        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 (type.contains(TYPE_INSERT)) {
+        if (config.isEnableAuditLogWrite()) {
+          AUDIT_LOGGER.debug("user:{},type:{},action:{}", username, type, log);
+        }
+      } else {
+        AUDIT_LOGGER.info("user:{},type:{},action:{}", username, type, log);
+      }
+    }
+  }
+}

Reply via email to