收集 PingOne Advanced Identity Cloud 日志

解析器版本:4.0

支持的平台:

本文档介绍了如何使用 Google Cloud Storage V2 将 PingOne Advanced Identity Cloud(以前称为 ForgeRock Identity Cloud)日志注入到 Google Security Operations。

PingOne Advanced Identity Cloud 是一种云原生身份即服务 (IDaaS) 平台,可提供身份管理、访问管理和身份治理功能。借助 Cloud Identity,组织可以管理用户身份、强制执行身份验证政策(包括多重身份验证),并在应用中提供单点登录功能,同时保持合规性和安全性。

如需了解详情,请参阅 ForgeRock Identity Cloud 文档

准备工作

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

  • Google SecOps 实例
  • 已启用 Cloud Storage API 的 GCP 项目
  • 创建和管理 GCS 存储分区的权限
  • 管理 GCS 存储分区的 IAM 政策的权限
  • 创建 Cloud Run 服务、Pub/Sub 主题和 Cloud Scheduler 作业的权限
  • 对 PingOne Advanced Identity Cloud 管理控制台的特权访问权限(租户管理员)
  • 具有监控端点访问权限的 PingOne Advanced Identity Cloud Log API 密钥和 Secret

创建 Google Cloud Storage 存储桶

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

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

在 PingOne Advanced Identity Cloud 中创建日志 API 密钥

PingOne Advanced Identity Cloud 使用 Log API 密钥对向 /monitoring/logs 端点发出的请求进行身份验证。这与用于 AM/IDM 操作的服务账号不同。

创建 API 密钥

  1. 前往 https://<tenant-env-fqdn>/platform/admin(例如 https://openam-mycompany-ew2.id.forgerock.io/platform/admin),登录 PingOne Advanced Identity Cloud 管理控制台。
  2. 点击租户菜单(右上角)。
  3. 点击租户设置
  4. 点击全局设置标签页。
  5. 点击 Log API Keys
  6. 点击 New Log API Key
  7. 输入一个描述性名称(例如,chronicle-log-collector)。
  8. 点击创建
  9. 复制并妥善保存以下值:

    • api_key_id:API 密钥标识符。
    • api_key_secret:API 密钥 Secret。

获取租户环境 FQDN

  1. 登录 PingOne Advanced Identity Cloud 管理控制台。
  2. 点击租户菜单(右上角)。
  3. 点击租户设置
  4. 详细信息下,记下租户名称值。
    • 生产环境格式:openam-<base-name>-<data-region>.id.forgerock.io
    • 开发格式:openam-<base-name>-<data-region>-dev.id.forgerock.io
    • 沙盒格式:openam-<sandbox-name>.forgeblocks.com

测试 API 访问权限

  • 在继续进行集成之前,请先测试您的凭据:

    # Replace with your actual tenant FQDN and credentials
    TENANT_FQDN="openam-mycompany-ew2.id.forgerock.io"
    API_KEY="<your-api-key-id>"
    API_SECRET="<your-api-key-secret>"
    
    # List available log sources
    curl -v \
        -H "x-api-key: ${API_KEY}" \
        -H "x-api-secret: ${API_SECRET}" \
        "https://${TENANT_FQDN}/monitoring/logs/sources?_prettyPrint=true"
    
    # Retrieve recent audit logs
    curl -v \
        -H "x-api-key: ${API_KEY}" \
        -H "x-api-secret: ${API_SECRET}" \
        "https://${TENANT_FQDN}/monitoring/logs?source=am-authentication&_pageSize=5"
    

如果响应成功,则返回 HTTP 200,并附带包含日志条目的 JSON 对象。如果您收到 HTTP 401,请验证 API 密钥和 Secret。如果您收到 HTTP 429,则表示您已超出每分钟 60 个请求的速率限制。

为 Cloud Run 函数创建服务账号

Cloud Run 函数需要一个服务账号,该账号具有向 GCS 存储桶写入内容以及被 Pub/Sub 调用的权限。

创建服务账号

  1. GCP 控制台中,依次前往 IAM 和管理 > 服务账号
  2. 点击创建服务账号
  3. 提供以下配置详细信息:
    • 服务账号名称:输入 forgerock-logs-collector-sa
    • 服务账号说明:输入 Service account for Cloud Run function to collect PingOne Advanced Identity Cloud logs
  4. 点击创建并继续
  5. 向此服务账号授予对项目的访问权限部分中,添加以下角色:
    1. 点击选择角色
    2. 搜索并选择 Storage Object Admin
    3. 点击 + 添加其他角色
    4. 搜索并选择 Cloud Run Invoker
    5. 点击 + 添加其他角色
    6. 搜索并选择 Cloud Functions Invoker
  6. 点击继续
  7. 点击完成

