收集 Salesforce Commerce Cloud 日志

支持的平台:

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

Salesforce Commerce Cloud 是一个电子商务平台,可生成交易、访问和安全审核日志。Cloud Run 函数会按计划连接到 Salesforce Commerce Cloud WebDAV 端点,下载日志文件,以 NDJSON 格式将其写入 GCS 存储桶,然后 Google SecOps 会通过 GCS V2 Feed 提取这些日志文件。

准备工作

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

  • Google SecOps 实例
  • 已启用 Cloud Storage API 的 GCP 项目
  • 创建和管理 GCS 存储分区的权限
  • 管理 GCS 存储分区的 IAM 政策的权限
  • 创建 Cloud Run 服务、Pub/Sub 主题和 Cloud Scheduler 作业的权限
  • 对 Salesforce Commerce Cloud 商家管理工具拥有 WebDAV 访问权限的特权访问权限

创建 Google Cloud Storage 存储桶

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

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

收集 Salesforce Commerce Cloud 凭据

配置 WebDAV 访问权限

  1. 登录 Salesforce Commerce Cloud 实例的商家管理工具
  2. 依次前往管理 > 组织 > 角色和权限
  3. 验证您的用户账号是否已启用 WebDAV 文件访问权限。
  4. 记下您的 SFCC 实例主机名(例如 development-yoursite-dw.demandware.net)。
  5. 将以下凭据保存在安全的位置:

    • SFCC 主机:您的实例主机名(例如 development-yoursite-dw.demandware.net)。
    • 用户名:您的商家管理工具用户名。
    • 密码:您的商家管理工具密码。

验证权限

如需验证账号是否具有所需权限,请执行以下操作:

  1. 登录 Salesforce Commerce Cloud 实例的商家管理工具
  2. 依次前往管理 > 网站开发 > 开发设置
  3. 点击 WebDAV 部分下的 Log Files
  4. 如果您能看到日志文件目录,则表示您拥有所需的权限。
  5. 如果您看不到此选项,请与 SFCC 管理员联系,以获取 WebDAV 访问权限。

测试 API 访问权限

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

    # Replace with your actual credentials
    SFCC_HOST="development-yoursite-dw.demandware.net"
    USERNAME="your-username"
    PASSWORD="your-password"
    
    # Test WebDAV access to log directory
    curl -v -u "${USERNAME}:${PASSWORD}" \
      "https://${SFCC_HOST}/on/demandware.servlet/webdav/Sites/Logs/"
    

为 Cloud Run 函数创建服务账号

Cloud Run 函数需要一个服务账号,该账号具有写入 GCS 存储桶的权限,并且可以由 Pub/Sub 调用。

创建服务账号

  1. GCP 控制台中,依次前往 IAM 和管理 > 服务账号
  2. 点击创建服务账号
  3. 提供以下配置详细信息:
    • 服务账号名称:输入 sfcc-logs-collector-sa
    • 服务账号说明:输入 Service account for Cloud Run function to collect Salesforce Commerce 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. 点击您的存储桶名称(例如 sfcc-logs)。
  3. 前往权限标签页。
  4. 点击授予访问权限
  5. 提供以下配置详细信息:
    • 添加主账号:输入服务账号电子邮件地址(例如 sfcc-logs-collector-sa@your-project.iam.gserviceaccount.com)。
    • 分配角色:选择 Storage Object Admin
  6. 点击保存

创建 Pub/Sub 主题

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

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

创建 Cloud Run 函数以收集日志

Cloud Run 函数将由 Cloud Scheduler 中的 Pub/Sub 消息触发,以从 Salesforce Commerce Cloud WebDAV 中提取日志并将其写入 GCS。

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

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

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

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

  8. 前往安全性标签页:

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

    1. 点击变量和密钥
    2. 为每个环境变量点击+ 添加变量
    变量名称 示例值 说明
    GCS_BUCKET sfcc-logs GCS 存储桶名称
    GCS_PREFIX sfcc 日志文件的前缀
    STATE_KEY sfcc/state.json 状态文件路径
    SFCC_HOST development-yoursite-dw.demandware.net SFCC 实例主机名
    SFCC_USERNAME your-username 商家管理工具用户名
    SFCC_PASSWORD your-password 商家管理工具密码
    LOG_DIRS security,error,warn,customerror 以逗号分隔的日志目录
    LOOKBACK_HOURS 24 初始回溯期
  10. 变量和密钥标签页中,向下滚动到请求

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

    • 资源部分中:
      • 内存:选择 512 MiB 或更高值。
      • CPU:选择 1
    • 点击完成
  12. 向下滚动到执行环境

    • 选择默认(推荐)。
  13. 修订版本伸缩部分中:

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

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

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

