> For the complete documentation index, see [llms.txt](https://documentation.alluxio.io/ee-ai-cn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://documentation.alluxio.io/ee-ai-cn/administration/audit-access-logs/audit-log.md).

# 审计日志

Alluxio 审计日志是安全与合规的关键组件，它提供了系统内执行操作的详细、结构化记录。它可以帮助您监控敏感数据访问、跟踪管理命令并满足法规要求。

审计日志以结构化的 **JSON** 格式生成，便于解析并与 Splunk 或 ELK Stack 等分析工具集成。日志记录涵盖两大类操作：

1. **管理操作**：用于管理任务的 API 请求，例如加载数据或管理挂载点。
2. **数据访问**：通过各种接口（包括 **S3、HDFS、FUSE 和 Python SDK**）执行的读写操作。

本指南介绍了如何为这两类操作启用和配置审计日志记录。

## 启用和配置审计日志记录

审计日志记录是分别为管理操作和数据访问接口配置的。

### 步骤 1：启用管理操作审计日志记录

此配置记录所有管理 API 请求。此功能**默认启用**。

审计日志存储在 Gateway 主机的 `/mnt/alluxio/logs/gateway/audit/` 目录中，并存储在 Gateway pod 的 `/opt/alluxio/logs/audit/` 目录中。要修改日志位置或其他设置，您可以更新 `alluxio-cluster.yaml` 文件中的 `gateway` 部分：

```yaml
spec:
  gateway:
    enabled: true
    log:
      level: info
      type: hostPath
      hostPath: /mnt/alluxio/logs/gateway
      size: 1Gi
      storageClass: standard
    auditLog:
      enabled: true
```

### 步骤 2：启用数据访问审计日志记录

此配置记录来自使用 S3、HDFS 和 FUSE 接口的客户端的数据访问操作。

要启用它，请将以下属性添加到您的 `alluxio-cluster.yaml` 文件中：

```yaml
spec:
  properties:
    alluxio.audit.logging.enabled: "true"
    alluxio.audit.logging.poll.interval: "5s"
```

* 默认情况下，数据访问审计日志存储在 `${audit.logs.dir}` 目录中。您可以通过修改 `conf/log4j2.xml` 文件中的 `*_AUDIT_LOG` appender 来自定义此位置。
* 对于 3.3.3 及以后的 operator 版本，所需的审计日志 appender 默认包含在 `log4j2.xml` 中。对于更早的版本，您必须手动将日志记录器配置添加到 `alluxio-configmap` 的 `log4j2.xml` 部分。

| 属性                                    | 描述                           | 默认值     |
| ------------------------------------- | ---------------------------- | ------- |
| `alluxio.audit.logging.enabled`       | 设置为 `true` 以启用数据访问操作的审计日志记录。 | `false` |
| `alluxio.audit.logging.poll.interval` | 将审计日志写入文件的间隔。                | `5s`    |

## 通过 REST API 和 CLI 进行动态配置

审计日志和访问日志均支持通过 REST API 或 User CLI 进行动态配置。修改在集群范围内生效，并在集群重启后保持不变。

{% hint style="info" %}
如需启用审计日志或访问日志，请先与售后支持讨论日志保留策略。
{% endhint %}

### REST API

使用 `LogConfigEntity` 同时控制两种日志。

创建 `LogConfigEntity.json` 文件：

```json
{
  "accessLogEnabled": false,
  "auditLogEnabled": false,
  "bfRefreshInterval": "6000s",
  "logPollInterval": "5s"
}
```

| 字段                  | 描述                              | 默认值     |
| ------------------- | ------------------------------- | ------- |
| `accessLogEnabled`  | 是否启用访问日志。                       | `false` |
| `auditLogEnabled`   | 是否启用审计日志。                       | `false` |
| `bfRefreshInterval` | 访问日志的布隆过滤器刷新周期。推荐设置为 100 分钟。    | —       |
| `logPollInterval`   | 访问日志和审计日志从内存写入磁盘的时间间隔。推荐设置为 5s。 | —       |

应用配置：

```shell
jq -n --rawfile conf ./LogConfigEntity.json '{key: "LogConfigEntity", conf: $conf}' | curl -sS 'http://<coordinator_host>:19999/api/v1/conf' -X PUT -H 'Content-Type: application/json' --data @-
```

验证配置：

```shell
curl -sS 'http://<coordinator_host>:19999/api/v1/conf?key=LogConfigEntity' | jq
```

### User CLI

`alluxio log` 命令组用于管理审计日志和访问日志的动态配置。

#### log access

管理访问日志的开启状态以及布隆过滤器的刷新间隔。

```shell
bin/alluxio log access [--enable <true|false>] [--bfRefreshInterval <duration>]
```

* `--enable`：启用或禁用访问日志。可选值为 `true` 或 `false`。
* `--bfRefreshInterval`：布隆过滤器的刷新时间间隔。支持带单位的时间格式，例如 `30s`、`10min`、`1h`。推荐设置为 100 分钟。

示例：

```shell
# 启用访问日志，并设置刷新间隔为 30 分钟
bin/alluxio log access --enable=true --bfRefreshInterval=30min

# 禁用访问日志
bin/alluxio log access --enable=false
```

#### log audit

管理审计日志的开启状态。

```shell
bin/alluxio log audit [--enable <true|false>]
```

* `--enable`：启用或禁用审计日志。可选值为 `true` 或 `false`。

示例：

```shell
# 启用审计日志
bin/alluxio log audit --enable=true

# 禁用审计日志
bin/alluxio log audit --enable=false
```

#### log status

展示当前集群中审计日志和访问日志的所有相关配置状态。该命令不接受任何参数。

```shell
bin/alluxio log status
```

示例输出：

```console
Access Log Enabled: true
Audit Log Enabled: false
Bloom Filter Refresh Interval: 3600000ms
Log Poll Interval: 5000ms
```

{% hint style="info" %}

* **持久化**：通过 `log access` 和 `log audit` 所做的修改在集群重启后依然有效。
* **生效范围**：配置修改后，相关进程会通过动态配置机制感知并应用新设置。
  {% endhint %}

## 理解审计日志格式

每个审计日志条目都是一个结构化的 JSON 对象，具有一致的模式，便于处理和分析。

### 审计日志模式

| 字段               | 类型            | 描述                                                                                            |
| ---------------- | ------------- | --------------------------------------------------------------------------------------------- |
| `timestamp`      | 字符串           | ISO 8601 格式的操作时间戳，带时区（例如，`2025-08-02T09:12:30.123456+08:00[Asia/Singapore]`）。                 |
| `user`           | JSON 对象       | 有关执行操作的用户的信息，包含 `name`（用户标识符）、`group`（组列表）和 `role`（角色列表）。                                     |
| `interface`      | 字符串           | 使用的访问接口。可能的值：`S3`、`FUSE`、`HADOOP_FS` 和 `GATEWAY`。`GATEWAY` 代表管理操作。                            |
| `operation`      | 字符串 / JSON 对象 | 具体的操作或 API 名称。对于数据访问接口，这是一个字符串（例如，`GetObject`）。对于 Gateway，这是一个包含 `method` 和 `path` 的 JSON 对象。 |
| `resource`       | JSON 对象 / 字符串 | 涉及的资源。内容因接口而异。例如，S3 操作包括 `bucket` 和 `object`，而 HDFS 操作包括 `path`。                              |
| `status`         | 字符串           | 操作的结果，例如 `SUCCESS`、`FAILURE`、`FORBIDDEN`、`ALLOWED` 或 `UNAUTHORIZED`。                          |
| `errorMessage`   | 字符串           | 如果操作失败，此字段包含错误消息。                                                                             |
| `clientIp`       | 字符串           | 发起请求的客户端的 IP 地址。                                                                              |
| `clientPort`     | 字符串           | 客户端连接的源端口号。                                                                                   |
| `reqContentLen`  | 字符串           | 请求的内容长度（如果适用）。                                                                                |
| `respContentLen` | 字符串           | 响应的内容长度（如果适用）。                                                                                |
| `requestId`      | 字符串           | 请求的唯一标识符，主要由 Gateway 使用。                                                                      |

### 日志示例

#### 示例 1：管理操作

用户通过 API 列出所有挂载点。

```json
{
    "timestamp": "2025-07-29T15:21:21.846416+08:00",
    "user": {
        "name": "super-user",
        "group": ["Storage"],
        "role": ["SuperAdmin"]
    },
    "interface": "GATEWAY",
    "operation": {
        "method": "GET",
        "path": "/api/v1/mount"
    },
    "resource": {
        "parameters": {},
        "body": {}
    },
    "status": "SUCCESS",
    "errorMessage": "",
    "clientIp": "192.168.124.21",
    "requestId": "b3c9efe4-35aa-42d0-8690-ab044126452c"
}
```

#### 示例 2：S3 API 数据访问

用户使用 S3 客户端获取一个对象。

```json
{
    "timestamp": "2025-07-24T14:45:59.911358+08:00[Asia/Shanghai]",
    "user": {
        "name": "search-admin@alluxio.com",
        "group": ["Search"],
        "role": ["GroupAdmin"]
    },
    "interface": "S3",
    "operation": "GetObject",
    "resource": {
        "bucket": "testbucket",
        "object": "hosts3",
        "sourcePath": null,
        "prefix": null,
        "path": null
    },
    "status": "SUCCESS",
    "errorMessage": null,
    "clientIp": "127.0.0.1",
    "clientPort": "60304",
    "reqContentLen": "None",
    "respContentLen": "268",
    "requestId": null
}
```

#### 示例 3：HDFS API 数据访问

用户使用 Hadoop 客户端打开一个文件。

```json
{
    "timestamp": "2025-07-24T16:37:28.71468+08:00[Asia/Shanghai]",
    "user": {
        "name": "search-admin@alluxio.com",
        "group": ["Search"],
        "role": ["GroupAdmin"]
    },
    "interface": "HADOOP_FS",
    "operation": "HadoopFs.Open",
    "resource": {
        "path": "/testbucket/hosts3"
    },
    "status": "ALLOWED",
    "clientIp": "192.168.1.104"
}
```

#### 示例 4：FUSE 数据访问

匿名用户从 FUSE 挂载点读取文件（`cat testbucket/hosts`）。

```json
{
    "timestamp": "2025-07-24T14:48:14.566555+08:00[Asia/Shanghai]",
    "user": {
        "name": "anonymous",
        "group": null,
        "role": null
    },
    "interface": "FUSE",
    "operation": "Fuse.Open",
    "resource": {
        "path": "/testbucket/hosts"
    },
    "status": "SUCCESS",
    "errorMessage": null,
    "clientIp": null,
    "clientPort": null,
    "reqContentLen": null,
    "respContentLen": null,
    "requestId": null
}
{
    "timestamp": "2025-07-24T14:48:14.650128+08:00[Asia/Shanghai]",
    "user": {
        "name": "anonymous",
        "group": null,
        "role": null
    },
    "interface": "FUSE",
    "operation": "Fuse.Read",
    "resource": {
        "fd": 3,
        "path": "/testbucket/hosts"
    },
    "status": "SUCCESS",
    "errorMessage": null,
    "clientIp": null,
    "clientPort": null,
    "reqContentLen": null,
    "respContentLen": "268",
    "requestId": null
}
{
    "timestamp": "2025-07-24T14:48:14.650381+08:00[Asia/Shanghai]",
    "user": {
        "name": "anonymous",
        "group": null,
        "role": null
    },
    "interface": "FUSE",
    "operation": "Fuse.Release",
    "resource": {
        "path": "/testbucket/hosts"
    },
    "status": "SUCCESS",
    "errorMessage": null,
    "clientIp": null,
    "clientPort": null,
    "reqContentLen": null,
    "respContentLen": null,
    "requestId": null
}
```

#### 示例 5：Python SDK 数据访问

用户通过 Python SDK 删除文件。

```json
{
    "timestamp": "2025-07-24T15:42:59.002146+08:00[Asia/Shanghai]",
    "user": {
        "name": "anonymous",
        "group": null,
        "role": null
    },
    "interface": "HTTP",
    "operation": "HttpServer.Rm",
    "resource": {
        "path": null,
        "srcPath": null,
        "dstPath": null,
        "ufsFullPath": "/testbucket/test.txt"
    },
    "status": "SUCCESS",
    "errorMessage": null,
    "clientIp": "0:0:0:0:0:0:0:1",
    "clientPort": "48304",
    "reqContentLen": null,
    "respContentLen": "38",
    "requestId": null
}
```

## 附录：按接口审计的操作

### 管理操作

所有管理 API 调用都会被审计。

### S3 API

所有 S3 API 调用都会被审计。对于像 `DeleteObjects` 这样的批量操作，会为每个子操作生成一个单独的日志条目。

### Hadoop 文件系统 (HDFS) API

以下 Hadoop 文件系统 API 操作会被审计：

* `HadoopFs.Authenticate`
* `HadoopFs.Create`
* `HadoopFs.Append`
* `HadoopFs.Delete`
* `HadoopFs.GetFileStatus`
* `HadoopFs.GetFileBlockLocations`
* `HadoopFs.ListStatus`
* `HadoopFs.Mkdirs`
* `HadoopFs.Open`
* `HadoopFs.Rename`
* `HadoopFs.SetOwner`
* `HadoopFs.SetPermission`

**关于 `clientIp` 的说明**：对于 Hadoop 文件系统接口，会获取一个 IPv4 地址。如果机器有多个网卡，可能无法确定哪个网卡用于该操作。建议依赖 `user` 来识别操作者。

### FUSE API

以下 FUSE 操作会被审计：

* `Fuse.Create`
* `Fuse.Open`
* `Fuse.Opendir`
* `Fuse.Release`
* `Fuse.Mkdir`
* `Fuse.Rmdir`
* `Fuse.Unlink`
* `Fuse.Rename`
* `Fuse.Chown`
* `Fuse.Chmod`
* `Fuse.Truncate`
* `Fuse.Symlink`
* `Fuse.Link`

**关于 FUSE 日志记录的说明**：典型的文件访问序列包括 `Fuse.Open`，然后是 `read` 或 `write` 操作，最后是 `Fuse.Release`。为了避免生成过多的日志，单个的 `read` 和 `write` 调用不会被审计。相反，关于是否发生读或写的信息会作为 `Fuse.Release` 事件的一部分被记录下来。

### HTTP Server（由 Python SDK 使用）

以下 HTTP server 操作会被审计：

* `HttpServer.GetFile`
* `HttpServer.WriteFile`
* `HttpServer.FilterParquetFile`
* `HttpServer.FilterParquetFileRaw`
* `HttpServer.Mkdir`
* `HttpServer.Touch`
* `HttpServer.Mv`
* `HttpServer.Rm`
* `HttpServer.Copy`
* `HttpServer.ListFiles`
* `HttpServer.GetFileStatus`
* `HttpServer.Load`
* `HttpServer.Tail`
* `HttpServer.Head`
* `HttpServer.GetRange`

像 `HealthCheck`、`GetCache`、`PostCache` 这样的操作不会被审计。
