blob: 776febda7a8e043a65be99c82952528a0328c2d9 [file] [log] [blame] [view] [edit]
# Cobalt: Telemetry with built-in privacy
[TOC]
## Overview
Cobalt is a pipeline for collecting metrics data from user-owned devices in the
field and producing aggregated reports.
Cobalt includes a suite of features for preserving user privacy and anonymity
while giving product owners the data they need to improve their products.
- **Differential Privacy.** If you enable it, Cobalt can add random
noise on the client during metrics collection.
- **Shuffling.** Our pipeline shuffles the collected records to break
linkability. This also amplifies the level of differential privacy.
- **No IDs.** Cobalt does not use device IDs or user IDs; not even pseudonymous
IDs.
- **No exact timestamps.** Cobalt uses day indices only.
- **Only standard metric types.** Not arbitrary protocol buffers.
- **No ad-hoc, post-facto querying.** Whereas on other telemetry systems
standard practice is to *"collect now; ask questions later"*, with Cobalt the
analyst must think in advance about what aggregations they wish to report and
predeclare reports.
- **Only aggregated data is released.** It is not possible to query the raw
collected data.
## Cobalt Core
The code in the Git repo at
[https://fuchsia.googlesource.com/cobalt](https://fuchsia.googlesource.com/cobalt)
is known as **Cobalt Core**. It contains:
- Client-side libraries for:
- Logging metric events to Cobalt
- Local aggregation
- Privacy encoding
- Local data storage
- Upload orchestration
- Protocol buffers for the registry of Cobalt's projects, metrics and reports.
- Protocol buffers for data transport
- The registry parser
In order to have a working Cobalt system you need to also have
- A server-side implementation of the Cobalt pipeline including a *Shuffler*
and *Analyzers* (aka *Report-Generators*.)
- There is a server-side pipeline running at Google with code in the internal Google
repository.
- As of this writing that is the only server-side implementation of Cobalt.
- An *embedding* of Cobalt Core into a client-side platform.
- This allows the code-to-be-measured to easily invoke Cobalt's *Logger* interface.
- There is an embedding into the *Fuchsia* operating system at
[//src/cobalt](https://fuchsia.googlesource.com/fuchsia/+/refs/heads/main/src/cobalt/).
- If you have a Fuchsia checkout, you will find a copy of Cobalt Core has
been pulled in at `//third_party/cobalt`.
- As of this writing, Fuchsia is the only embedding of Cobalt Core.
This document describes how to develop, build and test Cobalt Core independently
of Fuchsia, as well as from in the Fuchsia tree.
## Requirements
1. We have only tested the stand-alone Cobalt Core build on Linux. You may or
may not have success on other systems.
2. Python version at least 2.7
3. Git
## Fetch the code
To download just the Cobalt Core repo:
- `git clone https://fuchsia.googlesource.com/cobalt`
- `cd cobalt`
To download the entire Fuchsia source code, including Cobalt Core, follow the
[instructions](https://fuchsia.dev/fuchsia-src/get-started/get_fuchsia_source).
Then change into the Cobalt Core directory:
- `cd third_party/cobalt`
## Run setup
```./cobaltb.py setup```
This command is required after a first checkout, before running any other
`cobaltb.py` commands, and will take a few minutes the first time. It does
the following:
* Fetches third party code into Cobalt's `third_party` dir via Git submodules.
* Fetches the sysroot and puts it in Cobalt's `sysroot` dir. This uses
[CIPD](https://chromium.googlesource.com/chromium/src.git/+/main/docs/cipd.md).
### In the Fuchsia Tree
If the `./cobaltb.py setup` command is run in the `third_party/cobalt` checkout
of Cobalt Core in a Fuchsia tree, the Git submodules may interfere with the
correct functioning of Jiri to update the repos in the Fuchsia tree. If
problems occur, the submodules can be removed with: `./cobaltb.py deinit`.
Before running any other `cobaltb.py` commands in this checkout,
`./cobaltb.py setup` will need to be run again to refetch the submodules.
## cobaltb.py
The Python script `cobaltb.py` in the root directory is used to orchestrate
building and testing Cobalt. It was already used above in `./cobaltb.py setup`.
* `./cobaltb.py -h` for general help
* `cobaltb.py <command> -h` for help on a command
## Build
```./cobaltb.py build```
The Cobalt build uses GN and ninja.
## Test
```./cobaltb.py test```
This runs the tests from the currently built code (`build` must be run first).
## Formatting and Linting
```./cobaltb.py fmt```
```./cobaltb.py lint```
See: [clang-tidy](docs/clang-tidy.md) for an explanation of clang-tidy configuration options.
## Rolling Submodules
```./cobaltb.py sync_with_fuchsia --make_commit```
Cobalt Core's standalone build relies on git submodules to load several other
git repositories, including the Cobalt Registry. These submodules are not rolled
automatically, so developers need to occasionally manually roll them to keep the
libraries and the Cobalt Registry up to date. The command above will update all
Cobalt Core submodules to the latest versions used in Fuchsia's integration repo,
syncs the prebuilts into `cobalt.ensure`, copies over some required files from the
fuchsia repo, then creates a commit with a description of which submodules were
updated.
## Building Cobalt in Fuchsia
If the Cobalt Core checkout is part of a Fuchsia tree, it can also be built
using Fuchsia's tools. This can be done to test the Cobalt code changes build
and function correctly in Fuchsia. However, the build/test/fmt/lint commands
above should always be used before contributing a change to Cobalt Core.
- Build all of Fuchsia (assumes the Fuchsia build was already configured, see
[instructions](https://fuchsia.dev/fuchsia-src/get-started/build_fuchsia)):
```fx build```
In this way, the Cobalt Core and Fuchsia build systems can function correctly
in parallel.
## Contributing
Cobalt uses the [Gerrit](https://fuchsia-review.googlesource.com/)
code review tool. Although Cobalt Core is independent of Fuchsia, we do
share infrastructure with Fucshia and so much of the instructions from
Fuchsia's
[Contributing Guide](https://fuchsia.dev/fuchsia-src/development/source_code/contribute_changes)
apply to Cobalt Core. The main difference is that Cobalt
Core does not use Jiri--it uses Git submodules instead.
### Generate a cookie
Follow the [instructions here.](https://fuchsia.dev/fuchsia-src/development/source_code/contribute_changes#generate-a-cookie)
### Create a change in Gerrit
To create a [change](https://gerrit-review.googlesource.com/Documentation/concept-changes.html)
in Gerrit do the following:
- Go to your Cobalt Core directory, for example:
```cd ~/cobalt```
- Create a new branch:
```
git checkout -b <branch_name>
```
- Create or edit files in the new branch.
- Add the updated files:
```git add <files>```
- Commit the updated files and write a change message.
``` git commit```
- Upload the commit to Gerrit:
```git push origin HEAD:refs/for/main```
See the [Gerrit documentation](https://gerrit-documentation.storage.googleapis.com/Documentation/2.12.3/intro-user.html#upload-change) for more information.
### Update a change in Gerrit
After creating a change, to upload a patch to your change, do the following:
- Create or edit files in the same branch.
- Add the updated files:
```git add <files>```
- Include the patch in the same commit using the `--amend` option:
```git commit --amend```
- Upload the patch to Gerrit:
```git push origin HEAD:refs/for/main```