收集 Google App Engine 日志

解析器版本:3.0

支持的平台:

本文档介绍了如何使用 Google Cloud Storage V2 将 Google App Engine 日志注入 Google Security Operations。

Google App Engine 是一个全代管式无服务器平台,用于构建和部署 Web 应用和 API。App Engine 会自动为 HTTP 请求生成请求日志,并根据您的代码生成应用日志。这些日志会发送到 Cloud Logging,并可导出到 Cloud Storage,以便注入到 Google Security Operations。

准备工作

确保您满足以下前提条件:

  • Google SecOps 实例
  • 启用了 Cloud Storage API 的 GCP 项目
  • 创建和管理 GCS 存储桶的权限
  • 管理 GCS 存储桶的 IAM 政策的权限
  • 创建 Cloud Logging 日志接收器的权限 (roles/logging.configWriter)
  • 有效的 App Engine 应用(标准环境或柔性环境)

创建 Google Cloud Storage 存储桶

  1. 前往 Google Cloud 控制台。
  2. 选择您的项目或创建一个新项目。
  3. 在导航菜单中,依次前往 Cloud Storage > 存储桶。
  4. 点击创建存储分区。
  5. 提供以下配置详细信息:

    设置 值
    为存储桶命名 输入一个全局唯一的名称(例如 appengine-logs-export)
    位置类型 根据您的需求进行选择(区域级、双区域级、多区域级)
    位置 选择位置(例如 us-central1)
    存储类别 标准(推荐用于频繁访问的日志)
    访问权限控制 统一(推荐)
    保护工具 可选:启用对象版本控制或保留政策
  6. 点击创建。

配置 Cloud Logging,以将 App Engine 日志导出到 GCS

Cloud Logging 使用日志接收器将日志条目路由到支持的目标位置,包括 Cloud Storage 存储桶。接收器的写入者身份需要对目标存储桶拥有 Storage Object Creator 角色 (roles/storage.objectCreator)。

创建 Cloud Logging 日志接收器

  1. 在 Google Cloud 控制台中,前往 Logging>日志路由器。
  2. 点击创建接收器。
  3. 提供以下配置详细信息:
    • 接收器名称:输入一个描述性名称(例如 appengine-to-gcs)。
    • 接收器说明:可选说明。
  4. 点击下一步。
  5. 在选择接收器服务部分中:
    • 接收器服务:选择 Cloud Storage 存储桶。
    • 选择 Cloud Storage 存储桶:从下拉菜单中选择 appengine-logs-export。
  6. 点击下一步。
  7. 在选择要包含在接收器中的日志部分,输入过滤条件查询以选择 App Engine 日志。资源类型必须正好为“gae_app”。

    对于所有 App Engine 日志(请求日志和应用日志):

    resource.type="gae_app"
    

    仅适用于 App Engine 请求日志:

    resource.type="gae_app"
    logName="projects/PROJECT_ID/logs/appengine.googleapis.com/request_log"
    

    对于 App Engine 应用日志 (stdout/stderr):

    resource.type="gae_app"
    (logName="projects/PROJECT_ID/logs/stdout" OR logName="projects/PROJECT_ID/logs/stderr")
    

    将 PROJECT_ID 替换为您的 GCP 项目 ID。

  8. 点击下一步。

  9. 检查配置,然后点击创建接收器。

向接收器写入者身份授予权限

创建接收器后,您必须向接收器的写入者身份授予目标存储桶的 Storage Object Creator 角色。服务账号的写入者身份类似于:serviceAccount:service-123456789012@gcp-sa-logging.iam.gserviceaccount.com

  1. 在日志路由器页面中,找到新创建的接收器。
  2. 点击源名称旁边的菜单图标(三个竖点)。
  3. 选择查看接收器详情。
  4. 复制写入者身份(服务账号邮箱)。
  5. 前往 Cloud Storage > 存储桶。
  6. 点击相应存储桶的名称 (appengine-logs-export)。
  7. 前往权限标签页。
  8. 点击授予访问权限。
  9. 提供以下配置详细信息:
    • 添加主账号:粘贴接收器的写入者身份(服务账号邮箱)。
    • 分配角色:选择 Storage Object Creator。
  10. 点击保存。

检索 Google SecOps 服务账号

Google SecOps 使用唯一的服务账号从您的 GCS 存储桶中读取数据。您必须向此服务账号授予对存储桶的访问权限。

