Skip to main content

Telemetry

dfmt reports one anonymous event per run. This page lists every field it contains, how to see exactly what your machine would send, and how to turn it off.

We collect it for two reasons: to know how many people use dfmt and on what, and to find out where the parser and formatter fail in real projects so we can fix them. Nothing on this page is a summary — the event has no fields beyond the ones listed here, and --telemetry-preview shows you the literal payload before it is sent.

What is never sent​

  • File names, paths, directory names, or your project's name
  • SQL, Jinja, or any other file content — not even fragments from error messages
  • Your IP address, hostname, user name, or any account identifier
  • Git remote URLs, branch names, or commit hashes

Events are anonymous in PostHog's sense: no person profile is created, and geolocation from the connection is disabled. Data is stored in PostHog's EU cloud.

How to turn it off​

Any one of these disables reporting; there is no setting that forces it on.

MethodScope
DLAB_TELEMETRY=0 in the environmentThis shell / this user
"telemetry": false at the root of dlab.jsonEveryone working in that project, including CI
DO_NOT_TRACK=1 in the environmentThis shell / this user

DO_NOT_TRACK=1 is the convention shared by many command-line tools, so a machine already opted out of everything is opted out of dfmt too.

Only a binary built at a release tag reports at all. A build from a source checkout carries a git describe version such as 0.0.1-M5-12-gabc1234-dirty, and sends nothing — so working on dfmt itself needs no opt-out. --telemetry-preview names the reason it is off.

Deleting ~/.config/dlab/telemetry-id ($XDG_CONFIG_HOME/dlab/telemetry-id, or %APPDATA%\dlab\telemetry-id on Windows) resets the installation id.

How to see what would be sent​

dfmt check --telemetry-preview

prints the full event as JSON on stderr, followed by whether it was sent, and why not if it was not.

The event​

Event name: dlab:dfmt_run. One per invocation, sent after the run's own output. The binary hands the event to a short-lived background process of itself and exits at once, so your prompt never waits on the network; that process gives up after a few seconds if the network is blocked. With --telemetry-preview the event is sent before exit instead, so the outcome can be printed. A failed send is never reported outside --telemetry-preview — nothing about formatting depends on it.

The event carries the identity and environment blocks below, product, and then the run, file, error and timing sections, which are specific to dfmt.

Identity​

FieldMeaning
install_idA random UUID minted the first time dfmt runs on this machine, stored in the file above. Derived from nothing about the machine.
project_idA truncated salted SHA-256 of the git origin URL with credentials stripped. Lets runs in the same repository be counted together across machines; the URL itself is not recoverable from it. Absent outside a git checkout.
distinct_idinstall_id locally; project:<project_id> in CI, where runners are ephemeral and an install id would count every run as a new installation.

Environment​

FieldMeaning
$lib_versionThe dfmt version: the release tag this binary was built at, e.g. 0.0.1-M5. Always a tag, because a build that is not at one does not report.
$os, $os_versionOperating system family (macos, linux, windows, other) and its major.minor version
archCPU architecture, e.g. aarch64
cpu_countNumber of processors
is_nativeWhether the native binary or a JVM ran
is_interactiveWhether stderr is a terminal
is_ci, ci_providerWhether a CI environment was detected, and which one (github, gitlab, buildkite, circleci, travis, jenkins, azure, teamcity, bitbucket, codebuild, drone, other)

The run​

FieldMeaning
productdfmt
modecheck, write, or print
dialectThe SQL dialect the run used
has_config_fileWhether a dlab.json was found
has_changed_since, has_model_flag, is_no_jinja, is_verboseWhich of those options were used
is_dbt, dbt_adapter, dbt_model_count, dbt_macro_count, dbt_init_msWhether a dbt project was detected, its adapter type, its size, and how long loading it took
is_dbt_init_failedPresent when a dbt project was found but could not be loaded, and the run fell back to plain SQL
exit_codeThe process exit code
exit_reasonPresent only when the run stopped before formatting. One of usage, no_config, no_dialect, missing_packages, model_requires_dbt, model_not_found, no_changed_files, no_files, scan_failed, uncaught
exception_classWith exit_reason: uncaught: the Java class name of what crashed dfmt, e.g. OutOfMemoryError. Never the message.

Files​

FieldMeaning
file_countFiles the run looked at
written_file_countFiles dfmt write changed
changed_file_countFiles dfmt check would have changed
unchanged_file_countFiles already formatted
failed_file_countFiles that errored
warned_file_countFiles that produced at least one warning
skipped_file_countFiles returned untouched by decision: disabled dbt models, Jinja files outside a dbt project
jinja_file_countFiles that went through the template pipeline
source_char_count, file_char_count_p50, file_char_count_maxTotal and per-file size of what was formatted

Errors​

FieldMeaning
warning_countAll warnings across all files
sql_parse_error_countSQL the parser could not fully read
jinja_error_countJinja syntax or evaluation failures
runtime_dependent_countModels that need a live warehouse to compile
reconstruction_failure_countCases where dfmt's own template layer gave up — bugs in dfmt
parse_error_kind_countsSQL parse errors by kind: missing_keyword, missing_punct, skipped, node
parse_error_production_countsThe ten grammar rules that failed most often, by our internal rule names, with counts
failure_kind_countsWhy files failed, by kind: empty_output, destructive_write_refused, write_failed, or the class name of the exception (StackOverflowError, IOException, …). Never a message.

The error fields are why the telemetry earns its keep: knowing that Expression fails ten times more often than SelectStatement under snowflake tells us what to fix next, and no example of your SQL is needed to know it.

Timing​

FieldMeaning
cpu_msParse and format time summed over files, with file IO excluded
batch_msWall time of the batch, IO included
wall_msWall time of the whole process

source_char_count / cpu_ms is a throughput independent of how many files a project has or how large they are; cpu_ms / batch_ms is how much parallelism the machine gave.