Help us learn about your current experience with the documentation. Take the survey.

Service Ping 开发指南

Service Ping 是一个 GitLab 进程,用于收集并发送每周的数据包给 GitLab。 该数据包提供了重要的高层级数据,帮助我们的产品、支持和销售团队了解 GitLab 的使用情况。这些数据有助于:

  • 按月(或周)对比计数,大致了解实例如何使用不同的产品功能。
  • 收集其他事实,帮助我们分类和理解 GitLab 安装。
  • 计算我们各阶段的月活跃用户数(SMAU),这有助于衡量我们各阶段和功能的成功度。

Service Ping 信息不是匿名的。它与实例的主机名相关联,但不包含项目名称、用户名或任何其他特定数据。

Service Ping 默认启用。但是,您可以在任何 GitLab 自托管实例上禁用某些指标。当 Service Ping 启用时,GitLab 会收集来自其他实例的数据,并向您的用户显示您实例的使用统计信息。

Service Ping 术语

我们使用以下术语来描述 Service Ping 组件:

  • Service Ping:收集并生成 JSON 数据包的进程。
  • Service Data:Service Ping JSON 数据包的内容。这包括指标。
  • Metrics:主要由实例数据库中不同表的行数组成。每个指标在 YAML 文件中都有相应的指标定义
  • MAU:月活跃用户。
  • WAU:周活跃用户。

已知问题

  • Service Ping 只传递指标,不传递单个事件。
  • 指标必须在代码库中存在并已实现,才能在相应版本的 Service Pings 中传递该版本的 GitLab。

Service Ping 请求流程

以下示例展示了 GitLab 实例、版本应用、许可应用、Salesforce、GitLab GCP 存储桶、GitLab Snowflake 数据仓库和 Tableau 之间的基本请求/响应流程:

sequenceDiagram
    participant GitLab Instance
    participant Versions Application
    participant Licenses Application
    participant Salesforce
    participant GCP Bucket
    participant Snowflake DW
    participant Tableau Dashboards
    GitLab Instance->>Versions Application: Send Service Ping
    loop Process usage data
        Versions Application->>Versions Application: Parse usage data
        Versions Application->>Versions Application: Write to database
        Versions Application->>Versions Application: Update license ping time
    end
    loop Process data for Salesforce
        Versions Application-xLicenses Application: Request Zuora subscription id
        Licenses Application-xVersions Application: Zuora subscription id
        Versions Application-xSalesforce: Request Zuora account id  by Zuora subscription id
        Salesforce-xVersions Application: Zuora account id
        Versions Application-xSalesforce: Usage data for the Zuora account
    end
    Versions Application->>GCP Bucket: Export Versions database
    GCP Bucket->>Snowflake DW: Import data
    Snowflake DW->>Snowflake DW: Transform data using dbt
    Snowflake DW->>Tableau Dashboards: Data available for querying
    Versions Application->>GitLab Instance: DevOps Score (Conversational Development Index)