添加函数代码

  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
      import base64
      import re
      
      # Initialize HTTP client with timeouts
      http = urllib3.PoolManager(
        timeout=urllib3.Timeout(connect=10.0, read=60.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', 'sfcc')
      STATE_KEY = os.environ.get('STATE_KEY', 'sfcc/state.json')
      SFCC_HOST = os.environ.get('SFCC_HOST')
      SFCC_USERNAME = os.environ.get('SFCC_USERNAME')
      SFCC_PASSWORD = os.environ.get('SFCC_PASSWORD')
      LOG_DIRS = [d.strip() for d in os.environ.get('LOG_DIRS', 'security,error,warn,customerror').split(',') if d.strip()]
      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 Salesforce Commerce Cloud
        logs via WebDAV and write to GCS.
      
        Args:
          cloud_event: CloudEvent object containing Pub/Sub message
        """
      
        if not all([GCS_BUCKET, SFCC_HOST, SFCC_USERNAME, SFCC_PASSWORD]):
          print('Error: Missing required environment variables')
          return
      
        try:
          bucket = storage_client.bucket(GCS_BUCKET)
      
          # Load state
          state = load_state(bucket, STATE_KEY)
      
          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"])
            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 since {last_time.isoformat()}")
      
          # Build auth header
          credentials = f"{SFCC_USERNAME}:{SFCC_PASSWORD}"
          encoded_credentials = base64.b64encode(credentials.encode('utf-8')).decode('utf-8')
          headers = {
            'Authorization': f'Basic {encoded_credentials}',
            'User-Agent': 'GoogleSecOps-SFCCCollector/1.0'
          }
      
          total_files = 0
          webdav_base = f"https://{SFCC_HOST}/on/demandware.servlet/webdav/Sites/Logs"
      
          for log_dir in LOG_DIRS:
            print(f"Processing log directory: {log_dir}")
            files_processed = fetch_and_upload_logs(
              bucket=bucket,
              webdav_base=webdav_base,
              log_dir=log_dir,
              headers=headers,
              since=last_time,
              now=now,
            )
            total_files += files_processed
      
          if total_files == 0:
            print("No new log files found.")
          else:
            print(f"Successfully processed {total_files} log files")
      
          save_state(bucket, STATE_KEY, now.isoformat())
      
        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 list_webdav_files(webdav_url: str, headers: dict):
        """List files in a WebDAV directory using PROPFIND."""
        backoff = 1.0
        max_retries = 3
      
        for attempt in range(max_retries):
          response = http.request('PROPFIND', webdav_url, headers={**headers, 'Depth': '1'})
      
          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
      
          if response.status not in (200, 207):
            print(f"HTTP Error listing {webdav_url}: {response.status}")
            return []
      
          content = response.data.decode('utf-8')
          # Parse file names from WebDAV PROPFIND XML response
          files = re.findall(r'<D:href>([^<]+)</D:href>', content)
          return [f for f in files if not f.endswith('/')]
      
        return []
      
      def fetch_and_upload_logs(bucket, webdav_base: str, log_dir: str, headers: dict, since: datetime, now: datetime):
        """
        Fetch log files from a WebDAV directory and upload to GCS.
      
        Args:
          bucket: GCS bucket object
          webdav_base: WebDAV base URL
          log_dir: Log directory name
          headers: HTTP headers with auth
          since: Only process files newer than this
          now: Current time for file naming
      
        Returns:
          Number of files processed
        """
        dir_url = f"{webdav_base}/{log_dir}/"
        files = list_webdav_files(dir_url, headers)
        files_processed = 0
        backoff = 1.0
      
        for file_path in files:
          file_name = file_path.split('/')[-1]
          if not file_name:
            continue
      
          # Download file
          file_url = f"https://{SFCC_HOST}{file_path}"
      
          response = http.request('GET', file_url, headers=headers)
      
          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)
            response = http.request('GET', file_url, headers=headers)
      
          if response.status != 200:
            print(f"Error downloading {file_name}: {response.status}")
            continue
      
          backoff = 1.0
          content = response.data
      
          if not content:
            continue
      
          # Upload to GCS
          timestamp = now.strftime('%Y%m%d_%H%M%S')
          object_key = f"{GCS_PREFIX}/{log_dir}/{file_name}_{timestamp}"
          blob = bucket.blob(object_key)
      
          # Convert log lines to NDJSON
          lines = content.decode('utf-8', errors='replace').splitlines()
          records = []
          for line in lines:
            line = line.strip()
            if line:
              try:
                record = json.loads(line)
              except json.JSONDecodeError:
                record = {'raw_log': line, 'log_dir': log_dir, 'source_file': file_name}
              records.append(record)
      
          if records:
            ndjson = '\n'.join([json.dumps(r, ensure_ascii=False) for r in records]) + '\n'
            blob.upload_from_string(ndjson, content_type='application/x-ndjson')
            print(f"Uploaded {len(records)} records from {file_name} to gs://{GCS_BUCKET}/{object_key}")
            files_processed += 1
      
        return files_processed
      
    • 第二个文件 - 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. 提供以下配置详细信息:

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

时间表频率选项

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

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

测试集成

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

    Fetching logs since YYYY-MM-DDTHH:MM:SS+00:00
    Processing log directory: security
    Uploaded X records from filename.log to gs://sfcc-logs/sfcc/security/filename.log_YYYYMMDD_HHMMSS
    Successfully processed X log files
    
  5. 检查 GCS 存储桶 (sfcc-logs) 以确认日志是否已写入。

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

  • HTTP 401:检查环境变量中的 SFCC 凭据
  • HTTP 403:验证账号在商家管理工具中是否具有 WebDAV 文件访问权限
  • HTTP 429:速率限制 - 函数将自动重试并进行退避
  • 缺少环境变量:检查是否已设置所有必需的变量

在 Google SecOps 中配置 Feed 以注入 Salesforce Commerce Cloud 日志

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

    chronicle-12345678@chronicle-gcp-prod.iam.gserviceaccount.com
    
  8. 复制此电子邮件地址。您将在下一步骤中用到它。

  9. 点击下一步

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

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

      gs://sfcc-logs/sfcc/
      
      • 替换:
        • sfcc-logs:您的 GCS 存储桶名称。
        • sfcc/:存储日志的前缀/文件夹路径。
    • 来源删除选项:根据您的偏好选择删除选项:

      • 永不:转移后永不删除任何文件(建议用于测试)。
      • 删除已转移的文件:在成功转移后删除文件。
      • 删除已转移的文件和空目录:成功转移后删除文件和空目录。

    • 文件存在时间上限:包含在过去指定天数内修改的文件(默认值为 180 天)。

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

    • 提取标签:要应用于相应 Feed 中事件的标签。

  11. 点击下一步

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

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

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

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

UDM 映射表

日志字段 UDM 映射 逻辑
auth.mechanism extensions.auth.mechanism 已合并
csv_format extensions.auth.mechanism 已映射:falseauth.mechanism
event_id extensions.auth.mechanism 已映射:Login: Successauth.mechanism
mechanism extensions.auth.mechanism 已合并
LoginType extensions.auth.type 已映射:ApplicationAUTHTYPE_UNSPECIFIED
csv_format extensions.auth.type 已映射:falseAUTHTYPE_UNSPECIFIED
event_id extensions.auth.type 映射的值(共 6 个,例如“Login”“LoginAsEvent”“IdentityVerificationEvent”“LoginE...
eventType.name metadata.description 直接映射
metadata_description metadata.description 直接映射
collected_timestamp metadata.event_timestamp 解析为 yyyyMMddHHmmss
createdAt metadata.event_timestamp 解析为 UNIX_MS
createdDate metadata.event_timestamp 解析为 yyyy-MM-ddTHH:mm:ss.SSS
timestamp metadata.event_timestamp 解析为 yyyyMMddHHmmss
ts_date metadata.event_timestamp 解析为 yyyy-MM-dd HH:mm:ss.SSSZ
csv_format metadata.event_type 映射:falseUSER_LOGINfalseUSER_LOGOUTfalse → `USER_RESOURCE_UPDATE_CON...
event_id metadata.event_type 映射:Login: SuccessUSER_LOGINLogoutUSER_LOGOUT
event_type metadata.event_type 直接映射
label metadata.ingestion_labels 已合并
resource_name metadata.ingestion_labels 已映射:`"ReportEvent","SessionHijackingEventStore","BulkApiResultEventStore","CredentialStu...
attrs.cat metadata.product_event_type 已重命名/已映射
eventType.id metadata.product_event_type 直接映射
event_id metadata.product_event_type 直接映射
event_identifier metadata.product_log_id 直接映射
id metadata.product_log_id 直接映射
protocol network.application_protocol 直接映射
transaction_id network.dhcp.transaction_id 直接映射
referral_url network.http.referral_url 直接映射
request_status network.http.response_code 直接映射
attrs.Application principal.application 已重命名/已映射
enterpriseId principal.group.product_object_id 直接映射
attrs.src principal.ip 已合并
csv_format principal.ip 已映射:falseattrs.src
event_id principal.ip 已映射:Login: Successattrs.src
Status_LK principal.labels 已合并
Status_LK principal.resource.attribute.labels 已合并
browser_name principal.resource.name 直接映射
memberId principal.resource.product_object_id 直接映射
principal_resource_type principal.resource.type 直接映射
attrs.usrName principal.user.email_addresses 已合并
csv_format principal.user.email_addresses 已映射:falseattrs.usrName
src_email principal.user.email_addresses 已合并
attrs.USER_ID_DERIVED principal.user.product_object_id 已重命名/已映射
employee.employeeName principal.user.user_display_name 直接映射
user_display_name principal.user.user_display_name 直接映射
attrs.usrName principal.user.userid 直接映射
employee.userName principal.user.userid 直接映射
login_key principal.user.userid 直接映射
user_id principal.user.userid 直接映射
csv_format security_result 已映射:falsesec_result
event_id security_result 已映射:Login: Successsec_result
sec_result security_result 已合并
sr security_result 已合并
action security_result.action 已合并
eventSource.name src.resource.name 直接映射
eventSource.id src.resource.product_object_id 直接映射
organization_id target.administrative_domain 直接映射
target_hostname target.asset.hostname 直接映射
device_id target.asset_id 直接映射
target_hostname target.hostname 直接映射
call_time target.resource.attribute.labels 已合并
cpu target.resource.attribute.labels 已合并
db_cpu target.resource.attribute.labels 已合并
db_type target.resource.attribute.labels 已合并
duration_time target.resource.attribute.labels 已合并
entry_p target.resource.attribute.labels 已合并
exe_time target.resource.attribute.labels 已合并
no_sql_que target.resource.attribute.labels 已合并
ope target.resource.attribute.labels 已合并
rows_proc target.resource.attribute.labels 已合并
run target.resource.attribute.labels 已合并
ses_level target.resource.attribute.labels 已合并
ss_type target.resource.attribute.labels 已合并
total_time target.resource.attribute.labels 已合并
user_ty target.resource.attribute.labels 已合并
verify_method target.resource.attribute.labels 已合并
attrs.AccountId target.resource.id 已重命名/已映射
attrs.CaseId target.resource.id 已重命名/已映射
attrs.ContactId target.resource.id 已重命名/已映射
eventSource.id target.resource.id 直接映射
request_id target.resource.id 直接映射
eventSource.name target.resource.name 直接映射
object.name target.resource.name 直接映射
resource_name target.resource.name 直接映射
object.id target.resource.product_object_id 直接映射
event_id target.resource.resource_type 映射:PlatformEncryptionACCESS_POLICYApexCalloutACCESS_POLICY、`ApexTrigge...
target_resource_type target.resource.resource_type 直接映射
event_id target.resource.type 已映射:(QueuedExecution/ApexExecution)BATCHApexTriggerDATABASE_TRIGGER、`Co...
attrs.LoginUrl target.url 已重命名/已映射
attrs.attributes.url target.url 已重命名/已映射
uri target.url 直接映射
attrs.usrName target.user.email_addresses 已合并
csv_format target.user.email_addresses 已映射:falseattrs.usrName
event_id target.user.email_addresses 已映射:Logoutattrs.usrName
target_user_display_name target.user.user_display_name 直接映射
target_user_name target.user.userid 直接映射
不适用 extensions.auth.auth_details 常量:ACTIVE
不适用 extensions.auth.type 常量:SSO
不适用 metadata.event_type 常量:GENERIC_EVENT
不适用 metadata.product_name 常量:SALESFORCE
不适用 metadata.vendor_name 常量:SALESFORCE
不适用 target.resource.resource_type 常量:ACCESS_POLICY
不适用 target.resource.type 常量:BATCH

更新日志

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

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