如何配置Grafana Loki动态采集并过滤AWS弹性伸缩EC2实例日志?
解决方案
问题1:配置Promtail动态发现弹性伸缩组内的EC2实例
Promtail原生支持AWS EC2服务发现,可通过EC2标签筛选弹性伸缩组(ASG)内的实例,无需手动维护IP列表。核心是利用ec2_sd_configs配置段结合标签过滤,同时通过IAM角色赋予Promtail访问EC2元数据的权限。
关键配置示例(promtail-config.yaml)
scrape_configs: - job_name: "aws-ec2-asg-logs" # 启用EC2服务发现 ec2_sd_configs: - region: us-east-1 # 替换为你的AWS区域 port: 9080 # Promtail默认监听端口(拉取模式需确保实例启动此端口;推送模式可忽略) filters: # 通过ASG名称过滤实例,替换为你的弹性伸缩组名称 - name: "tag:aws:autoscaling:groupName" values: ["your-asg-group-name"] # 重写标签,保留实例标识信息 relabel_configs: # 保留实例ID作为标签 - source_labels: [__meta_aws_ec2_instance_id] target_label: instance_id # 保留ASG名称标签 - source_labels: [__meta_aws_ec2_tag_aws_autoscaling_groupName] target_label: asg_name # 仅保留运行中的实例 - source_labels: [__meta_aws_ec2_instance_state] regex: running action: keep # 日志收集路径配置(替换为你的日志路径) static_configs: - targets: ["localhost"] labels: job: "myapp-logs" __path__: "/var/log/myapp/*.log"
注意事项
- 确保Promtail所在实例拥有
ec2:DescribeInstances的IAM权限,通过IAM角色绑定实现,无需硬编码密钥。 - 若采用推送模式(实例上的Promtail主动推送到Loki),无需配置
ec2_sd_configs的port,而是在每个实例的Promtail配置中加入remote_write指向Loki,同时通过启动模板/用户数据在实例启动时自动安装配置Promtail,新实例加入ASG后会自动推送日志。
问题2:为日志添加服务器标识以便过滤
最便捷的方式是通过Promtail自动从EC2元数据提取实例信息,作为日志标签附加,无需修改应用代码。
方式1:通过Promtail标签注入(推荐)
在Promtail的static_configs中直接注入实例元数据:
static_configs: - targets: ["localhost"] labels: job: "myapp-logs" instance_id: "${__meta_aws_ec2_instance_id}" # 自动获取实例ID hostname: "${__meta_aws_ec2_hostname}" # 自动获取主机名 __path__: "/var/log/myapp/*.log"
过滤效果
在Grafana的Loki查询中,可直接通过标签过滤单台实例日志:
{job="myapp-logs", instance_id="i-0123456789abcdef0"}
问题3:AWS弹性伸缩组日志收集的最佳实践与工具
最佳实践
- 用启动模板自动部署Promtail:将Promtail的安装、配置脚本加入EC2启动模板的用户数据,新实例加入ASG后自动完成配置并启动日志推送,无需手动干预。
示例用户数据(bash脚本):#!/bin/bash # 安装Promtail wget https://github.com/grafana/loki/releases/download/v2.9.0/promtail-linux-amd64.zip unzip promtail-linux-amd64.zip mv promtail-linux-amd64 /usr/local/bin/promtail # 写入Promtail配置(替换Loki地址) cat > /etc/promtail-config.yaml << EOF server: http_listen_port: 9080 grpc_listen_port: 0 positions: filename: /tmp/positions.yaml clients: - url: http://your-loki-endpoint:3100/loki/api/v1/push scrape_configs: - job_name: "myapp-logs" static_configs: - targets: ["localhost"] labels: job: "myapp-logs" instance_id: \$(curl -s http://169.254.169.254/latest/meta-data/instance-id) __path__: "/var/log/myapp/*.log" EOF # 创建systemd服务启动Promtail cat > /etc/systemd/system/promtail.service << EOF [Unit] Description=Promtail Service After=network.target [Service] ExecStart=/usr/local/bin/promtail -config.file=/etc/promtail-config.yaml Restart=always [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable --now promtail - 使用IAM角色而非密钥:为EC2实例绑定IAM角色,授予必要的EC2元数据访问权限,避免密钥泄露。
- 结合CloudWatch作为中间层:如果Promtail直接收集存在网络限制,可先将日志推送到CloudWatch Logs,再通过Loki的CloudWatch数据源拉取日志到Grafana,利用CloudWatch的自动实例发现能力。
推荐工具
- Promtail:与Loki原生集成,轻量且配置简单,适合直接收集EC2日志。
- Fluent Bit:性能更优,支持更多数据源和输出,适合大规模ASG场景,可通过AWS Firehose中转到Loki。
- AWS Systems Manager:用于批量管理Promtail配置更新,无需登录实例。
内容的提问来源于stack exchange,提问作者Abdul Gaffoor Noor Basha
相关产品推荐
相关产品推荐

