如何将GCP中VM的输出定向至Stackdriver及配置日志条目属性
我来帮你一步步解决这两个问题——把GCP VM的输出定向到Stackdriver(现在官方更名为Cloud Logging,但咱们还是沿用你提到的名称),以及配置日志的级别、名称这些属性:
1. 确保VM拥有日志写入权限
首先得给你的VM服务账号授予Logging Writer角色,这样VM才能把日志发送到Stackdriver:
- 你可以在GCP控制台的VM详情页,找到「服务账号」选项卡添加角色;
- 或者用gcloud命令行执行:
gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \ --member=serviceAccount:YOUR_VM_SERVICE_ACCOUNT \ --role=roles/logging.logWriter
(记得替换YOUR_PROJECT_ID和YOUR_VM_SERVICE_ACCOUNT为实际值)
2. 安装并配置日志代理(推荐Ops Agent)
GCP现在推荐用Cloud Operations Ops Agent替代旧的Stackdriver Agent,它能同时收集日志和指标。
安装Ops Agent
- Debian/Ubuntu:
curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh bash add-google-cloud-ops-agent-repo.sh --also-install
- RHEL/CentOS:
curl -sSO https://dl.google.com/cloudagents/add-google-cloud-ops-agent-repo.sh bash add-google-cloud-ops-agent-repo.sh --also-install
- Windows(PowerShell):
(New-Object Net.WebClient).DownloadFile("https://dl.google.com/cloudagents/google-cloud-ops-agent-windows-installer.exe", "$env:TEMP\google-cloud-ops-agent-windows-installer.exe") & "$env:TEMP\google-cloud-ops-agent-windows-installer.exe" /S
收集自定义应用日志
如果你的应用把输出写到某个文件(比如/var/log/myapp.log),需要修改Ops Agent的配置文件来指定收集这个文件:
- Linux配置路径:
/etc/google-cloud-ops-agent/config.yaml - Windows配置路径:
C:\Program Files\Google\Cloud Operations\Ops Agent\config\config.yaml
示例配置(收集JSON格式的应用日志):
logging: receivers: myapp_log: type: files include_paths: - /var/log/myapp.log record_log_file_path: true processors: parse_json: type: parse_json field: message time_key: timestamp time_format: "%Y-%m-%dT%H:%M:%S%z" service: pipelines: default_pipeline: receivers: [myapp_log] processors: [parse_json]
修改后重启代理:
- Linux:
sudo systemctl restart google-cloud-ops-agent - Windows:
Restart-Service google-cloud-ops-agent
收集应用的stdout/stderr
如果你的应用直接输出到控制台,你可以:
- 把输出重定向到上面配置的日志文件,比如:
./myapp > /var/log/myapp.log 2>&1 - 用systemd管理应用,让stdout/stderr输出到journald(Ops Agent默认会收集journald日志)。示例systemd服务文件:
[Unit] Description=My Custom App [Service] ExecStart=/path/to/myapp StandardOutput=journal+console StandardError=journal+console Restart=always [Install] WantedBy=multi-user.target
1. 应用层面直接设置(推荐)
如果你的应用使用Stackdriver Logging的SDK,可以直接在代码里指定日志级别和名称,这样最准确。
以Python为例(使用google-cloud-logging库):
import logging from google.cloud import logging_v2 # 初始化客户端和自定义日志器 client = logging_v2.Client() custom_logger = client.logger("my-app-logger") # 这里设置日志名称 # 发送不同级别的日志 custom_logger.log_text("这是一条INFO级别的日志", severity="INFO") custom_logger.log_text("这是一条WARNING级别的日志", severity="WARNING") custom_logger.log_text("这是一条ERROR级别的日志", severity="ERROR") # 也可以结合Python标准logging模块 handler = client.get_default_handler() cloud_logger = logging.getLogger("cloud-standard-logger") cloud_logger.setLevel(logging.INFO) cloud_logger.addHandler(handler) cloud_logger.info("标准INFO日志") cloud_logger.warning("标准WARNING日志") cloud_logger.error("标准ERROR日志")
其他语言(Java、Go等)也有对应的SDK,用法类似,直接指定severity和logger名称即可。
2. 通过日志代理解析设置
如果应用输出的是结构化日志(比如JSON格式),可以通过Ops Agent的处理器来提取并设置级别和名称:
设置日志级别
假设你的应用日志格式是:{"timestamp": "2024-05-20T12:34:56Z", "level": "ERROR", "message": "出错了"},可以添加modify_fields处理器把level映射到Stackdriver的severity字段:
logging: receivers: myapp_log: type: files include_paths: - /var/log/myapp.log processors: parse_json: type: parse_json field: message set_severity: type: modify_fields fields: severity: copy_from: jsonPayload.level service: pipelines: default_pipeline: receivers: [myapp_log] processors: [parse_json, set_severity]
设置日志名称
在接收器配置里添加log_id即可指定日志名称:
logging: receivers: myapp_log: type: files include_paths: - /var/log/myapp.log log_id: "my-custom-logger" # 自定义日志名称 service: pipelines: default_pipeline: receivers: [myapp_log]
3. 在Stackdriver控制台筛选日志
配置完成后,你可以在Cloud Logging控制台用过滤条件快速筛选:
- 按级别筛选:
severity=ERROR - 按日志名称筛选:
logName="projects/YOUR_PROJECT/logs/my-custom-logger"
内容的提问来源于stack exchange,提问作者Andy

