

# 将 Amazon ECS 日志发送到 AWS 服务或 AWS Partner
<a name="using_firelens"></a>

您可以使用适用于 Amazon ECS 的 FireLens 来使用任务定义参数将日志路由到 AWS 服务或 AWS Partner Network（APN）目标来进行日志存储和分析。AWS Partner Network 是一个由合作伙伴组成的全球社区，它利用计划、专业知识和资源来构建、营销和销售客户产品。有关更多信息，请参阅 [AWS Partner](https://aws.amazon.com/partners/work-with-partners/)。FireLens 与 [Fluentd](https://www.fluentd.org/) 和 [Fluent Bit](https://fluentbit.io/) 结合使用。我们提供 AWS for Fluent Bit 映像，您也可以使用自己的 Fluentd 或 Fluent Bit 映像。

默认情况下，Amazon ECS 会配置容器依赖关系，以便 Firelens 容器先启动，任何使用它的容器随后启动。Firelens 容器也会在所有使用它的容器停止后才停止。

要使用此功能，您必须为您的任务创建一个 IAM 角色，该角色提供使用任务需要的任何 AWS 服务所需的权限。例如，如果容器将日志路由到 Firehose，则任务需要调用 `firehose:PutRecordBatch` API 的权限。有关更多信息，请参阅 *IAM用户指南*中的[添加和删除 IAM 标识权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html)。

在以下条件下，您的任务也可能需要 Amazon ECS 任务执行角色。有关更多信息，请参阅 [Amazon ECS 任务执行 IAM 角色](task_execution_IAM_role.md)。
+ 如果在 Fargate 上托管您的任务，并且您正在从 Amazon ECR 提取容器映像或 AWS Secrets Manager 在日志配置中引用敏感数据，那么您必须包含任务执行 IAM 角色。
+ 当您使用托管于 Amazon S3 中的自定义配置文件时，任务执行 IAM 角色必须包含 `s3:GetObject` 权限。

使用 FireLens for Amazon ECS 时考虑以下事项：
+ 建议您在日志容器名称中添加 `my_service_`，以便可以在控制台中轻松区分容器名称。
+ 默认情况下，Amazon ECS 在应用程序容器和 FireLens 容器之间添加启动容器顺序依赖关系。当您在应用程序容器和 FireLens 容器之间指定容器顺序时，默认的启动容器顺序将被覆盖。
+ 支持将适用于 Amazon ECS 的 FireLens 用于托管在 Linux 上的 AWS Fargate 和 Amazon EC2 的任务。Windows 容器不支持 FireLens。

  有关如何为 Windows 容器配置集中日志记录的信息，请参阅[使用 Fluent Bit 在 Amazon ECS 上对 Windows 容器进行集中日志记录](https://aws.amazon.com/blogs/containers/centralized-logging-for-windows-containers-on-amazon-ecs-using-fluent-bit/)。
+ 您可以使用 CloudFormation 模板为 Amazon ECS 配置 FireLens。有关更多信息，请参阅《AWS CloudFormation 用户指南》**中的 [AWS::ECS::TaskDefinition FirelensConfiguration](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-firelensconfiguration.html)
+ FireLens 在端口 `24224` 上侦听，因此为了确保从任务外部无法访问 FireLens 日志路由器，不得允许任务使用的安全组中端口 `24224` 上的入站流量。对于使用 `awsvpc` 网络模式的任务，这是与任务关联的安全组。对于使用 `host` 网络模式的任务，它是与托管任务的 Amazon EC2 实例关联的安全组。对于使用 `bridge` 网络模式的任务，请勿创建任何使用端口 `24224` 的端口映射。
+ 对于使用 `bridge` 网络模式的任务，具有 FirelLens 配置的容器必须在依赖它的任何应用程序容器启动之前启动。要控制容器的启动顺序，请在任务定义中使用依赖条件。有关更多信息，请参阅 [容器依赖项](task_definition_parameters.md#container_definition_dependson)。
**注意**  
如果您将容器定义中的依赖条件参数与 FirelLens 配置结合使用，请确保每个容器均具有 `START` 或 `HEALTHY` 条件要求。
+ 默认情况下，FireLens 将集群和任务定义名称以及集群的 Amazon 资源名称（ARN）作为元数据键添加到您的 stdout/stderr 容器日志中。以下为元数据格式的示例。

  ```
  "ecs_cluster": "cluster-name",
  "ecs_task_arn": "arn:aws:ecs:region:111122223333:task/cluster-name/f2ad7dba413f45ddb4EXAMPLE",
  "ecs_task_definition": "task-def-name:revision",
  ```

  如果您不希望日志中出现元数据，请在任务定义的 `firelensConfiguration` 部分中将 `enable-ecs-log-metadata` 设置为 `false`。

  ```
  "firelensConfiguration":{
     "type":"fluentbit",
     "options":{
        "enable-ecs-log-metadata":"false",
        "config-file-type":"file",
        "config-file-value":"/extra.conf"
  }
  ```

您可以将 FireLens 容器配置为以非根用户身份运行。请考虑以下事项：
+  要将 FireLens 容器配置为以非根用户身份运行，您必须使用以下其中一种格式指定用户：
  + `uid`
  + `uid:gid`
  + `uid:group`

  有关在容器定义中指定用户的更多信息，请参阅《Amazon Elastic Container Service API 参考》**中的 [ContainerDefinition](https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_ContainerDefinition.html)。

  FireLens 容器通过 UNIX 套接字接收应用程序日志。Amazon ECS 代理使用 `uid` 将套接字目录的所有权分配给 FireLens 容器。
+ 在 Amazon ECS 代理版本 `1.96.0` 及更高版本以及经 Amazon ECS 优化的 AMI 版本 `v20250716` 及更高版本上，支持将 FireLens 容器配置为以非根用户身份运行。
+ 当您为 FireLens 容器指定用户时，`uid` 必须是唯一的，并且不得用于属于任务中其他容器或容器实例的其他进程。

有关如何将多个配置文件用于 Amazon ECS 的信息（包括您托管的文件或 Amazon S3 中的文件），请参阅 [Init process for Fluent Bit on ECS, multi-config support](https://github.com/aws/aws-for-fluent-bit/tree/mainline/use_cases/init-process-for-fluent-bit)。

有关示例配置的信息，请参阅[Amazon ECS 任务定义示例：将日志路由到 FireLens](firelens-taskdef.md)。

有关配置日志以实现高吞吐量的更多信息，请参阅[配置 Amazon ECS 日志，以实现高吞吐量](firelens-docker-buffer-limit.md)。

# 配置 Amazon ECS 日志，以实现高吞吐量
<a name="firelens-docker-buffer-limit"></a>

对于高日志吞吐量场景，我们建议将 `awsfirelens` 日志驱动程序与 FireLens 和 Fluent Bit 一起使用。Fluent Bit 是一款轻量级日志处理器，资源利用效率高，可以处理数百万条日志记录。但是，要大规模实现最佳性能，需要调整其配置。

本部分介绍高级 Fluent Bit 优化技术，用于处理高日志吞吐量，同时保持系统稳定性并确保不丢失数据。

有关如何使用 FireLens 自定义配置文件的信息，请参阅 [使用自定义配置文件](firelens-taskdef.md#firelens-taskdef-customconfig)。有关其他示例，请参阅 GitHub 上的 [Amazon ECS FireLens 示例](https://github.com/aws-samples/amazon-ecs-firelens-examples)。

**注意**  
本部分中的某些配置选项（例如 `workers` 和 `threaded`）需要适用于 Fluent Bit 版本 3 或更高版本的 AWS。有关可用版本的信息，请参阅[适用于 Fluent Bit 的 AWS 版本](https://github.com/aws/aws-for-fluent-bit/releases)。

## 了解分块
<a name="firelens-understanding-chunks"></a>

Fluent Bit 以称为*分块*的单元处理数据。当 INPUT 插件收到数据时，引擎会创建一个分块，该分块在发送到 OUTPUT 目标之前存储在内存或文件系统中。

缓冲行为取决于 INPUT 部分中的 `storage.type` 设置。默认情况下，Fluent Bit 使用内存缓冲。对于高吞吐量或生产场景，文件系统缓冲可提供更好的韧性。

有关更多信息，请参阅 Fluent Bit 文档中的[分块](https://docs.fluentbit.io/manual/administration/buffering-and-storage#chunks)和 AWS for Fluent Bit 示例存储库中的[什么是分块？](https://github.com/aws-samples/amazon-ecs-firelens-examples/tree/mainline/examples/fluent-bit/oomkill-prevention#what-is-a-chunk)。

## 内存缓冲（默认）
<a name="firelens-memory-buffering"></a>

默认情况下，Fluent Bit 使用内存缓冲（`storage.type memory`）。您可以使用 `Mem_Buf_Limit` 参数限制每个 INPUT 插件的内存使用量。

以下示例显示了一个内存缓冲的输入配置：

```
[INPUT]
    Name          tcp
    Tag           ApplicationLogs
    Port          5170
    storage.type  memory
    Mem_Buf_Limit 5MB
```

**重要**  
当一个插件超出 `Mem_Buf_Limit` 时，Fluent Bit 将暂停输入并且会丢失新记录。这可能会导致背压并减慢应用程序的速度。Fluent Bit 日志中会出现以下警告：  

```
[input] tcp.1 paused (mem buf overlimit)
```

内存缓冲适用于日志吞吐量低至中等的简单应用场景。对于需要高吞吐量或用于生产环境且存在数据丢失风险的情况，应采用文件系统缓冲机制。

有关更多信息，请参阅 Fluent Bit 文档中的[缓冲和内存](https://docs.fluentbit.io/manual/administration/buffering-and-storage#buffering-and-memory)以及 AWS for Fluent Bit 示例存储库中的[仅限内存缓冲](https://github.com/aws-samples/amazon-ecs-firelens-examples/tree/mainline/examples/fluent-bit/oomkill-prevention#case-1-memory-buffering-only-default-or-storagetype-memory)。

## 文件系统缓冲
<a name="firelens-filesystem-buffering"></a>

对于高吞吐量场景，我们建议使用文件系统缓冲。有关 Fluent Bit 如何管理缓冲和存储的更多信息，请参阅 Fluent Bit 文档中的[缓冲和存储](https://docs.fluentbit.io/manual/administration/buffering-and-storage)。

文件系统缓冲提供以下优势：
+ **更大的缓冲容量** – 磁盘空间通常比内存更充足。
+ **持久性** – 缓冲的数据在 Fluent Bit 重新启动后仍能存活下来。
+ **正常降级** – 在输出失败期间，数据会积聚在磁盘上，而不是导致内存耗尽。

要启用文件系统缓冲，请提供自定义 Fluent Bit 配置文件。以下示例展示了建议的配置：

```
[SERVICE]
    # Flush logs every 1 second
    Flush 1
    # Wait 120 seconds during shutdown to flush remaining logs
    Grace 120
    # Directory for filesystem buffering
    storage.path             /var/log/flb-storage/
    # Limit chunks stored 'up' in memory (reduce for memory-constrained environments)
    storage.max_chunks_up    32
    # Flush backlog chunks to destinations during shutdown (prevents log loss)
    storage.backlog.flush_on_shutdown On

[INPUT]
    Name forward
    unix_path /var/run/fluent.sock
    # Run input in separate thread to prevent blocking
    threaded true
    # Enable filesystem buffering for persistence
    storage.type filesystem

[OUTPUT]
    Name cloudwatch_logs
    Match *
    region us-west-2
    log_group_name /aws/ecs/my-app
    log_stream_name $(ecs_task_id)
    # Use multiple workers for parallel processing
    workers 2
    # Retry failed flushes up to 15 times
    retry_limit 15
    # Maximum disk space for buffered data for this output
    storage.total_limit_size 10G
```

关键配置参数：

`storage.path`  
Fluent Bit 在磁盘上存储缓冲块的目录。

`storage.backlog.flush_on_shutdown`  
启用后，Fluent Bit 会尝试在停机期间将所有积压文件系统块刷新到目标。这有助于确保在 Fluent Bit 停止之前传输数据，但可能会增加停机时间。

`storage.max_chunks_up`  
保留在内存中的块的数量。默认值为 128 个块，这会消耗 500 MB 以上的内存，因为每个块最多可以使用 4-5 MB 的内存。在内存受限的环境中，请降低此值。例如，如果您有 50 MB 可于缓冲，请将其设置为 8-10 个块。

`storage.type filesystem`  
为输入插件启用文件系统存储。尽管名称如此，但 Fluent Bit 会使用 `mmap` 将块映射到内存和磁盘，从而在不牺牲性能的情况下提供持久性。

`storage.total_limit_size`  
特定 OUTPUT 插件的缓冲数据的最大磁盘空间。当达到此限制时，该输出的最旧记录将被删除。有关大小的更多信息，请参阅 [了解 `storage.total_limit_size`](#firelens-storage-sizing)。

`threaded true`  
在自己的线程中运行输入，与 Fluent Bit 的主事件循环分开。这样可以防止慢速输入阻塞整个管道。

有关更多信息，请参阅 Fluent Bit 文档中的[文件系统缓冲](https://docs.fluentbit.io/manual/administration/buffering-and-storage#filesystem-buffering)以及 AWS for Fluent Bit 示例存储库中的[文件系统和内存缓冲](https://github.com/aws-samples/amazon-ecs-firelens-examples/tree/mainline/examples/fluent-bit/oomkill-prevention#case-2-filesystem-and-memory-buffering-storagetype-filesystem)。

## 了解 `storage.total_limit_size`
<a name="firelens-storage-sizing"></a>

每个 OUTPUT 插件上的 `storage.total_limit_size` 参数控制该输出的缓冲数据的最大磁盘空间。当达到此限制时，该输出的最旧记录将被删除以为新数据腾出空间。当磁盘空间完全耗尽时，Fluent Bit 无法将记录加入队列，这些记录会丢失。

根据您的日志速率和所需的恢复窗口，使用以下公式计算适当的 `storage.total_limit_size`：

```
If log rate is in KB/s, convert to MB/s first:
log_rate (MB/s) = log_rate (KB/s) / 1000

storage.total_limit_size (GB) = log_rate (MB/s) × duration (hours) × 3600 (seconds/hour) / 1000 (MB to GB)
```

下表显示了常见日志速率和恢复窗口的计算示例：


| 日志速率 | 1 小时 | 6 小时 | 12 小时 | 24 小时 | 
| --- | --- | --- | --- | --- | 
| 0.25 MB/s | 0.9 GB | 5.4 GB | 10.8GB | 21.6GB | 
| 0.5 MB/s | 1.8 GB | 10.8GB | 21.6GB | 43.2 GB | 
| 1 MB/s | 3.6 GB | 21.6GB | 43.2 GB | 86.4GB | 
| 5 MB/s | 18 GB | 108 GB | 216 GB | 432 GB | 
| 10 MB/s | 36 GB | 216 GB | 432 GB | 864 GB | 

要观测峰值吞吐量并选择合适的缓冲区大小，请使用 [measure-throughput FireLens 样本](https://github.com/aws-samples/amazon-ecs-firelens-examples/tree/mainline/examples/measure-throughput)。

使用公式、示例计算和基准测试来选择合适的 `storage.total_limit_size`，在故障发生时为尽力恢复提供足够的空间。

## Amazon ECS 任务存储要求
<a name="firelens-storage-task-requirements"></a>

将 OUTPUT 部分的所有 `storage.total_limit_size` 值相加，并为开销部分预留缓冲空间。这个总数决定了您在 Amazon ECS 任务定义中所需的存储空间大小。例如，3 个输出 × 每个 10GB = 30GB \$1 缓冲区 (5—10GB) = 总共需要 35—40GB。如果总存储量超过可用存储空间，则 Fluent Bit 可能无法将记录加入队列，这些记录会丢失。

提供以下存储选项：

绑定挂载（临时存储）  
+ 对于 AWS Fargate，默认值为 20GB 的临时存储空间（最大 200GB）。在任务定义中使用 `ephemeralStorage` 进行配置。有关更多信息，请参阅《AWS CloudFormation 用户指南》**中的 [EphemeralStorage](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-ephemeralstorage.html)。
+ 对于 EC2，使用 Amazon ECS 优化的 AMI（在操作系统和 Docker 之间共享）时，默认值为 30GB。通过更改根卷大小来增加。

Amazon EBS 卷  
+ 提供高度可用、持久、高性能的块存储。
+ 需要卷配置和任务定义中指向 `storage.path` 的 `mountPoint`（默认：`/var/log/flb-storage/`）。
+ 有关更多信息，请参阅 [在 Amazon ECS 任务定义中将卷配置推迟到启动时间](specify-ebs-config.md)。

Amazon EFS 卷  
+ 提供简单的可扩展文件存储。
+ 需要卷配置和任务定义中指向 `storage.path` 的 `mountPoint`（默认：`/var/log/flb-storage/`）。
+ 有关更多信息，请参阅 [在 Amazon ECS 任务定义中指定 Amazon EFS 文件系统](specify-efs-config.md)。

有关数据卷的更多信息，请参阅 [Amazon ECS 任务的存储选项](using_data_volumes.md)。

## 优化输出配置
<a name="firelens-output-optimization"></a>

网络问题、服务中断和目标节流可能会导致无法传送日志。正确的输出配置可确保韧性而不会丢失数据。

当输出刷新失败时，Fluent Bit 可以重试该操作。以下参数控制重试行为：

`retry_limit`  
在首次尝试后放弃记录之前的最大重试次数。默认 为 1。例如，`retry_limit 3` 表示总尝试次数 4 次（1 次初始尝试 \$1 3 次重试）。对于生产环境，我们建议设置为 15 或更高，这可以通过指数回退覆盖几分钟的中断时间。  
设置为 `no_limits` 或 `False` 以进行无限重试：  
+ 使用内存缓冲时，无限次重试会导致输入插件在达到内存限制时暂停。
+ 使用文件系统缓冲时，最旧的记录在到达 `storage.total_limit_size` 时会被丢弃。
用尽所有重试次数（1 次初始尝试 \$1 `retry_limit` 次重试）后，记录将被删除。带有 `auto_retry_requests true` 的 AWS 插件（默认）在 Fluent Bit 的重试机制之前提供了额外的重试层。有关更多信息，请参阅 Fluent Bit 文档中的[配置重试](https://docs.fluentbit.io/manual/administration/scheduling-and-retries#configure-retries)。  
例如，使用默认设置（`scheduler.base 5`、`scheduler.cap 2000`、`net.connect_timeout 10s`）的 `retry_limit 3` 可提供大约 70 秒的调度程序等待时间（10s \$1 20s \$1 40s）、40 秒的网络连接超时（4 次尝试 × 10s）以及 AWS 插件重试次数，总计大约 2-10 分钟，具体取决于网络条件和操作系统 TCP 超时。

`scheduler.base`  
两次重试之间的基本秒数（默认值：5）。我们建议 10 秒。

`scheduler.cap`  
两次重试之间的最大秒数（默认值：2000）。我们建议 60 秒。

两次重试之间的等待时间使用带有抖动的指数回退：

```
wait_time = random(base, min(base × 2^retry_number, cap))
```

例如，使用 `scheduler.base 10` 和 `scheduler.cap 60`：
+ 第一次重试：在 10–20 秒之间随机等待
+ 第二次重试：在 10–40 秒之间随机等待
+ 第三次重试及以后：在 10–60 秒之间随机等待（上限）

有关更多信息，请参阅 Fluent Bit 文档中的[配置重试等待时间](https://docs.fluentbit.io/manual/administration/scheduling-and-retries#configure-wait-time-for-retry)和[联网](https://docs.fluentbit.io/manual/administration/networking)。

`workers`  
并行输出处理的线程数。多个 Worker 允许并发刷新，从而提高处理多个块时的吞吐量。

`auto_retry_requests`  
一种特定于 AWS 插件的设置，在 Fluent Bit 的内置重试机制之前提供了额外的重试层。默认值为 `true`。启用后，AWS 输出插件会在内部重试失败的请求，然后请求才会被视为刷新失败并受 `retry_limit` 配置的约束。

`[SERVICE]` 部分中的 `Grace` 参数设置 Fluent Bit 在停机期间等待刷新缓冲数据的时间。`Grace` 期限必须与容器的 `stopTimeout` 相协调。确保 `stopTimeout` 超过 `Grace` 期限，进而允许 Fluent Bit 在接收 `SIGKILL` 之前完成刷新。例如，如果 `Grace` 为 120 秒，则将 `stopTimeout` 设置为 150 秒。

以下示例展示了针对高吞吐量场景的完整 Fluent Bit 配置，其中包含所有推荐设置：

```
[SERVICE]
    # Flush logs every 1 second
    Flush 1
    # Wait 120 seconds during shutdown to flush remaining logs
    Grace 120
    # Directory for filesystem buffering
    storage.path             /var/log/flb-storage/
    # Limit chunks stored 'up' in memory (reduce for memory-constrained environments)
    storage.max_chunks_up    32
    # Flush backlog chunks to destinations during shutdown (prevents log loss)
    storage.backlog.flush_on_shutdown On
    # Minimum seconds between retries
    scheduler.base           10
    # Maximum seconds between retries (exponential backoff cap)
    scheduler.cap            60

[INPUT]
    Name forward
    unix_path /var/run/fluent.sock
    # Run input in separate thread to prevent blocking
    threaded true
    # Enable filesystem buffering for persistence
    storage.type filesystem

[OUTPUT]
    Name cloudwatch_logs
    Match *
    region us-west-2
    log_group_name /aws/ecs/my-app
    log_stream_name $(ecs_task_id)
    # Use multiple workers for parallel processing
    workers 2
    # Retry failed flushes up to 15 times
    retry_limit 15
    # Maximum disk space for buffered data for this output
    storage.total_limit_size 10G
```

## 了解数据丢失情况
<a name="firelens-record-loss-scenarios"></a>

在长时间故障或输出目标出现问题的情况下，记录可能会丢失。本指南中的配置建议是尽力减少数据丢失，但不能保证长时间故障期间零丢失。了解这些场景有助于您配置 Fluent Bit 以最大限度地提高韧性。

记录可能会以两种方式丢失：当存储空间满时，最旧的记录会被删除；或者当系统无法再接收更多数据时，最新的记录会被拒绝。

### 最旧的记录已删除
<a name="firelens-record-loss-oldest-dropped"></a>

当重试尝试用尽或 `storage.total_limit_size` 已满且需要为新数据腾出空间时，最旧的缓冲记录将被丢弃。

超出了重试限制  
发生在 AWS 插件重试（如果 `auto_retry_requests true`）加上 1 次初始 Fluent Bit 尝试加上 `retry_limit` 重试次数之后。为了缓解风险，为每个 OUTPUT 插件设置 `retry_limit no_limits` 以进行无限次重试：  

```
[OUTPUT]
    Name                        cloudwatch_logs
    Match                       ApplicationLogs
    retry_limit                 no_limits
    auto_retry_requests         true
```
无限重试可防止由于重试耗尽而丢弃记录，但可能会导致 `storage.total_limit_size` 被填满。

已达到存储限制（文件系统缓冲）  
在输出目标不可用的时间超过您所配置的 `storage.total_limit_size` 可以缓冲的时间时，就会出现这种情况。例如，日志速率为 1 MB/s 的 10GB 缓冲区可提供大约 2.7 小时的缓冲时间。为了缓解风险，请增加每个 OUTPUT 插件的 `storage.total_limit_size` 并预置足够的 Amazon ECS 任务存储空间：  

```
[OUTPUT]
    Name                        cloudwatch_logs
    Match                       ApplicationLogs
    storage.total_limit_size    10G
```

### 最新的记录被拒绝
<a name="firelens-record-loss-newest-rejected"></a>

当磁盘空间耗尽或由于 `Mem_Buf_Limit` 暂停输入时，最新的记录将被丢弃。

磁盘空间已耗尽（文件系统缓冲）  
当磁盘空间完全耗尽时发生。Fluent Bit 无法将新记录列队且它们会丢失。为了缓解风险，将所有的 `storage.total_limit_size` 值相加并预置足够的 Amazon ECS 任务存储空间。有关更多信息，请参阅 [Amazon ECS 任务存储要求](#firelens-storage-task-requirements)。

已达到内存限制（内存缓冲）  
在输出目标不可用且内存缓冲区已满时发生。暂停的输入插件将停止接受新记录。要缓解风险，请使用 `storage.type filesystem` 提高韧性，或增加 `Mem_Buf_Limit`。

### 最大限度减少数据丢失的最佳实践
<a name="firelens-record-loss-best-practices"></a>

考虑以下最佳实践来最大限度减少数据丢失：
+ **使用文件系统缓冲** – 设置 `storage.type filesystem` 以在中断期间提高韧性。
+ **适当调整存储空间大小** – 根据日志速率和所需的恢复窗口计算 `storage.total_limit_size`。
+ **预置足够的磁盘** – 确保 Amazon ECS 任务有足够的临时存储、Amazon EBS 或 Amazon EFS。
+ **配置重试行为** – 在 `retry_limit`（用尽重试后丢弃记录）和 `no_limits`（无限次重试但可能会填满存储空间）之间保持平衡。

## 使用多目标日志记录实现可靠性
<a name="firelens-multi-destination"></a>

将日志发送到多个目标可以消除单点故障。例如，如果 CloudWatch Logs 出现中断，日志仍会到达 Amazon S3。

多目标日志记录提供以下优势：Amazon S3 输出插件还支持 gzip 和 Parquet 格式等压缩选项，这可以降低存储成本。有关更多信息，请参阅 Fluent Bit 文档中的 [S3 压缩](https://docs.fluentbit.io/manual/pipeline/outputs/s3#compression)。

多目标日志记录可以提供以下优势：
+ **冗余** – 如果一个目标出现故障，日志仍会到达另一个目标。
+ **恢复** – 重建一个系统与另一个系统之间的差距。
+ **持久性** – 将日志归档到 Amazon S3 实现长期保留。
+ **成本优化** – 将最近的日志保存在诸如 CloudWatch Logs 之类的快速查询服务中，保留时间较短，而将所有日志归档到成本较低的 Amazon S3 存储可以实现长期保留。

以下 Fluent Bit 配置将日志发送到 CloudWatch Logs 和 Amazon S3：

```
[OUTPUT]
    Name cloudwatch_logs
    Match *
    region us-west-2
    log_group_name /aws/ecs/my-app
    log_stream_name $(ecs_task_id)
    workers 2
    retry_limit 15

[OUTPUT]
    Name s3
    Match *
    bucket my-logs-bucket
    region us-west-2
    total_file_size 100M
    s3_key_format /fluent-bit-logs/$(ecs_task_id)/%Y%m%d/%H/%M/$UUID
    upload_timeout 10m
    # Maximum disk space for buffered data for this output
    storage.total_limit_size 5G
```

两个输出都使用相同的 `Match *` 模式，因此所有记录都独立发送到两个目标。在一个目标中断期间，日志继续流向另一个目标，而失败的刷新会积聚在文件系统缓冲区中供以后重试。

## 通过 tail 输入插件使用基于文件的日志记录
<a name="firelens-tail-input"></a>

对于日志丢失是一个关键问题的高吞吐量场景，可以使用另一种方法：让应用程序将日志写入磁盘上的文件，然后使用 `tail` 输入插件将 Fluent Bit 配置为读取日志。这种方法完全绕过了 Docker 日志记录驱动程序层。

通过 tail 插件进行基于文件的日志记录提供以下优势：
+ **偏移跟踪** – Tail 插件可以将文件偏移存储在数据库文件中（使用 `DB` 选项），从而在 Fluent Bit 重新启动后提供持久性。这有助于防止在容器重新启动期间丢失日志。
+ **输入级缓冲** – 可以使用 `Mem_Buf_Limit` 直接在输入插件上配置内存缓冲区限制，从而更精细地控制内存使用情况。
+ **避免 Docker 开销** – 日志直接从文件转到 Fluent Bit，无需通过 Docker 的日志缓冲区。

要使用这种方法，您的应用程序必须将日志写入文件中，而不是 `stdout`。应用程序容器和 Fluent Bit 容器都挂载一个存储日志文件的共享卷。

以下示例展示了具有最佳实践的 tail 输入配置：

```
[INPUT]
    Name tail
    # File path or glob pattern to tail
    Path /var/log/app.log
    # Database file for storing file offsets (enables resuming after restart)
    DB /var/log/flb_tail.db
    # when true, controls that only fluent-bit will access the database (improves performance)
    DB.locking true
    # Skip long lines instead of skipping the entire file
    Skip_Long_Lines On
    # How often (in seconds) to check for new files matching the glob pattern
    Refresh_Interval 10
    # Extra seconds to monitor a file after rotation to account for pending flush
    Rotate_Wait 30
    # Maximum size of the buffer for a single line
    Buffer_Max_Size 10MB
    # Initial allocation size for reading file data
    Buffer_Chunk_Size 1MB
    # Maximum memory buffer size (tail pauses when full)
    Mem_Buf_Limit 75MB
```

使用 tail 输入插件时，请考虑以下几点：
+ 对应用程序日志实施日志轮换，以防止磁盘耗尽。监控基础卷指标以衡量性能。
+ 根据您的日志格式考虑诸如 `Ignore_Older`、`Read_from_Head` 和多行解析器之类的设置。

有关更多信息，请参阅 Fluent Bit 文档中的 [Tail](https://docs.fluentbit.io/manual/pipeline/inputs/tail)。有关最佳实践，请参阅适用于 Fluent Bit 的 AWS 故障排除指南中的 [Tail 配置和最佳实践](https://github.com/aws/aws-for-fluent-bit/blob/mainline/troubleshooting/debugging.md#tail-config-with-best-practices)。

## 直接记录到 FireLens
<a name="firelens-environment-variables"></a>

在任务定义中指定 `awsfirelens` 日志驱动程序时，Amazon ECS 容器 代理会将以下环境变量注入容器中：

`FLUENT_HOST`  
分配给 FirelLens 容器的 IP 地址。  
如果在 `bridge` 网络模式下使用 EC2，则在重启 FireLens 日志路由器容器（容器定义中包含 `firelensConfiguration` 对象的容器）后，应用程序容器中的 `FLUENT_HOST` 环境变量可能会变得不准确。这是因为 `FLUENT_HOST` 是一个动态 IP 地址，重启后就会改变。地址改变后，直接从应用程序容器登录到 `FLUENT_HOST` IP 地址可能会失败。有关重启单个容器的更多信息，请参阅 [使用容器重启策略重启 Amazon ECS 任务中的单个容器](container-restart-policy.md)。

`FLUENT_PORT`  
Fluent Forward 协议正在侦听的端口。

您可以使用这些环境变量，使用 Fluent Forward 协议从应用程序代码直接记录到 Fluent Bit 日志路由器，而不是写入 `stdout`。这种方法绕过了 Docker 日志记录驱动程序层，提供以下优势：
+ **更低的延迟** – 日志无需通过 Docker 的日志记录基础设施即可直接转到 Fluent Bit。
+ **结构化日志记录** – 以原生方式发送结构化日志数据，无需 JSON 编码开销。
+ **更好的控制** – 您的应用程序可以实现自己的缓冲和错误处理逻辑。

以下 Fluent 记录器库支持 Fluent Forward 协议，可用于将日志直接发送到 Fluent Bit：
+ **Go** – [fluent-logger-golang](https://github.com/fluent/fluent-logger-golang)
+ **Python** – [fluent-logger-python](https://github.com/fluent/fluent-logger-python)
+ **Java** – [fluent-logger-java](https://github.com/fluent/fluent-logger-java)
+ **Node.js** – [fluent-logger-node](https://github.com/fluent/fluent-logger-node)
+ **Ruby** – [fluent-logger-ruby](https://github.com/fluent/fluent-logger-ruby)

## 配置 Docker 缓冲区限制
<a name="firelens-buffer-limit"></a>

创建任务定义时，您可以通过在 `log-driver-buffer-limit` 中指定值来指定将在内存中缓冲的日志行数。这会控制 Docker 和 Fluent Bit 之间的缓冲区。有关更多信息，请参阅 Docker 文档中的 [Fluentd 日志记录驱动程序](https://docs.docker.com/engine/logging/drivers/fluentd/)。

当吞吐量高时使用此选项，因为 Docker 可能会耗尽缓冲区内存并丢弃缓冲区消息，以便添加新消息。

使用此选项时，请考虑以下几点：
+ 平台版本为 `1.4.0` 或更高版本的 EC2 和 Fargate 类型支持此选项。
+ 该选项仅在 `logDriver` 设置为 `awsfirelens` 时有效。
+ 默认缓冲区限制为 `1048576` 个日志行。
+ 缓冲区限制必须大于或等于 `0` 且小于 `536870912` 个日志行。
+ 用于此缓冲区的最大内存量是每个日志行的大小与缓冲区大小的乘积。例如，假设应用程序的日志行大小平均为 `2` KiB，则缓冲区限制为 4096 时最多只能使用 `8` MiB。除了日志驱动程序的内存缓冲区外，在任务级别分配的内存总量必须大于为所有容器分配的内存量。

以下任务定义展示了如何配置 `log-driver-buffer-limit`：

```
{
    "containerDefinitions": [
        {
            "name": "my_service_log_router",
            "image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:3",
            "cpu": 0,
            "memoryReservation": 51,
            "essential": true,
            "firelensConfiguration": {
                "type": "fluentbit"
            }
        },
        {
            "essential": true,
            "image": "public.ecr.aws/docker/library/httpd:latest",
            "name": "app",
            "logConfiguration": {
                "logDriver": "awsfirelens",
                "options": {
                    "Name": "firehose",
                    "region": "us-west-2",
                    "delivery_stream": "my-stream",
                    "log-driver-buffer-limit": "52428800"
                }
            },
            "dependsOn": [
                {
                    "containerName": "my_service_log_router",
                    "condition": "START"
                }
            ],
            "memoryReservation": 100
        }
    ]
}
```

# Amazon ECS 的 AWS for Fluent Bit 映像存储库
<a name="firelens-using-fluentbit"></a>

AWS 提供了 Fluent Bit 映像以及 CloudWatch Logs 和 Firehose 的插件。我们建议使用 Fluent Bit 作为日志路由器，因为其资源利用率低于 Fluentd。有关更多信息，请参阅 [CloudWatch Logs for Fluent Bit](https://github.com/aws/amazon-cloudwatch-logs-for-fluent-bit) 和 [Amazon Kinesis Firehose for Fluent Bit](https://github.com/aws/amazon-kinesis-firehose-for-fluent-bit)。

为了获得高可用性，Amazon ECR 公开映像浏览馆和 Amazon ECR 存储库上的 Amazon ECR 都提供了 **AWS for Fluent Bit** 映像。

## Amazon ECR 公开映像浏览馆
<a name="firelens-image-ecrpublic"></a>

Amazon ECR 公开映像浏览馆提供了 AWS for Fluent Bit 映像。这是下载 AWS for Fluent Bit 映像的推荐位置，因为它是一个公共存储库，可从所有AWS 区域区域使用。有关更多信息，请参阅 Amazon ECR 公开映像浏览馆上的 [aws-for-fluent-bit](https://gallery.ecr.aws/aws-observability/aws-for-fluent-bit)。

### Linux
<a name="firelens-image-ecrpublic-linux"></a>

Amazon ECR 公开映像浏览馆中的 AWS for Fluent Bit 映像支持带有 `ARM64` 或 `x86-64` 架构的 Amazon Linux 操作系统。

通过使用所需的映像标记指定存储库 URL，可以从 Amazon ECR 公开映像浏览馆中提取 AWS for Fluent Bit 映像。可在 Amazon ECR 公开映像浏览馆上的**映像标签**选项卡上找到映像标签。

下面说明 Docker CLI 使用的语法。

```
docker pull public.ecr.aws/aws-observability/aws-for-fluent-bit:tag
```

例如，您可以使用此 Docker CLI 命令拉取适用于 Fluent Bit 的 AWS 版本的“3.x”系列中的最新映像。

```
docker pull public.ecr.aws/aws-observability/aws-for-fluent-bit:3
```

**注意**  
可以进行未经身份验证的拉取，但速率限制低于经过身份验证的拉取。拉取前如果要使用 AWS 账户验证身份，请使用以下命令。  

```
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws
```

#### AWS for Fluent Bit 3.0.0
<a name="firelens-image-ecrpublic-linux-3.0.0"></a>

除了现有的 AWS for Fluent Bit 版本 `2.x` 外，AWS for Fluent Bit 还支持新的主要版本 `3.x`。新的主要版本包括将映像从 Amazon Linux 2 升级到 Amazon Linux 2023 以及将 Fluent Bit 版本 `1.9.10` 升级到 `4.1.1`。有关更多信息，请参阅 GitHub 上的 [AWS for Fluent Bit 存储库](https://github.com/aws/aws-for-fluent-bit/blob/mainline/VERSIONS.md)。

以下示例展示了 AWS for Fluent Bit `3.x` 映像更新后的标签：

您可以对 AWS for Fluent Bit 映像使用多架构标签。

```
docker pull public.ecr.aws/aws-observability/aws-for-fluent-bit:3
```

### Windows
<a name="firelens-image-ecrpublic-windows"></a>

Amazon ECR 公开映像浏览馆中 Fluent Bit 映像的 AWS 支持带有以下操作系统的 `AMD64` 架构：
+ Windows Server 2022 Full
+ Windows Server 2022 Core
+ Windows Server 2019 Full
+ Windows Server 2019 Core

AWS Fargate 上的 Windows 容器不支持 FireLens。

通过使用所需的映像标记指定存储库 URL，可以从 Amazon ECR 公开映像浏览馆中提取 AWS for Fluent Bit 映像。可在 Amazon ECR 公开映像浏览馆上的**映像标签**选项卡上找到映像标签。

下面说明 Docker CLI 使用的语法。

```
docker pull public.ecr.aws/aws-observability/aws-for-fluent-bit:tag
```

例如，您可以使用此 Docker CLI 命令拉取最新的稳定 AWS for Fluent Bit 映像。

```
docker pull public.ecr.aws/aws-observability/aws-for-fluent-bit:windowsservercore-stable
```

**注意**  
可以进行未经身份验证的拉取，但速率限制低于经过身份验证的拉取。拉取前如果要使用 AWS 账户验证身份，请使用以下命令。  

```
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws
```

## Amazon ECR
<a name="firelens-image-ecr"></a>

AWS for Fluent Bit 映像可在 Amazon ECR 上获得高可用性。可以使用以下命令来检索映像 URI 并确定映像在给定 AWS 区域 区域的可用性。

### Linux
<a name="firelens-image-ecr-linux"></a>

可以使用以下命令检索最新的稳定 AWS for Fluent Bit 映像 URI。

```
aws ssm get-parameters \
      --names /aws/service/aws-for-fluent-bit/stable \
      --region us-east-1
```

使用以下命令来查询 Systems Manager Parameter Store 参数可以列出 AWS for Fluent Bit 映像的所有版本。

```
aws ssm get-parameters-by-path \
      --path /aws/service/aws-for-fluent-bit \
      --region us-east-1
```

可以通过引用 Systems Manager 参数存储名称在 CloudFormation 模板中引用最新的稳定 AWS for Fluent Bit 映像。以下是示例：

```
Parameters:
  FireLensImage:
    Description: Fluent Bit image for the FireLens Container
    Type: AWS::SSM::Parameter::Value<String>
    Default: /aws/service/aws-for-fluent-bit/stable
```

**注意**  
如果命令失败或没有输出，则映像在调用该命令的 AWS 区域不可用。

### Windows
<a name="firelens-image-ecr-windows"></a>

可以使用以下命令检索最新的稳定 AWS for Fluent Bit 映像 URI。

```
aws ssm get-parameters \
      --names /aws/service/aws-for-fluent-bit/windowsservercore-stable \
      --region us-east-1
```

使用以下命令来查询 Systems Manager Parameter Store 参数可以列出 AWS for Fluent Bit 映像的所有版本。

```
aws ssm get-parameters-by-path \
      --path /aws/service/aws-for-fluent-bit/windowsservercore \
      --region us-east-1
```

可以通过引用 Systems Manager 参数存储名称在 CloudFormation 模板中引用最新的稳定 AWS for Fluent Bit 映像。以下是示例：

```
Parameters:
  FireLensImage:
    Description: Fluent Bit image for the FireLens Container
    Type: AWS::SSM::Parameter::Value<String>
    Default: /aws/service/aws-for-fluent-bit/windowsservercore-stable
```

# Amazon ECS 任务定义示例：将日志路由到 FireLens
<a name="firelens-taskdef"></a>

要将自定义日志路由与 FireLens 结合使用，您必须在任务定义中指定以下内容：
+ 包含 FireLens 配置的日志路由器容器。我们建议将容器标记为 `essential`。
+ 一个或多个包含指定 `awsfirelens` 日志驱动程序的日志配置的应用程序容器。
+ 一个任务 IAM 角色 Amazon 资源名称（ARN），其中包含任务路由日志所需的权限。

使用 AWS 管理控制台创建新的任务定义时，通过 Firelens 集成部分可以轻松添加日志路由器容器。有关更多信息，请参阅 [使用控制台创建 Amazon ECS 任务定义](create-task-definition.md)。

Amazon ECS 将转换日志配置并生成 Fluentd 或 Fluent Bit 输出配置。输出配置挂载在 `/fluent-bit/etc/fluent-bit.conf`（对于 Fluent Bit）和 `/fluentd/etc/fluent.conf`（对于 Fluentd）处的日志路由容器中。

**重要**  
FireLens 在端口 `24224` 上侦听。因此，为了确保从任务外部无法访问 FireLens 日志路由器，不得允许任务使用的安全组中端口 `24224` 上的入口流量。对于使用 `awsvpc` 网络模式的任务，这是与任务关联的安全组。对于使用 `host` 网络模式的任务，它是与托管任务的 Amazon EC2 实例关联的安全组。对于使用 `bridge` 网络模式的任务，请勿创建任何使用端口 `24224` 的端口映射。

默认情况下，Amazon ECS 会在日志条目中添加其他字段来帮助标识日志源。
+ `ecs_cluster`：任务所属的集群的名称。
+ `ecs_task_arn` – 容器所属的任务的完整 Amazon 资源名称（ARN）。
+ `ecs_task_definition`：任务正在使用的任务定义名称和修订。
+ `ec2_instance_id` – 容器托管于的 Amazon EC2 实例 ID。此字段仅对使用 EC2 启动类型的任务有效。

如果您不想要元数据，可以将 `enable-ecs-log-metadata` 设置为 `false`。

下面的任务定义示例定义了一个日志路由器容器，它使用 Fluent Bit 将日志路由到 CloudWatch Logs。该示例还定义了一个应用程序容器，它使用日志配置将日志路由到 Amazon Data Firehose 并将用于缓冲事件的内存设置为 2MiB。

**注意**  
有关更多示例任务定义，请参阅 GitHub 上的 [Amazon ECS FireLens 示例](https://github.com/aws-samples/amazon-ecs-firelens-examples)。

```
{
  "family": "firelens-example-firehose",
  "taskRoleArn": "arn:aws:iam::123456789012:role/ecs_task_iam_role",
  "containerDefinitions": [
    {
            "name": "log_router",
            "image": "public.ecr.aws/aws-observability/aws-for-fluent-bit:3",
            "cpu": 0,
            "memoryReservation": 51,
            "portMappings": [],
            "essential": true,
            "environment": [],
            "mountPoints": [],
            "volumesFrom": [],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "/ecs/ecs-aws-firelens-sidecar-container",
                    "mode": "non-blocking",
                    "awslogs-create-group": "true",
                    "max-buffer-size": "25m",
                    "awslogs-region": "us-east-1",
                    "awslogs-stream-prefix": "firelens"
                },
                "secretOptions": []
            },
            "systemControls": [],
            "firelensConfiguration": {
                "type": "fluentbit"
            }
        },
    {
      "essential": true,
      "image": "public.ecr.aws/docker/library/httpd:latest",
      "name": "app",
      "logConfiguration": {
        "logDriver": "awsfirelens",
        "options": {
          "Name": "firehose",
          "region": "us-west-2",
          "delivery_stream": "my-stream",
          "log-driver-buffer-limit": "1048576"
        }
      },
      "memoryReservation": 100
    }
  ]
}
```

在 `logConfiguration` 对象中指定为选项的键值对用于生成 Fluentd 或 Fluent Bit 输出配置。以下是来自 Fluent Bit 输出定义的代码示例。

```
[OUTPUT]
    Name   firehose
    Match  app-firelens*
    region us-west-2
    delivery_stream my-stream
```

**注意**  
FirelLens 可管理 `match` 配置。您没有在任务定义中指定 `match` 配置。

## 使用自定义配置文件
<a name="firelens-taskdef-customconfig"></a>

您可以指定自定义配置文件。配置文件格式是您所使用的日志路由器的本机格式。有关更多信息，请参阅 [Fluentd Config 文件语法](https://docs.fluentd.org/configuration/config-file)和 [YAML 配置](https://docs.fluentbit.io/manual/administration/configuring-fluent-bit/yaml)。

在您的自定义配置文件中，对于使用 `bridge` 或 `awsvpc` 网络模式的任务，请勿通过 TCP 设置 Fluentd 或 Fluent Bit 转发输入，因为 FireLens 会将它添加到输入配置中。

您的 FireLens 配置必须包含以下选项才能指定自定义配置文件：

`config-file-type`  
自定义配置文件的源位置。可用选项为 `s3` 或 `file`。  
托管在 AWS Fargate 上的任务仅支持 `file` 配置文件类型。但是，您可以使用适用于 Fluent Bit 的 AWS 初始化容器在 AWS Fargate 上使用 Amazon S3 中托管的配置文件。有关更多信息，请参阅 GitHub 上的 [ECS 上的 Fluent Bit 的初始化进程，多配置支持](https://github.com/aws/aws-for-fluent-bit/blob/mainline/use_cases/init-process-for-fluent-bit/README.md)。

`config-file-value`  
自定义配置文件的源。如果使用 `s3` 配置文件类型，则配置文件值是 Amazon S3 存储桶和文件的完整 ARN。如果使用 `file` 配置文件类型，则配置文件值是容器映像中或挂载到容器中的卷上存在的配置文件的完整路径。  
在使用自定义配置文件时，必须指定一个与 FireLens 所用路径不同的路径。Amazon ECS 保留对于 Fluent Bit 和 `/fluentd/etc/fluent.conf` 对于 Fluentd 的文件路径 `/fluent-bit/etc/fluent-bit.conf`。

以下示例显示了指定自定义配置时所需的语法。

**重要**  
要指定托管于 Amazon S3 中的自定义配置文件，请确保已创建具有适当权限的任务执行 IAM 角色。

下面显示了在指定自定义配置时所需的语法。

```
{
  "containerDefinitions": [
    {
      "essential": true,
      "image": "906394416424.dkr.ecr.us-west-2.amazonaws.com/aws-for-fluent-bit:3",
      "name": "log_router",
      "firelensConfiguration": {
        "type": "fluentbit",
        "options": {
          "config-file-type": "s3 | file",
          "config-file-value": "arn:aws:s3:::amzn-s3-demo-bucket/fluent.conf | filepath"
        }
      }
    }
  ]
}
```

**注意**  
托管在 AWS Fargate 上的任务仅支持 `file` 配置文件类型。但是，您可以使用适用于 Fluent Bit 的 AWS 初始化容器在 AWS Fargate 上使用 Amazon S3 中托管的配置文件。有关更多信息，请参阅 GitHub 上的 [ECS 上的 Fluent Bit 的初始化进程，多配置支持](https://github.com/aws/aws-for-fluent-bit/blob/mainline/use_cases/init-process-for-fluent-bit/README.md)。