在 Google SecOps 中配置 Feed 以注入 App Engine 日志

  1. 前往 SIEM 设置 > Feed。
  2. 点击添加新 Feed。
  3. 点击配置单个 Feed。
  4. 在 Feed 名称字段中,输入 Feed 的名称(例如 App Engine Logs)。
  5. 选择 Google Cloud Storage V2 作为来源类型。
  6. 选择 GCP_APP_ENGINE 作为日志类型。

  7. 点击获取服务账号。

  8. 系统会显示一个专属的服务账号邮箱,例如:

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  9. 复制此邮箱。您将在下一步骤中用到它。

  10. 点击下一步。

  11. 为以下输入参数指定值:

    • 存储桶网址:输入带有前缀路径的 GCS 存储桶 URI:

      gs://appengine-logs-export/
      

      Cloud Logging 会在目录分层结构下按日志类型和日期整理导出的日志文件。日志类型可以是复合名称,例如 appengine.googleapis.com/request_log。文件会进行分片,并以时间段命名(例如 08:00:00_08:59:59_S0.json)。

    • 来源删除选项:根据您的偏好选择删除选项:

      • 永不:转移后永不删除任何文件(建议在测试时使用)。
      • 删除已转移的文件:在成功转移后删除文件。
      • 删除已转移的文件和空目录:成功转移后删除文件和空目录。
    • 文件存在时间上限:包含过去指定天数内修改过的文件。默认值为 180 天。

    • 资源命名空间:资源命名空间。

    • 注入标签:要应用于此 Feed 中的事件的标签。

  12. 点击下一步。

  13. 在最终确定界面中查看新的新闻信息流配置,然后点击提交。

向 Google SecOps 服务账号授予 IAM 权限

Google SecOps 服务账号需要对您的 GCS 存储桶拥有 Storage Object Viewer 角色。

  1. 前往 Cloud Storage > 存储桶。
  2. 点击存储桶名称 (appengine-logs-export)。
  3. 前往权限标签页。
  4. 点击授予访问权限。
  5. 提供以下配置详细信息:
    • 添加主账号:粘贴 Google SecOps 服务账号邮箱。
    • 分配角色:选择 Storage Object Viewer。
  6. 点击保存。

了解 App Engine 日志结构

App Engine 会自动将请求日志和应用日志发送到 Cloud Logging。App Engine 会自动针对发送到应用的请求发出日志,因此无需写入请求日志。本部分介绍了如何写入应用日志。

App Engine 请求日志包含 protoPayload 字段,这些字段包含 RequestLog 类型的对象,其 @type 为“type.googleapis.com/google.appengine.logging.v1.RequestLog”。资源类型为“gae_app”。

默认情况下,日志载荷是存储在日志条目的 textPayload 字段中的文本字符串。这些字符串在 Logs Explorer 中显示为消息,并与发出它们的 App Engine 服务和版本相关联。

如需写入结构化日志,请以单行序列化 JSON 的形式写入日志。如果您以 JSON 字典形式提供结构化日志,则系统会从 jsonPayload 中删除某些特殊字段,并将这些字段写入所生成 LogEntry 中的相应字段。例如,如果您的 JSON 包含 severity 属性,则系统会将该属性从 jsonPayload 中移除,并将其显示为日志条目的 severity。

已知限制

将日志从日志接收器路由到 Cloud Storage 时,Cloud Storage 目标位置仅包含请求日志。App Engine 将应用日志写入不同的文件夹。

路由的日志条目每小时向 Cloud Storage 存储桶保存一批。第一批条目可能需要 2 到 3 个小时才会开始显示。

在 App Engine 柔性环境中,日志记录会自动运行。不过,日志会以不同的格式收集。日志不会被请求捆绑,并且来自 stdout 和 stderr 的日志是分开收集的。

UDM 映射表