Service Ping 工作原理

  1. Service Ping 的 cron job 在 Sidekiq 中设置为每周运行。

  2. 当 cron job 运行时,它会调用 Gitlab::Usage::ServicePingReport.for(output: :all_metrics_values)

  3. Gitlab::Usage::ServicePingReport.for(output: :all_metrics_values) 向下级联到约 400+ 个其他计数器方法调用。

  4. 所有方法调用的响应被合并在一起成一个 JSON 数据包。

  5. 然后 JSON 数据包被发布到版本应用 如果需要防火墙例外,所需的 URL 取决于几个因素。如果主机名是 version.gitlab.com,协议是 TCP,端口号是 443,则所需的 URL 是 https://version.gitlab.com/

  6. 如果发生错误,它将与以下信息一起报告给版本应用:

    • uuid - GitLab 实例唯一标识符

    • hostname - GitLab 实例主机名

    • version - GitLab 实例当前版本

    • elapsed - 从 Service Ping 报告进程开始到错误发生时刻所经过的时间

    • message - 错误消息

      {
        "uuid"=>"02333324-1cd7-4c3b-a45b-a4993f05fb1d",
        "hostname"=>"127.0.0.1",
        "version"=>"14.7.0-pre",
        "elapsed"=>0.006946,
        "message"=>'PG::UndefinedColumn: ERROR:  column \"non_existent_attribute\" does not exist\nLINE 1: SELECT COUNT(non_existent_attribute) FROM \"issues\" /*applica...'
      }
  7. 最后,用于诊断目的的时序元数据信息被提交到版本应用。它由指标标识符列表和计算这些指标所需的时间组成:

    {
      "metadata"=>
      {
        "uuid"=>"0000000-0000-0000-0000-000000000000",
        "metrics"=>
        [{"name"=>"version", "time_elapsed"=>1.1811964213848114e-05},
         {"name"=>"installation_type", "time_elapsed"=>0.00017242692410945892},
         {"name"=>"license_billable_users", "time_elapsed"=>0.009520471096038818},
         ....
         {"name"=>"counts.clusters_platforms_eks",
          "time_elapsed"=>0.05638605775311589},
         {"name"=>"counts.clusters_platforms_gke",
          "time_elapsed"=>0.40995341585949063},
         {"name"=>"counts.clusters_platforms_user",
          "time_elapsed"=>0.06410990096628666},
         {"name"=>"counts.clusters_management_project",
          "time_elapsed"=>0.24020783510059118}
        ]
      }
    }

在 Geo 从站点上

我们还收集与 Geo 从站点相关的特定指标,通过 Service Ping 发送。

  1. Geo 从站点 service ping cron job 在 Sidekiq 中设置为每周运行。

  2. 当 cron job 运行时,它会调用 SecondaryUsageData.update_metrics!。这会从 Prometheus 收集相关指标,并将数据存储在 Geo 从站点跟踪数据库中,以便在 Geo 节点状态更新期间传输到主站点。

  3. Geo 节点状态数据与上述过程中的 JSON 数据包一起发送。以下是数据包示例,其中数组中的每个对象代表一个 Geo 节点:

    [
      {
        "git_fetch_event_count_weekly"=>nil,
        "git_push_event_count_weekly"=>nil,
        ... other geo node status fields
      }
    ]

Service Ping 数据包示例

以下是 Service Ping 数据包的示例内容。