必须拥有这些角色,才能:

  • Storage Object Admin:将日志写入 GCS 存储桶并管理状态文件。
  • Cloud Run Invoker:允许 Pub/Sub 调用该函数。
  • Cloud Functions Invoker:允许调用函数。

授予对 GCS 存储桶的 IAM 权限

向服务账号授予对 GCS 存储桶的写入权限:

  1. 前往 Cloud Storage > 存储分区
  2. 点击您的存储桶名称(例如 forgerock-identity-cloud-logs)。
  3. 前往权限标签页。
  4. 点击授予访问权限
  5. 提供以下配置详细信息:
    • 添加主账号:输入服务账号电子邮件地址(例如 forgerock-logs-collector-sa@PROJECT_ID.iam.gserviceaccount.com
    • 分配角色:选择 Storage Object Admin
  6. 点击保存

创建 Pub/Sub 主题

创建一个 Pub/Sub 主题,Cloud Scheduler 将向该主题发布消息,而 Cloud Run 函数将订阅该主题。

  1. GCP 控制台中,前往 Pub/Sub > 主题
  2. 点击创建主题
  3. 提供以下配置详细信息:
    • 主题 ID:输入 forgerock-logs-trigger
    • 将其他设置保留为默认值
  4. 点击创建

创建 Cloud Run 函数以收集日志

Cloud Run 函数将由来自 Cloud Scheduler 的 Pub/Sub 消息触发,以从 PingOne Advanced Identity Cloud 监控 API 中提取日志并将其写入 GCS。

  1. GCP 控制台中,前往 Cloud Run
  2. 点击创建服务
  3. 选择函数(使用内嵌编辑器创建函数)。
  4. 配置部分中,提供以下配置详细信息:

    设置
    Service 名称 forgerock-logs-collector
    区域 选择与您的 GCS 存储桶匹配的区域(例如 us-central1
    运行时 选择 Python 3.12 或更高版本
  5. 触发器(可选)部分中:

    1. 点击 + 添加触发器
    2. 选择 Cloud Pub/Sub
    3. 选择 Cloud Pub/Sub 主题中,选择 forgerock-logs-trigger
    4. 点击保存
  6. 身份验证部分中:

    1. 选择需要进行身份验证
    2. 检查 Identity and Access Management (IAM)
  7. 向下滚动并展开容器、网络、安全性

  8. 前往安全性标签页:

    • 服务账号:选择 forgerock-logs-collector-sa
  9. 前往容器标签页:

    1. 点击变量和密钥
    2. 为每个环境变量点击+ 添加变量
    变量名称 示例值 说明
    GCS_BUCKET forgerock-identity-cloud-logs GCS 存储桶名称
    GCS_PREFIX forgerock-logs 日志文件的前缀
    STATE_KEY forgerock-logs/state.json 状态文件路径
    TENANT_FQDN openam-mycompany-ew2.id.forgerock.io PingOne AIC 租户环境 FQDN
    API_KEY <your-api-key-id> PingOne AIC 日志 API 密钥 ID
    API_SECRET <your-api-key-secret> PingOne AIC 日志 API 密钥
    LOG_SOURCES am-authentication,am-access,am-activity,am-config,idm-access,idm-activity,idm-authentication,idm-sync 以逗号分隔的日志源
    MAX_RECORDS 5000 每次运行中每个来源的最大记录数
    PAGE_SIZE 1000 每页记录数(最多 1000 条)
    LOOKBACK_HOURS 24 初始回溯期
  10. 变量和 Secret 部分中,向下滚动到请求

    • 请求超时:输入 600 秒(10 分钟)
  11. 前往设置标签页:

    • 资源部分中:
      • 内存:选择 512 MiB 或更高值
      • CPU:选择 1
  12. 修订版本伸缩部分中:

    • 实例数下限:输入 0
    • 实例数上限:输入 100(或根据预期负载进行调整)
  13. 点击创建

  14. 等待服务创建完成(1-2 分钟)。

  15. 创建服务后,系统会自动打开内嵌代码编辑器

添加函数代码

  1. 入口点字段中输入 main
  2. 在内嵌代码编辑器中,创建两个文件:

    • main.py:

      import functions_framework
      from google.cloud import storage
      import json
      import os
      import urllib3
      from datetime import datetime, timezone, timedelta
      import time
      
      # Initialize HTTP client with timeouts
      http = urllib3.PoolManager(
          timeout=urllib3.Timeout(connect=5.0, read=30.0),
          retries=False,
      )
      
      # Initialize Storage client
      storage_client = storage.Client()
      
      # Environment variables
      GCS_BUCKET = os.environ.get('GCS_BUCKET')
      GCS_PREFIX = os.environ.get('GCS_PREFIX', 'forgerock-logs')
      STATE_KEY = os.environ.get('STATE_KEY', 'forgerock-logs/state.json')
      TENANT_FQDN = os.environ.get('TENANT_FQDN')
      API_KEY = os.environ.get('API_KEY')
      API_SECRET = os.environ.get('API_SECRET')
      LOG_SOURCES = os.environ.get('LOG_SOURCES', 'am-authentication,am-access,am-activity,idm-access,idm-activity,idm-authentication')
      MAX_RECORDS = int(os.environ.get('MAX_RECORDS', '5000'))
      PAGE_SIZE = int(os.environ.get('PAGE_SIZE', '1000'))
      LOOKBACK_HOURS = int(os.environ.get('LOOKBACK_HOURS', '24'))
      
      def parse_datetime(value: str) -> datetime:
          """Parse ISO datetime string to datetime object."""
          if value.endswith("Z"):
              value = value[:-1] + "+00:00"
          return datetime.fromisoformat(value)
      
      @functions_framework.cloud_event
      def main(cloud_event):
          """
          Cloud Run function triggered by Pub/Sub to fetch PingOne Advanced Identity Cloud
          logs and write to GCS.
      
          Args:
              cloud_event: CloudEvent object containing Pub/Sub message
          """
      
          if not all([GCS_BUCKET, TENANT_FQDN, API_KEY, API_SECRET]):
              print('Error: Missing required environment variables')
              return
      
          try:
              # Get GCS bucket
              bucket = storage_client.bucket(GCS_BUCKET)
      
              # Load state
              state = load_state(bucket, STATE_KEY)
      
              # Determine time window
              now = datetime.now(timezone.utc)
              last_time = None
      
              if isinstance(state, dict) and state.get("last_event_time"):
                  try:
                      last_time = parse_datetime(state["last_event_time"])
                      # Overlap by 2 minutes to catch any delayed events
                      last_time = last_time - timedelta(minutes=2)
                  except Exception as e:
                      print(f"Warning: Could not parse last_event_time: {e}")
      
              if last_time is None:
                  last_time = now - timedelta(hours=LOOKBACK_HOURS)
      
              print(f"Fetching logs from {last_time.isoformat()} to {now.isoformat()}")
      
              # Fetch logs for configured sources
              all_records = []
              newest_event_time = None
              sources = [s.strip() for s in LOG_SOURCES.split(',') if s.strip()]
      
              for source in sources:
                  records, source_newest_time = fetch_logs(
                      tenant_fqdn=TENANT_FQDN,
                      api_key=API_KEY,
                      api_secret=API_SECRET,
                      source=source,
                      start_time=last_time,
                      end_time=now,
                      page_size=PAGE_SIZE,
                      max_records=MAX_RECORDS,
                  )
                  all_records.extend(records)
      
                  if source_newest_time:
                      if newest_event_time is None or parse_datetime(source_newest_time) > parse_datetime(newest_event_time):
                          newest_event_time = source_newest_time
      
                  print(f"Source '{source}': {len(records)} records")
      
              if not all_records:
                  print("No new log records found.")
                  save_state(bucket, STATE_KEY, now.isoformat())
                  return
      
              # Write to GCS as NDJSON
              timestamp = now.strftime('%Y%m%d_%H%M%S')
              object_key = f"{GCS_PREFIX}/logs_{timestamp}.ndjson"
              blob = bucket.blob(object_key)
      
              ndjson = '\n'.join([json.dumps(record, ensure_ascii=False) for record in all_records]) + '\n'
              blob.upload_from_string(ndjson, content_type='application/x-ndjson')
      
              print(f"Wrote {len(all_records)} records to gs://{GCS_BUCKET}/{object_key}")
      
              # Update state with newest event time
              if newest_event_time:
                  save_state(bucket, STATE_KEY, newest_event_time)
              else:
                  save_state(bucket, STATE_KEY, now.isoformat())
      
              print(f"Successfully processed {len(all_records)} records")
      
          except Exception as e:
              print(f'Error processing logs: {str(e)}')
              raise
      
      def load_state(bucket, key):
          """Load state from GCS."""
          try:
              blob = bucket.blob(key)
              if blob.exists():
                  state_data = blob.download_as_text()
                  return json.loads(state_data)
          except Exception as e:
              print(f"Warning: Could not load state: {e}")
      
          return {}
      
      def save_state(bucket, key, last_event_time_iso: str):
          """Save the last event timestamp to GCS state file."""
          try:
              state = {'last_event_time': last_event_time_iso}
              blob = bucket.blob(key)
              blob.upload_from_string(
                  json.dumps(state, indent=2),
                  content_type='application/json'
              )
              print(f"Saved state: last_event_time={last_event_time_iso}")
          except Exception as e:
              print(f"Warning: Could not save state: {e}")
      
      def fetch_logs(tenant_fqdn: str, api_key: str, api_secret: str, source: str, start_time: datetime, end_time: datetime, page_size: int, max_records: int):
          """
          Fetch logs from PingOne Advanced Identity Cloud Monitoring API with pagination.
      
          Args:
              tenant_fqdn: Tenant environment FQDN
              api_key: Log API key ID
              api_secret: Log API key secret
              source: Log source (am-authentication, am-access, idm-access, etc.)
              start_time: Start time for log query
              end_time: End time for log query
              page_size: Number of records per page (max 1000)
              max_records: Maximum total records to fetch
      
          Returns:
              Tuple of (records list, newest_event_time ISO string)
          """
          endpoint = f"https://{tenant_fqdn}/monitoring/logs"
      
          headers = {
              'x-api-key': api_key,
              'x-api-secret': api_secret,
              'Accept': 'application/json',
              'User-Agent': 'GoogleSecOps-ForgeRockCollector/1.0'
          }
      
          records = []
          newest_time = None
          page_num = 0
          backoff = 1.0
      
          begin_time = start_time.strftime('%Y-%m-%dT%H:%M:%SZ')
          end_time_str = end_time.strftime('%Y-%m-%dT%H:%M:%SZ')
          paged_results_cookie = None
      
          while True:
              page_num += 1
      
              if len(records) >= max_records:
                  print(f"Reached max_records limit ({max_records})")
                  break
      
              current_limit = min(page_size, max_records - len(records))
              url = f"{endpoint}?source={source}&beginTime={begin_time}&endTime={end_time_str}&_pageSize={current_limit}"
      
              if paged_results_cookie:
                  url += f"&_pagedResultsCookie={paged_results_cookie}"
      
              try:
                  response = http.request('GET', url, headers=headers)
      
                  # Handle rate limiting with exponential backoff
                  if response.status == 429:
                      retry_after = int(response.headers.get('Retry-After', str(int(backoff))))
                      print(f"Rate limited (429). Retrying after {retry_after}s...")
                      time.sleep(retry_after)
                      backoff = min(backoff * 2, 30.0)
                      continue
      
                  backoff = 1.0
      
                  if response.status != 200:
                      print(f"HTTP Error: {response.status}")
                      response_text = response.data.decode('utf-8')
                      print(f"Response body: {response_text}")
                      return [], None
      
                  data = json.loads(response.data.decode('utf-8'))
      
                  page_results = data.get('result', [])
      
                  if not page_results:
                      print(f"No more results (empty page)")
                      break
      
                  print(f"Page {page_num}: Retrieved {len(page_results)} events")
                  records.extend(page_results)
      
                  # Track newest event time
                  for event in page_results:
                      try:
                          event_time = event.get('timestamp')
                          if event_time:
                              if newest_time is None or parse_datetime(event_time) > parse_datetime(newest_time):
                                  newest_time = event_time
                      except Exception as e:
                          print(f"Warning: Could not parse event time: {e}")
      
                  # Check for more results
                  paged_results_cookie = data.get('pagedResultsCookie')
                  if not paged_results_cookie or paged_results_cookie == "-1":
                      print(f"Reached last page (no more results)")
                      break
      
              except Exception as e:
                  print(f"Error fetching logs: {e}")
                  return [], None
      
          print(f"Retrieved {len(records)} total records from {page_num} pages")
          return records, newest_time
      
    • requirements.txt:

      functions-framework==3.*
      google-cloud-storage==2.*
      urllib3>=2.0.0
      
  3. 点击部署以保存并部署该函数。

  4. 等待部署完成(2-3 分钟)。

创建 Cloud Scheduler 作业

Cloud Scheduler 会定期向 Pub/Sub 主题发布消息,从而触发 Cloud Run 函数。

  1. GCP Console 中,前往 Cloud Scheduler
  2. 点击创建作业
  3. 提供以下配置详细信息:

    设置
    名称 forgerock-logs-collector-hourly
    区域 选择与 Cloud Run 函数相同的区域
    频率 0 * * * *(每小时一次,整点时)
    时区 选择时区(建议选择 UTC)
    目标类型 Pub/Sub
    主题 选择forgerock-logs-trigger
    消息正文 {}(空 JSON 对象)
  4. 点击创建

时间表频率选项

根据日志量和延迟时间要求选择频次:

频率 Cron 表达式 使用场景
每隔 5 分钟 */5 * * * * 大批量、低延迟
每隔 15 分钟 */15 * * * * 搜索量中等
每小时 0 * * * * 标准(推荐)
每 6 小时 0 */6 * * * 低成交量、批处理
每天 0 0 * * * 历史数据收集

测试集成

  1. Cloud Scheduler 控制台中,找到您的作业 (forgerock-logs-collector-hourly)。
  2. 点击强制运行以手动触发作业。
  3. 等待几秒钟。
  4. 前往 Cloud Run > 服务
  5. 点击 forgerock-logs-collector
  6. 点击日志标签页。
  7. 验证函数是否已成功执行。查找:

    Fetching logs from YYYY-MM-DDTHH:MM:SS+00:00 to YYYY-MM-DDTHH:MM:SS+00:00
    Source 'am-authentication': X records
    Source 'am-access': X records
    Wrote X records to gs://forgerock-identity-cloud-logs/forgerock-logs/logs_YYYYMMDD_HHMMSS.ndjson
    Successfully processed X records
    
  8. 前往 Cloud Storage > 存储分区

  9. 点击您的存储桶名称 (forgerock-identity-cloud-logs)。

  10. 转到 forgerock-logs/ 文件夹。

  11. 验证是否已创建具有当前时间戳的新 .ndjson 文件。

如果您在日志中看到错误,请执行以下操作:

  • HTTP 401:检查环境变量中的 Log API 密钥和 Secret。
  • HTTP 403:验证 API 密钥是否已在 PingOne Advanced Identity Cloud 中被撤消。
  • HTTP 429:速率限制(每个环境每分钟 60 个请求)- 函数将自动重试并进行退避。
  • 缺少环境变量:检查是否已设置所有必需的变量。

检索 Google SecOps 服务账号

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

获取服务账号电子邮件地址

  1. 依次前往 SIEM 设置 > Feed
  2. 点击添加新 Feed
  3. 点击配置单个 Feed
  4. Feed 名称字段中,输入 Feed 的名称(例如 ForgeRock Identity Cloud Logs)。
  5. 选择 Google Cloud Storage V2 作为来源类型
  6. 选择 ForgeRock Identity Cloud 作为日志类型
  7. 点击获取服务账号。系统会显示一个唯一的服务账号电子邮件地址,例如:

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  8. 复制此电子邮件地址,以便在下一步中使用。

  9. 点击下一步

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

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

      gs://forgerock-identity-cloud-logs/forgerock-logs/
      
    • 来源删除选项:根据您的偏好选择删除选项:

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

    • 资产命名空间资产命名空间

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

  11. 点击下一步

  12. 最终确定界面中查看新的 Feed 配置,然后点击提交

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

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

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

UDM 映射表

日志字段 UDM 映射 逻辑
aav_label additional.fields 已合并
detail_label additional.fields 已合并
id_label additional.fields 已合并
objectId_label additional.fields 已合并
secure_label additional.fields 已合并
source_label additional.fields 已合并
topic_label additional.fields 已合并
trackingId_list additional.fields 已合并
transactionId_label additional.fields 已合并
extensions extensions 已重命名/已映射
metadata metadata 已重命名/已映射
payload.eventName metadata.product_event_type 直接映射
network network 已重命名/已映射
x-forwarded-proto network.application_protocol 直接映射
payload.http.request.method network.http.method 直接映射
value network.http.response_code 已重命名/已映射
user-agent network.http.user_agent 直接映射
principal principal 已重命名/已映射
host principal.asset.hostname 直接映射
payload.client.ip principal.asset.ip 已合并
xip principal.asset.ip 已合并
host principal.hostname 直接映射
entry.info.ipAddress principal.ip 已合并
payload.client.ip principal.ip 已合并
xip principal.ip 已合并
payload.client.port principal.port 已重命名/已映射
user_distinguished_name principal.user.attribute.labels 已合并
payload.userId principal.user.userid 直接映射
userId principal.user.userid 直接映射
Security_Result security_result 已合并
target target 已重命名/已映射
payload.applicationPrincipal.0 target.application 直接映射
app_label target.resource.attribute.labels 已合并
realm_label target.resource.attribute.labels 已合并
payload.component target.resource.name 直接映射
payload.http.request.path target.url 直接映射
不适用 additional.fields 常量:topic_label
不适用 extensions.auth.type 常量:AUTHTYPE_UNSPECIFIED
不适用 metadata.event_type 常量:USER_LOGIN
不适用 principal.asset.ip 常量:payload.client.ip
不适用 principal.ip 常量:payload.client.ip
不适用 principal.user.attribute.labels 常量:user_distinguished_name
不适用 security_result 常量:Security_Result
不适用 target.resource.attribute.labels 常量:app_label
source_cloud event.idm.read_only_udm.additional.fields 从变更日志映射
type event.idm.read_only_udm.additional.fields 从变更日志映射
entry_info_nodeExtraLogging_auditInfo_Timestamp event.idm.read_only_udm.additional.fields 从变更日志映射
entry_info_nodeOutcome event.idm.read_only_udm.additional.fields 从变更日志映射
entry_info_authLevel event.idm.read_only_udm.additional.fields 从变更日志映射
entry_info_nodeExtraLogging_auditInfo_clientId event.idm.read_only_udm.principal.application 从变更日志映射
entry_info_nodeExtraLogging_auditInfo_EventName event.idm.read_only_udm.security_result.detection_fields 从变更日志映射
entry_info_nodeExtraLogging_auditInfo_FlowType event.idm.read_only_udm.security_result.detection_fields 从变更日志映射
entry_info_displayName event.idm.read_only_udm.security_result.detection_fields 从变更日志映射
entry_info_nodeType event.idm.read_only_udm.security_result.detection_fields 从变更日志映射
entry_info_nodeExtraLogging_auditInfo_Status event.idm.read_only_udm.security_result.action 从变更日志映射
entry_info_nodeExtraLogging_auditInfo_TransactionId event.idm.read_only_udm.metadata.product_log_id 从变更日志映射
entry_info_nodeId event.idm.read_only_udm.principal.user.userid 从变更日志映射
entry_info_treeName event.idm.read_only_udm.security_result.description 从变更日志映射
tenant_url event.idm.read_only_udm.principal.url 从变更日志映射
payload.client.ip event.idm.read_only_udm.principal.ipevent.idm.read_only_udm.principal.asset.ip之间 从变更日志映射
payload.http.request.headers.x-forwarded-for event.idm.read_only_udm.principal.ipevent.idm.read_only_udm.principal.asset.ip之间 从变更日志映射
payload.client.port event.idm.read_only_udm.principal.port 从变更日志映射
payload.http.request.method event.idm.read_only_udm.network.http.request.method 从变更日志映射
payload.http.request.path event.idm.read_only_udm.target.url 从变更日志映射
payload.topic event.idm.read_only_udm.additional.fields 从变更日志映射
payload.http.request.headers.accept-api-version event.idm.read_only_udm.additional.fields 从变更日志映射
payload.http.request.secure event.idm.read_only_udm.additional.fields 从变更日志映射
payload.request.detail event.idm.read_only_udm.additional.fields 从变更日志映射
payload.response event.idm.read_only_udm.additional.fields 从变更日志映射
payload.request event.idm.read_only_udm.additional.fields 从变更日志映射
payload.trackingIds event.idm.read_only_udm.additional.fields 从变更日志映射
payload.objectId event.idm.read_only_udm.additional.fields 从变更日志映射
payload.http.request.headers.user-agent event.idm.read_only_udm.network.http.user_agent 从变更日志映射
payload.http.request.headers.host event.idm.read_only_udm.principal.hostnameevent.idm.read_only_udm.principal.asset.hostname之间 从变更日志映射
payload.http.request.headers.x-forwarded-proto event.idm.read_only_udm.network.application_protocol 从变更日志映射
payload.response.statusCode event.idm.read_only_udm.network.http.response_code 从变更日志映射
payload.operation event.idm.read_only_udm.security_result.action_details 从变更日志映射

更新日志

查看相应解析器的更改日志

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