日志字段 UDM 映射 逻辑
jsonPayload.logger, taskTypeName, jsonPayload.@type, jsonPayload.backendTargetProjectNumber, jsonPayload.cacheDecision, resource.labels.version_id, resource.labels.module_id, logName, spanId, trace, protoPayload.@type, labels.clone_id, operation.producer additional.fields 与根据每个字段创建的键值对标签合并
元数据 元数据 已从“元数据”重命名
receiveTimestamp metadata.collected_timestamp 使用 RFC 3339 日期过滤器解析
metadata.event_type 如果 has_principal、has_target、has_principal_user 为 true,则设置为“USER_LOGIN”;如果 has_principal 和 has_target 为 true,则设置为“NETWORK_CONNECTION”;如果 has_principal 为 false 且 has_target 为 true,则设置为“USER_UNCATEGORIZED”;如果 has_principal 为 true,则设置为“STATUS_UPDATE”;如果 has_principal_user 为 true,则设置为“USER_UNCATEGORIZED”;否则设置为“GENERIC_EVENT”
metadata.extensions.auth.type 如果 has_principal、has_target、has_principal_user,则设置为“AUTHTYPE_UNSPECIFIED”
insertId metadata.product_log_id 直接复制的值
httpRequest.requestMethod,protoPayload.method network.http.method httpRequest.requestMethod 中的值(如果不为空),否则为 protoPayload.method
httpRequest.userAgent network.http.parsed_user_agent 已转换为 parseduseragent
httpRequest.status network.http.response_code 转换为字符串,然后转换为整数
httpRequest.userAgent network.http.user_agent 直接复制值
httpRequest.responseSize network.received_bytes 已转换为无符号整数
httpRequest.requestSize network.sent_bytes 已转换为无符号整数
主体 主体 如果非空,则重命名自主体
protoPayload.host principal.asset.hostname 直接复制的值
httpRequest.serverIp, protoPayload.ip principal.asset.ip 已与 httpRequest.serverIp 或 protoPayload.ip 中的 server_ip 合并
protoPayload.host principal.hostname 直接复制的值
httpRequest.serverIp, protoPayload.ip principal.ip 与 httpRequest.serverIp 或 protoPayload.ip 中的 server_ip 合并
protoPayload.appId principal.resource.attribute.labels 与包含键“appId”和相应字段中的值的 appId_label 合并
requestUser principal.user.email_addresses 如果与电子邮件格式匹配,则与 requestUser 合并
security_result security_result 从 security_result 合并
resource.labels.forwarding_rule_name security_result.rule_labels 与包含键“forwarding_rule_name”和字段值的 rule_label 合并
和程度上减少 security_result.severity 如果与 (?i)ERROR|CRITICAL 匹配,则设置为严重级别;如果与 (?i)INFO 匹配,则设置为 INFORMATIONAL;如果与 (?i)WARN 匹配,则设置为 MEDIUM;如果与 (?i)DEBUG 匹配,则设置为 LOW;否则设置为 UNKNOWN_SEVERITY
jsonPayload.statusDetails security_result.summary 直接复制值
目标 目标 如果目标不为空,则从目标重命名
resource.labels.backend_service_name target.application 直接复制的值
httpRequest.remoteIp、jsonPayload.remoteIp target.asset.ip 与从 httpRequest.remoteIp 或 jsonPayload.remoteIp 中提取的 remote_ip 合并
resource.labels.project_id target.cloud.project.name 直接复制的值
httpRequest.remoteIp、jsonPayload.remoteIp target.ip 与从 httpRequest.remoteIp 或 jsonPayload.remoteIp 提取的 remote_ip 合并
resource.labels.zone target.resource.attribute.cloud.availability_zone 直接复制值
resource.labels.target_proxy_name、resource.labels.url_map_name target.resource.attribute.labels 与每个来源的标签合并
resource.type target.resource.type 直接复制的值
httpRequest.requestUrl target.url 直接复制的值
metadata.product_name 设置为“GCP_APP_ENGINE”
metadata.vendor_name 设置为“GCP”
protoPayload.requestMetadata.callerIp event.idm.read_only_udm.principal.ip 从更新日志映射
protoPayload.requestMetadata.callerIp event.idm.read_only_udm.principal.asset.ip 从更新日志映射
protoPayload.authenticationInfo.principalEmail event.idm.read_only_udm.principal.user.email_addresses 从更新日志映射
protoPayload.methodName event.idm.read_only_udm.metadata.product_event_type 从更新日志映射
protoPayload.resourceName event.idm.read_only_udm.target.resource.name 从更新日志映射
protoPayload.serviceName event.idm.read_only_udm.target.application 从更新日志映射
protoPayload.resourceLocation.currentLocations event.idm.read_only_udm.target.resource.attribute.labels 从更新日志映射
protoPayload.authenticationInfo.oauthInfo.oauthClientId event.idm.read_only_udm.principal.resource.attribute.labels 从更新日志映射
protoPayload.requestMetadata.requestAttributes.time event.idm.read_only_udm.additional.fields 从更新日志映射
operation.first event.idm.read_only_udm.additional.fields 从更新日志映射
protoPayload.serviceData.updateService.request.updateMask event.idm.read_only_udm.additional.fields 从更新日志映射
operation.id event.idm.read_only_udm.additional.fields 从更新日志映射
protoPayload.authenticationInfo.serviceAccountKeyName event.idm.read_only_udm.additional.fields 从更新日志映射
protoPayload.authorizationInfo.permission event.idm.read_only_udm.security_result.rule_name 从更新日志映射
protoPayload.authorizationInfo.permissionType event.idm.read_only_udm.security_result.description 从更新日志映射
protoPayload.authorizationInfo.granted event.idm.read_only_udm.security_result.action 从更新日志映射
protoPayload.@type" , "labels.clone_id" and "operation.producer additional.labels 从更新日志映射

更新日志

查看此解析器的更新日志

需要更多帮助?获得社区成员和 Google SecOps 专业人士的解答。