{
  "uuid": "0000000-0000-0000-0000-000000000000",
  "hostname": "example.com",
  "version": "12.10.0-pre",
  "installation_type": "omnibus-gitlab",
  "active_user_count": 999,
  "recorded_at": "2020-04-17T07:43:54.162+00:00",
  "edition": "EEU",
  "license_md5": "00000000000000000000000000000000",
  "license_sha256": "0000000000000000000000000000000000000000000000000000000000000000",
  "license_id": null,
  "historical_max_users": 999,
  "licensee": {
    "Name": "ABC, Inc.",
    "Email": "email@example.com",
    "Company": "ABC, Inc."
  },
  "license_user_count": 999,
  "license_starts_at": "2020-01-01",
  "license_expires_at": "2021-01-01",
  "license_plan": "ultimate",
  "license_add_ons": {
  },
  "license_trial": false,
  "counts": {
    "assignee_lists": 999,
    "boards": 999,
    "ci_builds": 999,
    ...
  },
  "container_registry_enabled": true,
  "dependency_proxy_enabled": false,
  "gitlab_shared_runners_enabled": true,
  "gravatar_enabled": true,
  "influxdb_metrics_enabled": true,
  "ldap_enabled": false,
  "mattermost_enabled": false,
  "omniauth_enabled": true,
  "prometheus_enabled": false,
  "prometheus_metrics_enabled": false,
  "reply_by_email_enabled": "incoming+%{key}@incoming.gitlab.com",
  "signup_enabled": true,
  "projects_with_expiration_policy_disabled": 999,
  "projects_with_expiration_policy_enabled": 999,
  ...
  "elasticsearch_enabled": true,
  "license_trial_ends_on": null,
  "geo_enabled": false,
  "git": {
    "version": {
      "major": 2,
      "minor": 26,
      "patch": 1
    }
  },
  "gitaly": {
    "version": "12.10.0-rc1-93-g40980d40",
    "servers": 56,
    "clusters": 14,
    "filesystems": [
      "EXT_2_3_4"
    ]
  },
  "gitlab_pages": {
    "enabled": true,
    "version": "1.17.0"
  },
  "container_registry_server": {
    "vendor": "gitlab",
    "version": "2.9.1-gitlab",
    "db_enabled": false
  },
  "database": {
    "adapter": "postgresql",
    "version": "9.6.15",
    "pg_system_id": 6842684531675334351,
    "flavor": "Cloud SQL for PostgreSQL"
  },
  "analytics_unique_visits": {
    "g_analytics_contribution": 999,
    ...
  },
  "usage_activity_by_stage": {
    "configure": {
      "project_clusters_enabled": 999,
      ...
    },
    "create": {
      "merge_requests": 999,
      ...
    },
    "manage": {
      "events": 999,
      ...
    },
    "monitor": {
      "clusters": 999,
      ...
    },
    "package": {
      "projects_with_packages": 999
    },
    "plan": {
      "issues": 999,
      ...
    },
    "release": {
      "deployments": 999,
      ...
    },
    "secure": {
      "user_container_scanning_jobs": 999,
      ...
    },
    "verify": {
      "ci_builds": 999,
      ...
    }
  },
  "usage_activity_by_stage_monthly": {
    "configure": {
      "project_clusters_enabled": 999,
      ...
    },
    "create": {
      "merge_requests": 999,
      ...
    },
    "manage": {
      "events": 999,
      ...
    },
    "monitor": {
      "clusters": 999,
      ...
    },
    "package": {
      "projects_with_packages": 999
    },
    "plan": {
      "issues": 999,
      ...
    },
    "release": {
      "deployments": 999,
      ...
    },
    "secure": {
      "user_container_scanning_jobs": 999,
      ...
    },
    "verify": {
      "ci_builds": 999,
      ...
    }
  },
  "topology": {
    "duration_s": 0.013836685999194742,
    "application_requests_per_hour": 4224,
    "query_apdex_weekly_average": 0.996,
    "failures": [],
    "nodes": [
      {
        "node_memory_total_bytes": 33269903360,
        "node_memory_utilization": 0.35,
        "node_cpus": 16,
        "node_cpu_utilization": 0.2,
        "node_uname_info": {
          "machine": "x86_64",
          "sysname": "Linux",
          "release": "4.19.76-linuxkit"
        },
        "node_services": [
          {
            "name": "web",
            "process_count": 16,
            "process_memory_pss": 233349888,
            "process_memory_rss": 788220927,
            "process_memory_uss": 195295487,
            "server": "puma"
          },
          {
            "name": "sidekiq",
            "process_count": 1,
            "process_memory_pss": 734080000,
            "process_memory_rss": 750051328,
            "process_memory_uss": 731533312
          },
          ...
        ],
        ...
      },
      ...
    ]
  }
}

导出 Service Ping 数据

存在 Rake 任务以不同格式导出 Service Ping 数据。

  • Rake 任务导出 countdistinct_countsum 的原始 SQL 查询。
  • Rake 任务导出 redis_usage_data 的 Redis 计数器类或 Redis 块的行。
  • Rake 任务计算 alt_usage_data 指标。

在本地 GitLab 安装的主目录中,运行以下 Rake 任务以获取 YAML 或 JSON 版本:

# for YAML export of SQL queries
bin/rake gitlab:usage_data:dump_sql_in_yaml

# for JSON export of SQL queries
bin/rake gitlab:usage_data:dump_sql_in_json

# for JSON export of Non SQL data
bin/rake gitlab:usage_data:dump_non_sql_in_json

# You may pipe the output into a file
bin/rake gitlab:usage_data:dump_sql_in_yaml > ~/Desktop/usage-metrics-2020-09-02.yaml

Service Ping 的回退值

在这些情况下,我们返回回退值:

Case Value
已弃用的指标 (在版本 14.3 中移除) -1000
超时、一般性错误 -1
计数器中的标准错误 -2
直方图指标失败 { ‘-1’ => -1 }

监控

Service Ping 报告进程状态通过 Tableau 仪表板 进行监控。

相关主题