├── .buildconfig.yml
├── .cargo
└── config.toml
├── .circleci
├── config.yml
└── jazzy.yml
├── .config
└── nextest.toml
├── .detekt.yml
├── .dictionary
├── .git-blame-ignore-revs
├── .github
├── CODEOWNERS
├── dependabot.yml
└── workflows
│ ├── cargo-vet.yml
│ └── glean-probe-scraper.yml
├── .gitignore
├── .swiftlint.yml
├── .taskcluster.yml
├── .yamllint
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── Cargo.lock
├── Cargo.toml
├── DEPENDENCIES.md
├── LICENSE
├── Makefile
├── README.iOS.md
├── README.md
├── about.toml
├── bin
├── about.md.hbs
├── about.xml.hbs
├── build-rust-docs.bat
├── build-rust-docs.sh
├── build-swift-docs.sh
├── build-win.sh
├── build-xcframework.sh
├── check-artifact.sh
├── dependency-summary.sh
├── prepare-release.sh
├── publish-glean-swift.sh
├── run-ios-build.sh
├── run-ios-sample-app-build.sh
├── run-ios-sample-app-test.sh
├── run-ios-tests.sh
├── rust-wrapper-hack.sh
├── spellcheck.sh
├── update-glean-parser-version.sh
├── update-schema.sh
└── update-xcode-version.sh
├── build-scripts
├── publish_to_maven_local_if_modified.py
├── shared.py
├── substitute-local-glean.gradle
├── xc-cargo.sh
└── xc-universal-binary.sh
├── build.gradle
├── deny.toml
├── docs
├── dev
│ ├── README.md
│ ├── SUMMARY.md
│ ├── android
│ │ ├── development-with-mozilla-central.md
│ │ ├── glean-parser-substitution.md
│ │ ├── gradle-plugin-in-mc.md
│ │ ├── index.md
│ │ ├── logging.md
│ │ ├── sdk-ndk-versions.md
│ │ └── setup-android-build-environment.md
│ ├── api
│ │ └── index.md
│ ├── book.toml
│ ├── ci.md
│ ├── code_coverage.md
│ ├── contributing.md
│ ├── core
│ │ ├── dependency-management.md
│ │ ├── dependency-vetting.md
│ │ ├── documentation-guidelines.md
│ │ ├── index.md
│ │ ├── internal
│ │ │ ├── clearing.md
│ │ │ ├── database.md
│ │ │ ├── debug-pings.md
│ │ │ ├── directory-structure.md
│ │ │ ├── implementations.md
│ │ │ ├── index.md
│ │ │ ├── payload.md
│ │ │ ├── reserved-ping-names.md
│ │ │ └── upload.md
│ │ ├── logging-levels.md
│ │ ├── new-metric-type.md
│ │ └── new-metric-type
│ │ │ ├── kotlin.md
│ │ │ ├── platform.md
│ │ │ ├── python.md
│ │ │ ├── rust.md
│ │ │ └── swift.md
│ ├── cut-a-new-release.md
│ ├── docs.md
│ ├── glean.jpeg
│ ├── ios
│ │ ├── debug-glean-on-ios.md
│ │ ├── index.md
│ │ ├── setup-ios-build-environment.md
│ │ └── upgrading-supported-ios-platform.md
│ ├── python
│ │ ├── index.md
│ │ └── setting-up-python-build-environment.md
│ ├── testing.md
│ └── upgrading-glean-parser.md
├── shared
│ ├── blockquote-info.html
│ ├── blockquote-stop.html
│ ├── blockquote-warning.html
│ ├── glean.css
│ ├── mermaid-init.js
│ ├── mermaid.css
│ ├── mermaid.min.js
│ ├── tab_footer.md
│ ├── tab_header.md
│ └── tabs.js
└── user
│ ├── README.md
│ ├── SUMMARY.md
│ ├── _includes
│ ├── glean-js-redirect-collected-metrics.md
│ ├── label-errors.md
│ ├── label-limits.md
│ ├── labels-parameter.md
│ ├── lifetimes-parameters.md
│ ├── string-errors.md
│ └── string-limits.md
│ ├── appendix
│ ├── changelog
│ │ └── index.md
│ ├── contribution-guidelines.md
│ ├── glossary.md
│ ├── index.md
│ └── twig.md
│ ├── book.toml
│ ├── chart-distributions-ui.js
│ ├── chart-distributions.js
│ ├── chart.min.js
│ ├── glean.jpeg
│ ├── highlight.js
│ ├── language-bindings
│ ├── android
│ │ ├── android-build-configuration-options.md
│ │ ├── android-offline-builds.md
│ │ ├── gecko-content-processes-and-glean.md
│ │ ├── index.md
│ │ └── instrument-android-crashes-example.md
│ ├── index.md
│ ├── ios
│ │ ├── index.md
│ │ └── ios-build-configuration-options.md
│ └── javascript
│ │ ├── cli.md
│ │ ├── index.md
│ │ └── plugins
│ │ ├── encryption.md
│ │ └── index.md
│ ├── reference
│ ├── debug
│ │ ├── debugViewTag.md
│ │ ├── index.md
│ │ ├── logPings.md
│ │ ├── screenshots
│ │ │ ├── debug_view_tag_screenshot_swift.png
│ │ │ ├── log_pings_screenshot_swift.png
│ │ │ └── source_tags_screenshot_swift.png
│ │ └── sourceTags.md
│ ├── general
│ │ ├── attribution-api.md
│ │ ├── experiments-api.md
│ │ ├── glean-event-listener.md
│ │ ├── index.md
│ │ ├── initializing.md
│ │ ├── register-custom-pings.md
│ │ ├── shutdown.md
│ │ └── toggling-collection-status.md
│ ├── metrics
│ │ ├── boolean.md
│ │ ├── counter.md
│ │ ├── custom_distribution.md
│ │ ├── datetime.md
│ │ ├── event.md
│ │ ├── index.md
│ │ ├── labeled_booleans.md
│ │ ├── labeled_counters.md
│ │ ├── labeled_custom_distributions.md
│ │ ├── labeled_memory_distributions.md
│ │ ├── labeled_quantity.md
│ │ ├── labeled_strings.md
│ │ ├── labeled_timing_distributions.md
│ │ ├── memory_distribution.md
│ │ ├── object.md
│ │ ├── quantity.md
│ │ ├── rate.md
│ │ ├── string.md
│ │ ├── string_list.md
│ │ ├── text.md
│ │ ├── timespan.md
│ │ ├── timing_distribution.md
│ │ ├── url.md
│ │ └── uuid.md
│ ├── pings
│ │ └── index.md
│ └── yaml
│ │ ├── index.md
│ │ ├── metrics.md
│ │ ├── pings.md
│ │ └── tags.md
│ └── user
│ ├── adding-glean-to-your-project
│ ├── enable-data-ingestion.md
│ ├── index.md
│ ├── javascript.md
│ ├── kotlin.md
│ ├── python.md
│ ├── qt.md
│ ├── rust.md
│ ├── server.md
│ └── swift.md
│ ├── collected-metrics
│ └── metrics.md
│ ├── debugging
│ ├── android.md
│ ├── index.md
│ ├── ios.md
│ ├── javascript.md
│ └── python.md
│ ├── howto
│ ├── index.md
│ ├── investigating-data-issues
│ │ └── investigating-data-issues.md
│ ├── real-time-events
│ │ └── real-time-events.md
│ └── server-knobs-walkthrough
│ │ ├── images
│ │ ├── sk_walkthrough_image1.png
│ │ ├── sk_walkthrough_image10.png
│ │ ├── sk_walkthrough_image11.png
│ │ ├── sk_walkthrough_image12.png
│ │ ├── sk_walkthrough_image13.png
│ │ ├── sk_walkthrough_image14.png
│ │ ├── sk_walkthrough_image15.png
│ │ ├── sk_walkthrough_image16.png
│ │ ├── sk_walkthrough_image17.png
│ │ ├── sk_walkthrough_image18.png
│ │ ├── sk_walkthrough_image19.png
│ │ ├── sk_walkthrough_image2.png
│ │ ├── sk_walkthrough_image20.png
│ │ ├── sk_walkthrough_image21.png
│ │ ├── sk_walkthrough_image3.png
│ │ ├── sk_walkthrough_image4.png
│ │ ├── sk_walkthrough_image5.png
│ │ ├── sk_walkthrough_image6.png
│ │ ├── sk_walkthrough_image7.png
│ │ ├── sk_walkthrough_image8.png
│ │ └── sk_walkthrough_image9.png
│ │ └── server-knobs-walkthrough.md
│ ├── integrating-glean-for-product-managers.md
│ ├── metric-lifetime-timeline.svg
│ ├── metrics
│ ├── adding-new-metrics.md
│ ├── error-reporting.md
│ ├── index.md
│ ├── testing-metrics.md
│ └── validation-checklist.md
│ ├── pings
│ ├── baseline.md
│ ├── custom.md
│ ├── deletion-request.md
│ ├── events.md
│ ├── index.md
│ ├── metrics.md
│ ├── ping-schedules-and-timings.md
│ ├── ping_timing.svg
│ ├── sent-by-glean.md
│ └── testing-custom-pings.md
│ └── server-knobs
│ ├── index.md
│ ├── metrics
│ ├── advanced-topics.md
│ ├── example-scenarios.md
│ ├── experimenter-configuration.md
│ ├── faq.md
│ ├── index.md
│ └── product-integration.md
│ ├── other
│ ├── index.md
│ └── max-events.md
│ └── pings
│ ├── experimenter-configuration.md
│ ├── index.md
│ └── product-integration.md
├── glean-core
├── ARCHITECTURE.md
├── Cargo.toml
├── LICENSE
├── README.md
├── android-native
│ ├── build.gradle
│ ├── dependency-licenses.xml
│ ├── proguard-rules-consumer.pro
│ ├── proguard-rules.pro
│ └── src
│ │ └── main
│ │ └── AndroidManifest.xml
├── android
│ ├── build.gradle
│ ├── dependency-licenses.xml
│ ├── metrics.yaml
│ ├── proguard-rules-consumer.pro
│ ├── proguard-rules.pro
│ └── src
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── mozilla
│ │ │ └── telemetry
│ │ │ └── glean
│ │ │ ├── Dispatchers.kt
│ │ │ ├── Glean.kt
│ │ │ ├── config
│ │ │ └── Configuration.kt
│ │ │ ├── debug
│ │ │ └── GleanDebugActivity.kt
│ │ │ ├── net
│ │ │ ├── BaseUploader.kt
│ │ │ ├── HttpURLConnectionUploader.kt
│ │ │ ├── PingUploader.kt
│ │ │ └── Upload.kt
│ │ │ ├── private
│ │ │ ├── Aliases.kt
│ │ │ ├── BooleanMetricType.kt
│ │ │ ├── CounterMetricType.kt
│ │ │ ├── CustomDistributionMetricType.kt
│ │ │ ├── DatetimeMetricType.kt
│ │ │ ├── DenominatorMetricType.kt
│ │ │ ├── EventMetricType.kt
│ │ │ ├── HistogramBase.kt
│ │ │ ├── LabeledMetricType.kt
│ │ │ ├── MemoryDistributionMetricType.kt
│ │ │ ├── NumeratorMetricType.kt
│ │ │ ├── ObjectMetricType.kt
│ │ │ ├── PingType.kt
│ │ │ ├── QuantityMetricType.kt
│ │ │ ├── RateMetricType.kt
│ │ │ ├── StringListMetricType.kt
│ │ │ ├── StringMetricType.kt
│ │ │ ├── TextMetricType.kt
│ │ │ ├── TimespanMetricType.kt
│ │ │ ├── TimingDistributionMetricType.kt
│ │ │ ├── UrlMetricType.kt
│ │ │ └── UuidMetricType.kt
│ │ │ ├── scheduler
│ │ │ ├── GleanLifecycleObserver.kt
│ │ │ ├── MetricsPingScheduler.kt
│ │ │ └── PingUploadWorker.kt
│ │ │ ├── testing
│ │ │ ├── ErrorType.kt
│ │ │ ├── GleanTestLocalServer.kt
│ │ │ └── GleanTestRule.kt
│ │ │ └── utils
│ │ │ ├── DataPathUtils.kt
│ │ │ ├── DateUtils.kt
│ │ │ ├── GzipUtils.kt
│ │ │ ├── JsonUtils.kt
│ │ │ ├── LocaleUtils.kt
│ │ │ ├── ThreadUtils.kt
│ │ │ └── WorkManagerUtils.kt
│ │ └── test
│ │ ├── java
│ │ ├── android
│ │ │ └── util
│ │ │ │ └── Log.java
│ │ └── mozilla
│ │ │ └── telemetry
│ │ │ └── glean
│ │ │ ├── GleanFromJavaTest.java
│ │ │ ├── GleanTest.kt
│ │ │ ├── TestUtil.kt
│ │ │ ├── debug
│ │ │ └── GleanDebugActivityTest.kt
│ │ │ ├── net
│ │ │ ├── BaseUploaderTest.kt
│ │ │ └── HttpURLConnectionUploaderTest.kt
│ │ │ ├── pings
│ │ │ ├── CustomPingTest.kt
│ │ │ ├── DeletionPingTest.kt
│ │ │ └── RidealongPingTest.kt
│ │ │ ├── private
│ │ │ ├── AccumulationsBeforeGleanInitTest.kt
│ │ │ ├── BooleanMetricTypeTest.kt
│ │ │ ├── CounterMetricTypeTest.kt
│ │ │ ├── CustomDistributionMetricTypeTest.kt
│ │ │ ├── DatetimeMetricTypeTest.kt
│ │ │ ├── EventMetricTypeTest.kt
│ │ │ ├── LabeledMetricTypeTest.kt
│ │ │ ├── MemoryDistributionMetricTypeTest.kt
│ │ │ ├── ObjectMetricTypeTest.kt
│ │ │ ├── PingTypeTest.kt
│ │ │ ├── QuantityMetricTypeTest.kt
│ │ │ ├── RateMetricTypeTest.kt
│ │ │ ├── StringListMetricTypeTest.kt
│ │ │ ├── StringMetricTypeTest.kt
│ │ │ ├── TimespanMetricTypeTest.kt
│ │ │ ├── TimingDistributionMetricTypeTest.kt
│ │ │ ├── UrlMetricTypeTest.kt
│ │ │ └── UuidMetricTypeTest.kt
│ │ │ ├── scheduler
│ │ │ ├── MetricsPingSchedulerTest.kt
│ │ │ └── PingUploadWorkerTest.kt
│ │ │ ├── shadows
│ │ │ └── ShadowLog.java
│ │ │ └── utils
│ │ │ ├── DataPathUtilsTest.kt
│ │ │ ├── DateUtilsTest.kt
│ │ │ ├── GzipUtilsTest.kt
│ │ │ ├── JsonUtilsTest.kt
│ │ │ └── KArgumentCaptor.kt
│ │ └── resources
│ │ ├── mockito-extensions
│ │ └── org.mockito.plugins.MockMaker
│ │ └── robolectric.properties
├── build.rs
├── build
│ ├── Cargo.toml
│ ├── LICENSE
│ ├── README.md
│ └── src
│ │ └── lib.rs
├── bundle-android
│ └── Cargo.toml
├── bundle
│ ├── Cargo.toml
│ ├── src
│ │ ├── glean.udl
│ │ └── lib.rs
│ └── uniffi.toml
├── ios
│ ├── .gitkeep
│ ├── Glean.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── swiftpm
│ │ │ │ └── Package.resolved
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Glean.xcscheme
│ ├── Glean
│ │ ├── Config
│ │ │ └── Configuration.swift
│ │ ├── Debug
│ │ │ └── GleanDebugTools.swift
│ │ ├── Dispatchers.swift
│ │ ├── Glean.h
│ │ ├── Glean.swift
│ │ ├── GleanMetrics.swift
│ │ ├── Info.plist
│ │ ├── Metrics
│ │ │ ├── BooleanMetric.swift
│ │ │ ├── CounterMetric.swift
│ │ │ ├── DatetimeMetric.swift
│ │ │ ├── EventMetric.swift
│ │ │ ├── LabeledMetric.swift
│ │ │ ├── MemoryDistributionMetric.swift
│ │ │ ├── ObjectMetric.swift
│ │ │ ├── Ping.swift
│ │ │ ├── QuantityMetric.swift
│ │ │ ├── RateMetric.swift
│ │ │ ├── StringListMetric.swift
│ │ │ ├── StringMetric.swift
│ │ │ ├── TextMetric.swift
│ │ │ ├── TimespanMetric.swift
│ │ │ ├── TimingDistributionMetric.swift
│ │ │ ├── UrlMetric.swift
│ │ │ └── UuidMetric.swift
│ │ ├── Net
│ │ │ └── HttpPingUploader.swift
│ │ ├── Scheduler
│ │ │ ├── GleanLifecycleObserver.swift
│ │ │ └── MetricsPingScheduler.swift
│ │ └── Utils
│ │ │ ├── Logger.swift
│ │ │ ├── Sysctl.swift
│ │ │ ├── Unreachable.swift
│ │ │ └── Utils.swift
│ ├── GleanTests
│ │ ├── Config
│ │ │ └── ConfigurationTests.swift
│ │ ├── Debug
│ │ │ └── GleanDebugUtilityTests.swift
│ │ ├── GleanTests.swift
│ │ ├── Info.plist
│ │ ├── Metrics
│ │ │ ├── BooleanMetricTypeTest.swift
│ │ │ ├── CounterMetricTests.swift
│ │ │ ├── DatetimeMetricTypeTests.swift
│ │ │ ├── EventMetricTests.swift
│ │ │ ├── LabeledMetricTests.swift
│ │ │ ├── MemoryDistributionMetricTests.swift
│ │ │ ├── ObjectMetricTests.swift
│ │ │ ├── PingTests.swift
│ │ │ ├── QuantityMetricTypeTest.swift
│ │ │ ├── RateMetricTests.swift
│ │ │ ├── StringListMetricTests.swift
│ │ │ ├── StringMetricTests.swift
│ │ │ ├── TimespanMetricTests.swift
│ │ │ ├── TimingDistributionMetricTests.swift
│ │ │ ├── UrlMetricTests.swift
│ │ │ └── UuidMetricTests.swift
│ │ ├── Net
│ │ │ ├── BaselinePingTests.swift
│ │ │ ├── DeletionRequestPingTests.swift
│ │ │ └── HttpPingUploaderTests.swift
│ │ ├── RidealongPingTests.swift
│ │ ├── Scheduler
│ │ │ └── MetricsPingSchedulerTests.swift
│ │ ├── TestUtils.swift
│ │ └── Utils
│ │ │ └── DataPathUtilsTests.swift
│ ├── base.xcconfig
│ ├── debug.xcconfig
│ ├── release.xcconfig
│ └── sdk_generator.sh
├── megazord.uniffi.toml
├── metrics.yaml
├── pings.yaml
├── python
│ ├── .gitignore
│ ├── glean
│ │ ├── __init__.py
│ │ ├── _builtins.py
│ │ ├── _ffi.py
│ │ ├── _loader.py
│ │ ├── _process_dispatcher.py
│ │ ├── _subprocess
│ │ │ ├── __init__.py
│ │ │ └── _process_dispatcher_helper.py
│ │ ├── _util.py
│ │ ├── config.py
│ │ ├── glean.py
│ │ ├── metrics.yaml
│ │ ├── metrics
│ │ │ ├── __init__.py
│ │ │ ├── datetime.py
│ │ │ ├── event.py
│ │ │ ├── labeled.py
│ │ │ ├── object.py
│ │ │ ├── ping.py
│ │ │ ├── string.py
│ │ │ ├── timespan.py
│ │ │ ├── timing_distribution.py
│ │ │ ├── url.py
│ │ │ └── uuid.py
│ │ ├── net
│ │ │ ├── __init__.py
│ │ │ ├── base_uploader.py
│ │ │ ├── http_client.py
│ │ │ ├── ping_upload_worker.py
│ │ │ └── ping_uploader.py
│ │ ├── pings.yaml
│ │ └── testing
│ │ │ └── __init__.py
│ ├── requirements_dev.txt
│ └── tests
│ │ ├── conftest.py
│ │ ├── data
│ │ ├── core.yaml
│ │ ├── events_with_types.yaml
│ │ ├── glinter.yaml
│ │ └── pings.yaml
│ │ ├── metrics
│ │ ├── test_boolean.py
│ │ ├── test_counter.py
│ │ ├── test_datetime.py
│ │ ├── test_event.py
│ │ ├── test_labeled.py
│ │ ├── test_memory_distribution.py
│ │ ├── test_object.py
│ │ ├── test_quantity.py
│ │ ├── test_rate.py
│ │ ├── test_string.py
│ │ ├── test_string_list.py
│ │ ├── test_text.py
│ │ ├── test_timespan.py
│ │ ├── test_timing_distribution.py
│ │ ├── test_url.py
│ │ └── test_uuid.py
│ │ ├── test_collection_enabled.py
│ │ ├── test_glean.py
│ │ ├── test_loader.py
│ │ ├── test_network.py
│ │ └── test_subprocess.py
├── rlb
│ ├── Cargo.toml
│ ├── LICENSE
│ ├── README.md
│ ├── examples
│ │ ├── crashing-threads.rs
│ │ ├── delayed-ping-data.rs
│ │ ├── enabled-pings.rs
│ │ ├── long-running.rs
│ │ ├── pending-gets-removed.rs
│ │ ├── ping-lifetime-flush.rs
│ │ └── prototype.rs
│ ├── src
│ │ ├── common_test.rs
│ │ ├── configuration.rs
│ │ ├── core_metrics.rs
│ │ ├── lib.rs
│ │ ├── net
│ │ │ ├── http_uploader.rs
│ │ │ └── mod.rs
│ │ ├── private
│ │ │ ├── event.rs
│ │ │ ├── mod.rs
│ │ │ ├── object.rs
│ │ │ └── ping.rs
│ │ ├── system.rs
│ │ └── test.rs
│ └── tests
│ │ ├── collection_enabled.rs
│ │ ├── collection_enabled_bin.rs
│ │ ├── common
│ │ └── mod.rs
│ │ ├── custom_distribution_buffered.rs
│ │ ├── init_fails.rs
│ │ ├── interruptible_shutdown.rs
│ │ ├── memory_distribution_buffered.rs
│ │ ├── metric_metadata.rs
│ │ ├── near-empty-c0ffee-db.safe.bin
│ │ ├── never_init.rs
│ │ ├── no_time_to_init.rs
│ │ ├── overflowing_preinit.rs
│ │ ├── persist_ping_lifetime_nopanic.rs
│ │ ├── schema.rs
│ │ ├── simple.rs
│ │ ├── test-delayed-ping-data.sh
│ │ ├── test-enabled-pings.sh
│ │ ├── test-pending-gets-removed.sh
│ │ ├── test-ping-lifetime-flush.sh
│ │ ├── test-shutdown-blocking.sh
│ │ ├── test-thread-crashing.sh
│ │ ├── timing_distribution_buffered.rs
│ │ ├── timing_distribution_single_sample.rs
│ │ ├── upload_timing.rs
│ │ └── uploader_capabilities.rs
├── src
│ ├── common_metric_data.rs
│ ├── core
│ │ └── mod.rs
│ ├── core_metrics.rs
│ ├── coverage.rs
│ ├── database
│ │ └── mod.rs
│ ├── debug.rs
│ ├── dispatcher
│ │ ├── global.rs
│ │ └── mod.rs
│ ├── error.rs
│ ├── error_recording.rs
│ ├── event_database
│ │ └── mod.rs
│ ├── fd_logger.rs
│ ├── glean.udl
│ ├── glean_metrics.rs
│ ├── histogram
│ │ ├── exponential.rs
│ │ ├── functional.rs
│ │ ├── linear.rs
│ │ └── mod.rs
│ ├── internal_metrics.rs
│ ├── internal_pings.rs
│ ├── lib.rs
│ ├── lib_unit_tests.rs
│ ├── metrics
│ │ ├── boolean.rs
│ │ ├── counter.rs
│ │ ├── custom_distribution.rs
│ │ ├── datetime.rs
│ │ ├── denominator.rs
│ │ ├── event.rs
│ │ ├── experiment.rs
│ │ ├── labeled.rs
│ │ ├── memory_distribution.rs
│ │ ├── memory_unit.rs
│ │ ├── mod.rs
│ │ ├── numerator.rs
│ │ ├── object.rs
│ │ ├── ping.rs
│ │ ├── quantity.rs
│ │ ├── rate.rs
│ │ ├── recorded_experiment.rs
│ │ ├── remote_settings_config.rs
│ │ ├── string.rs
│ │ ├── string_list.rs
│ │ ├── text.rs
│ │ ├── time_unit.rs
│ │ ├── timespan.rs
│ │ ├── timing_distribution.rs
│ │ ├── url.rs
│ │ └── uuid.rs
│ ├── ping
│ │ └── mod.rs
│ ├── scheduler.rs
│ ├── storage
│ │ └── mod.rs
│ ├── system.rs
│ ├── traits
│ │ ├── boolean.rs
│ │ ├── counter.rs
│ │ ├── custom_distribution.rs
│ │ ├── datetime.rs
│ │ ├── event.rs
│ │ ├── labeled.rs
│ │ ├── memory_distribution.rs
│ │ ├── mod.rs
│ │ ├── numerator.rs
│ │ ├── object.rs
│ │ ├── ping.rs
│ │ ├── quantity.rs
│ │ ├── rate.rs
│ │ ├── string.rs
│ │ ├── string_list.rs
│ │ ├── text.rs
│ │ ├── timespan.rs
│ │ ├── timing_distribution.rs
│ │ ├── url.rs
│ │ └── uuid.rs
│ ├── upload
│ │ ├── directory.rs
│ │ ├── mod.rs
│ │ ├── policy.rs
│ │ ├── request.rs
│ │ └── result.rs
│ └── util.rs
├── tests
│ ├── boolean.rs
│ ├── collection_enabled.rs
│ ├── common
│ │ └── mod.rs
│ ├── counter.rs
│ ├── custom_distribution.rs
│ ├── datetime.rs
│ ├── event.rs
│ ├── labeled.rs
│ ├── memory_distribution.rs
│ ├── object.rs
│ ├── ping.rs
│ ├── ping_maker.rs
│ ├── quantity.rs
│ ├── rate.rs
│ ├── storage.rs
│ ├── string.rs
│ ├── string_list.rs
│ ├── text.rs
│ ├── timespan.rs
│ ├── timing_distribution.rs
│ └── uuid.rs
└── uniffi.toml
├── glean.1.schema.json
├── gradle-plugin
├── README.md
├── build.gradle
└── src
│ └── main
│ └── groovy
│ └── mozilla
│ └── telemetry
│ └── glean-gradle-plugin
│ └── GleanGradlePlugin.groovy
├── gradle.properties
├── gradle
├── libs.versions.toml
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── lint-baseline.xml
├── publish.gradle
├── pyproject.toml
├── samples
├── android
│ └── app
│ │ ├── README.md
│ │ ├── build.gradle
│ │ ├── metrics.yaml
│ │ ├── pings.yaml
│ │ ├── proguard-rules.pro
│ │ ├── src
│ │ ├── androidTest
│ │ │ └── java
│ │ │ │ └── org
│ │ │ │ └── mozilla
│ │ │ │ └── samples
│ │ │ │ └── gleancore
│ │ │ │ ├── MainActivityTest.kt
│ │ │ │ └── pings
│ │ │ │ ├── BackgroundPingTest.kt
│ │ │ │ ├── BaselinePingTest.kt
│ │ │ │ ├── DeletionRequestPingTest.kt
│ │ │ │ └── SharedTestUtils.kt
│ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── org
│ │ │ │ └── mozilla
│ │ │ │ └── samples
│ │ │ │ └── gleancore
│ │ │ │ ├── GleanApplication.kt
│ │ │ │ ├── MainActivity.kt
│ │ │ │ └── SampleBackgroundProcess.kt
│ │ │ └── res
│ │ │ ├── layout
│ │ │ └── activity_main.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values
│ │ │ └── strings.xml
│ │ │ └── xml
│ │ │ └── backup_rules.xml
│ │ └── tags.yaml
├── ios
│ └── app
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── base.xcconfig
│ │ ├── debug.xcconfig
│ │ ├── glean-sample-app.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ │ └── swiftpm
│ │ │ │ └── Package.resolved
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── glean-sample-app.xcscheme
│ │ ├── glean-sample-app
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ └── ViewController.swift
│ │ ├── glean-sample-appTests
│ │ ├── Info.plist
│ │ └── glean_sample_appTests.swift
│ │ ├── glean-sample-appUITests
│ │ ├── BaselinePingTest.swift
│ │ ├── DeletionRequestPingTest.swift
│ │ ├── EventPingTest.swift
│ │ ├── Info.plist
│ │ ├── MockServer.swift
│ │ └── ViewControllerTest.swift
│ │ ├── metrics.yaml
│ │ ├── pings.yaml
│ │ ├── release.xcconfig
│ │ └── sdk_generator.sh
├── python
│ ├── Makefile
│ ├── README.md
│ ├── glean-sample
│ │ └── __main__.py
│ ├── metrics.yaml
│ ├── pings.yaml
│ ├── pyproject.toml
│ └── requirements.txt
└── rust
│ ├── Cargo.toml
│ ├── build.rs
│ ├── metrics.yaml
│ ├── pings.yaml
│ └── src
│ └── main.rs
├── settings.gradle
├── supply-chain
├── audits.toml
├── config.toml
└── imports.lock
├── taskcluster
├── config.yml
├── docker
│ └── linux
│ │ ├── Dockerfile
│ │ ├── runbuild.sh
│ │ └── runlocally.sh
├── glean_taskgraph
│ ├── __init__.py
│ ├── build_config.py
│ ├── job.py
│ ├── loader
│ │ ├── __init__.py
│ │ ├── build_config.py
│ │ └── multi_dep.py
│ ├── target_tasks.py
│ ├── transforms
│ │ ├── __init__.py
│ │ ├── beetmover.py
│ │ ├── module_build.py
│ │ ├── multi_dep.py
│ │ └── signing.py
│ └── worker_types.py
├── kinds
│ ├── android-build
│ │ └── kind.yml
│ ├── beetmover
│ │ └── kind.yml
│ ├── docker-image
│ │ └── kind.yml
│ ├── module-build
│ │ └── kind.yml
│ ├── rust
│ │ └── kind.yml
│ └── signing
│ │ └── kind.yml
└── scripts
│ ├── cross-compile-setup.sh
│ ├── macos.manifest
│ └── rustup-setup.sh
├── tools
├── analysis
│ └── ping-patterns
│ │ ├── README.md
│ │ ├── config.py
│ │ └── ping-patterns.py
├── dbread.rs
├── docker-winbuild
│ ├── Dockerfile
│ ├── README.md
│ ├── build.sh
│ └── init.sh
├── embedded-uniffi-bindgen
│ ├── Cargo.toml
│ ├── README.md
│ └── src
│ │ ├── lib.rs
│ │ └── main.rs
└── patches
│ └── bcryptprimitives.rs
└── xcconfig
└── common.xcconfig
/.buildconfig.yml:
--------------------------------------------------------------------------------
1 | libraryVersion: 64.4.0
2 | groupId: org.mozilla.telemetry
3 | projects:
4 | glean:
5 | path: glean-core/android
6 | artifactId: glean
7 | publications:
8 | - name: glean
9 | type: aar
10 | description: 'The Glean SDK is a modern approach for a Telemetry library and is part of the Glean project.'
11 | glean-native:
12 | path: glean-core/android-native
13 | artifactId: glean-native
14 | publications:
15 | - name: glean-native
16 | type: aar
17 | - name: glean-native-forUnitTests
18 | type: jar
19 | description: 'The native libglean_ffi library for use with the Glean SDK.'
20 | glean-sample-app:
21 | path: samples/android/app
22 | artifactId: glean-sample-app
23 | description: 'An app demoing how to use the Glean library to collect and send telemetry data.'
24 | publications: []
25 | glean-gradle-plugin:
26 | path: gradle-plugin
27 | artifactId: glean-gradle-plugin
28 | publications:
29 | - name: glean-gradle-plugin
30 | type: jar
31 | description: 'A Gradle plugin to enable Glean SDK build-time support (metrics and pings API, docs, ...)'
32 |
--------------------------------------------------------------------------------
/.cargo/config.toml:
--------------------------------------------------------------------------------
1 | [alias]
2 | uniffi-bindgen = ["run", "--package", "uniffi-bindgen", "--"]
3 |
--------------------------------------------------------------------------------
/.circleci/jazzy.yml:
--------------------------------------------------------------------------------
1 | ---
2 | sdk: iphone
3 | module: Glean
4 | author_url: https://mozilla.github.com/glean
5 | github_url: https://github.com/mozilla/glean
6 | readme: README.iOS.md
7 | xcodebuild_arguments:
8 | - "-workspace"
9 | - "./glean-core/ios/Glean.xcodeproj/project.xcworkspace"
10 | - "-scheme"
11 | - "Glean"
12 | - "-destination"
13 | - "platform=iOS Simulator,name=iPhone 15"
14 |
--------------------------------------------------------------------------------
/.config/nextest.toml:
--------------------------------------------------------------------------------
1 | [profile.ci.junit]
2 | path = "junit.xml"
3 |
--------------------------------------------------------------------------------
/.detekt.yml:
--------------------------------------------------------------------------------
1 | style:
2 | # We want to allow "TODO" in comments
3 | ForbiddenComment:
4 | active: false
5 | # Allow for generated code
6 | WildcardImport:
7 | excludeImports:
8 | - mozilla.telemetry.glean.internal.*
9 | # Multiple returns are ok
10 | ReturnCount:
11 | active: false
12 |
13 | # Go ahead and jump (Jump!)
14 | # Go ahead and jump
15 | #
16 | # break/continue in loops are ok.
17 | LoopWithTooManyJumpStatements:
18 | active: false
19 |
20 | build:
21 | maxIssues: 0
22 |
23 | complexity:
24 | LongMethod:
25 | active: true
26 | threshold: 60
27 |
28 | # We need to relax naming of enums and classes a bit,
29 | # as they are generated by the glean_parser for metric types, such as events.
30 | naming:
31 | active: true
32 | ClassNaming:
33 | active: true
34 | classPattern: '[a-zA-Z0-9$]+'
35 | EnumNaming:
36 | active: true
37 | enumEntryPattern: '[a-zA-Z0-9$]+'
38 |
--------------------------------------------------------------------------------
/.git-blame-ignore-revs:
--------------------------------------------------------------------------------
1 | 00e22288040c8a14b4dcbf94a8eee9210757c476 # ktlint update & formatting
2 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # This Source Code Form is subject to the terms of the Mozilla Public
2 | # License, v. 2.0. If a copy of the MPL was not distributed with this
3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 |
5 | # This CODEOWNERS file defines individuals or teams that are responsible
6 | # for code in this repository.
7 | # See https://help.github.com/articles/about-codeowners/ for details.
8 |
9 | * @mozilla/glean
10 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | # glean
4 | - package-ecosystem: "cargo"
5 | directory: "/"
6 | schedule:
7 | interval: "daily"
8 | versioning-strategy: lockfile-only
9 |
10 | # glean-python
11 | - package-ecosystem: "pip"
12 | directory: "/glean-core/python"
13 | schedule:
14 | interval: "daily"
15 | ignore:
16 | # Updated in lockstep across all implementations
17 | - dependency-name: "glean_parser"
18 |
--------------------------------------------------------------------------------
/.github/workflows/cargo-vet.yml:
--------------------------------------------------------------------------------
1 | name: cargo-vet
2 | on:
3 | pull_request:
4 | push:
5 | branches:
6 | main
7 | jobs:
8 | cargo-vet:
9 | name: Vet Dependencies
10 | runs-on: ubuntu-latest
11 | env:
12 | CARGO_VET_VERSION: 0.10.0
13 | steps:
14 | - uses: actions/checkout@master
15 | - name: Install Rust
16 | run: rustup update stable && rustup default stable
17 | - uses: actions/cache@v4
18 | with:
19 | path: ${{ runner.tool_cache }}/cargo-vet
20 | key: cargo-vet-bin-${{ env.CARGO_VET_VERSION }}
21 | - name: Add the tool cache directory to the search path
22 | run: echo "${{ runner.tool_cache }}/cargo-vet/bin" >> $GITHUB_PATH
23 | - name: Ensure that the tool cache is populated with the cargo-vet binary
24 | run: |
25 | export CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
26 | cargo install --root ${{ runner.tool_cache }}/cargo-vet --version ${{ env.CARGO_VET_VERSION }} cargo-vet
27 | - name: Invoke cargo-vet
28 | run: cargo vet --locked
29 |
30 |
--------------------------------------------------------------------------------
/.github/workflows/glean-probe-scraper.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Glean probe-scraper
3 | on:
4 | pull_request:
5 | push:
6 | branches: main
7 |
8 | jobs:
9 | glean-probe-scraper:
10 | uses: mozilla/probe-scraper/.github/workflows/glean.yaml@main
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | docs/*/book
2 | docs/*/shared/
3 | docs/user/appendix/changelog.md
4 | docs/user/appendix/changelog/sdk.md
5 | docs/user/appendix/changelog/js.md
6 | target
7 |
8 | # Android stuff.
9 | *.iml
10 | .gradle
11 | local.properties
12 | .idea
13 | build
14 | captures
15 | .externalNativeBuild
16 | .lastAutoPublishContentsHash
17 |
18 | # Include glean-build crate again
19 | !/glean-core/build
20 |
21 | # iOS stuff.
22 | xcuserdata
23 | raw_xcode*log
24 | /glean-core/ios/Glean/Generated
25 | /glean-core/ios/Pipfile
26 | /glean-core/ios/Pipfile.lock
27 | /glean-core/ios/.venv
28 |
29 | # OS stuff
30 | .DS_Store
31 | *.dSYM
32 |
33 | # Python stuff
34 | *.egg-info
35 | dist/
36 | .venv*/
37 |
38 | # Wine stuff
39 | winpython/
40 |
41 | samples/ios/app/.venv/
42 | samples/python/.venv*/
43 | samples/python/data
44 | .mypy_cache/
45 | .coverage
46 | .coverage*
47 | htmlcov/
48 | *.log
49 |
50 | glean-core/python/glean/_uniffi
51 | __pycache__
52 | *.py[cod]
53 | .Python
54 |
55 | # UniFFI generated code
56 | glean-core/uniffi/src/glean_core.uniffi.rs
57 | glean-core/uniffi/src/uniffi
58 |
59 | *.swp
60 |
--------------------------------------------------------------------------------
/.swiftlint.yml:
--------------------------------------------------------------------------------
1 | excluded:
2 | - Carthage
3 | - glean-core/ios/Glean/Generated
4 | - samples/ios/app/Carthage
5 | - samples/ios/app/glean-sample-app/Generated
6 | disabled_rules:
7 | - file_length
8 | # We're pretty careful about this already, but it's a pain to disable
9 | # and reenable in the cases where we're sure.
10 | - force_try
11 | # We're pretty careful about this already, but it's a pain to disable
12 | # and reenable in the cases where we're sure (mostly tests).
13 | - force_cast
14 | # We'll get to these when we get to them!
15 | - todo
16 | - function_body_length
17 |
18 | identifier_name:
19 | # Turn off it complaining about `id` or `let t = title`, etc, but keep
20 | # warnings around e.g. enum names.
21 | min_length:
22 | warning: 0
23 | error: 0
24 |
25 | line_length:
26 | ignores_urls: true
27 |
--------------------------------------------------------------------------------
/.yamllint:
--------------------------------------------------------------------------------
1 | extends: default
2 |
3 | rules:
4 | line-length:
5 | ignore: |
6 | .circleci/config.yml
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Community Participation Guidelines
2 |
3 | This repository is governed by Mozilla's code of conduct and etiquette guidelines.
4 | For more details, please read the
5 | [Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/).
6 |
7 | ## How to Report
8 | For more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page.
9 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | resolver = "2"
3 |
4 | members = [
5 | "glean-core",
6 | "glean-core/rlb",
7 | "glean-core/bundle",
8 | "glean-core/bundle-android",
9 | "glean-core/build",
10 | "samples/rust",
11 | "tools/embedded-uniffi-bindgen",
12 | ]
13 |
14 | default-members = [
15 | "glean-core",
16 | "tools/embedded-uniffi-bindgen",
17 | ]
18 |
19 | [profile.release]
20 | opt-level = "s"
21 | debug = false
22 | lto = true
23 |
24 | [profile.dev.package.miniz_oxide]
25 | opt-level = 3
26 |
27 | [profile.dev.package.flate2]
28 | opt-level = 3
29 |
--------------------------------------------------------------------------------
/README.iOS.md:
--------------------------------------------------------------------------------
1 | # Glean SDK
2 |
3 | The `Glean SDK` is a modern approach for a Telemetry library and is part of the [Glean project][project-overview].
4 |
5 | ## Documentation
6 |
7 | The full Glean SDK documentation is available online:
8 |
9 | ## [The Glean SDK Book][book]
10 |
11 | ## License
12 |
13 | This Source Code Form is subject to the terms of the Mozilla Public
14 | License, v. 2.0. If a copy of the MPL was not distributed with this
15 | file, You can obtain one at http://mozilla.org/MPL/2.0/
16 |
17 | [project-overview]: https://docs.telemetry.mozilla.org/concepts/glean/glean.html
18 | [book]: https://mozilla.github.io/glean/
19 |
--------------------------------------------------------------------------------
/about.toml:
--------------------------------------------------------------------------------
1 | accepted = [
2 | "MPL-2.0",
3 | "Apache-2.0",
4 | "MIT",
5 | "CC0-1.0",
6 | "BSD-2-Clause",
7 | "BSD-3-Clause",
8 | "ISC",
9 | "Zlib",
10 | "Unicode-3.0",
11 | ]
12 |
13 | # Subset of targets we build for
14 | targets = [
15 | # Linux/Windows/macOS
16 | "x86_64-unknown-linux-gnu",
17 | "x86_64-pc-windows-gnu",
18 | "x86_64-apple-darwin",
19 |
20 | # Android targets
21 | "aarch64-linux-android",
22 | "armv7-linux-androideabi",
23 | "i686-linux-android",
24 | "x86_64-linux-android",
25 |
26 | # iOS targets
27 | "aarch64-apple-ios",
28 | "x86_64-apple-ios"
29 | ]
30 |
31 | ignore-build-dependencies = true
32 | ignore-dev-dependencies = true
33 | no-clearly-defined = true
34 |
--------------------------------------------------------------------------------
/bin/about.md.hbs:
--------------------------------------------------------------------------------
1 | # Licenses for Third-Party Dependencies
2 |
3 | Binary distributions of this software incorporate code from a number of third-party dependencies.
4 | These dependencies are available under a variety of free and open source licenses,
5 | the details of which are reproduced below.
6 |
7 | {{#each overview ~}}
8 | * [{{{name}}}](#{{id}})
9 | {{/each}}
10 | -------------
11 |
12 | {{#each licenses ~}}
13 | ## {{name}}
14 |
15 |
16 | The following text applies to code linked from these dependencies:
17 |
18 | {{#each used_by~}}
19 | * [{{crate.name}} {{crate.version}}]({{#if crate.repository}} {{crate.repository}} {{else}} https://crates.io/crates/{{crate.name}} {{/if}})
20 | {{/each}}
21 |
22 | ```
23 | {{{text}}}
24 | ```
25 | {{/each ~}}
26 |
--------------------------------------------------------------------------------
/bin/about.xml.hbs:
--------------------------------------------------------------------------------
1 |
2 |
7 | {{~#each licenses}}
8 | {{~#each used_by}}
9 |
10 | {{{../name}}}: {{crate.name}}
11 | {{#if crate.repository}}{{crate.repository}}{{else}}https://crates.io/crates/{{crate.name}}{{/if}}
12 |
13 | {{~/each}}
14 | {{~/each}}
15 |
16 |
--------------------------------------------------------------------------------
/bin/build-rust-docs.bat:
--------------------------------------------------------------------------------
1 | :: This Source Code Form is subject to the terms of the Mozilla Public
2 | :: License, v. 2.0. If a copy of the MPL was not distributed with this
3 | :: file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 |
5 | :: Build all docs with one command, on Windows.
6 | :: Documentation will be placed in `build/docs`.
7 | :: This behaves the same as build-rust-docs.sh.
8 |
9 | :: Note: there's no way to do "set -e" easily in
10 | :: Windows batch file, other than this:
11 | :: https://stackoverflow.com/a/13863374/261698
12 | :: I'm ignoring this for the moment, as I'm the
13 | :: only consumer for now :-)
14 |
15 | :: Set the docs location.
16 | set "docs_location=build\docs"
17 |
18 | :: Set the crate name.
19 | set "crate_name=glean_core"
20 |
21 | :: Add the changelog file.
22 | copy /Y CHANGELOG.md docs\user\appendix\changelog\sdk.md
23 |
24 | mdbook build docs\user\
25 | if errorlevel 1 exit /b %errorlevel%
26 |
27 | cargo doc --no-deps
28 |
29 | if exist %docs_location% rmdir /S /Q %docs_location%
30 | mkdir %docs_location%
31 | echo "" > %docs_location%\index.html
32 |
33 | mkdir %docs_location%\book
34 | xcopy /K /E docs\book\. %docs_location%\book
35 |
36 | mkdir %docs_location%\docs
37 | xcopy /K /E target\doc\. %docs_location%\docs
38 | echo "\n" > %docs_location%\docs\index.html
39 |
--------------------------------------------------------------------------------
/bin/build-swift-docs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # This Source Code Form is subject to the terms of the Mozilla Public
4 | # License, v. 2.0. If a copy of the MPL was not distributed with this
5 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 |
7 | set -eo pipefail
8 |
9 | # Build Swift with one command
10 | # Requires jazzy from https://github.com/realm/jazzy
11 |
12 | WORKSPACE_ROOT="$( cd "$(dirname "$0")/.." ; pwd -P )"
13 | cd "$WORKSPACE_ROOT"
14 |
15 | jazzy --version
16 | jazzy \
17 | --clean \
18 | --config "$WORKSPACE_ROOT/.circleci/jazzy.yml" \
19 | --output "$WORKSPACE_ROOT/build/docs/swift"
20 |
--------------------------------------------------------------------------------
/bin/dependency-summary.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This Source Code Form is subject to the terms of the Mozilla Public
4 | # License, v. 2.0. If a copy of the MPL was not distributed with this
5 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 |
7 | # This script can be used to generate a summary of our third-party dependencies,
8 | # including license details. Use it like this:
9 | #
10 | # bin/dependency-summary.sh
11 |
12 | set -eo pipefail
13 |
14 | CARGO_ABOUT_MIN_VERSION="0.7.0"
15 |
16 | WORKSPACE_ROOT="$( cd "$(dirname "$0")/.." ; pwd -P )"
17 |
18 | MD_TEMPLATE="${WORKSPACE_ROOT}/bin/about.md.hbs"
19 | XML_TEMPLATE="${WORKSPACE_ROOT}/bin/about.xml.hbs"
20 |
21 | MD_OUTPUT="${WORKSPACE_ROOT}/DEPENDENCIES.md"
22 | XML_OUTPUT="${WORKSPACE_ROOT}/glean-core/android/dependency-licenses.xml"
23 | XML_OUTPUT_NATIVE="${WORKSPACE_ROOT}/glean-core/android-native/dependency-licenses.xml"
24 |
25 | verlte() {
26 | [ "$1" = "$(printf "$1\n$2\n" | sort --version-sort | head -n1)" ]
27 | }
28 |
29 | command -v cargo-about >/dev/null || cargo install cargo-about
30 | installed_version=$(cargo-about --version | awk '{print $2}')
31 | if ! verlte "$CARGO_ABOUT_MIN_VERSION" "$installed_version"; then
32 | echo "WARN: Found cargo-about v${installed_version}, require at least ${CARGO_ABOUT_MIN_VERSION}" >&2
33 | echo "WARN: Please update cargo-about: cargo install cargo-about"
34 | fi
35 |
36 | cargo about generate "${MD_TEMPLATE}" > "${MD_OUTPUT}"
37 | cargo about generate "${XML_TEMPLATE}" > "${XML_OUTPUT}"
38 | cp "${XML_OUTPUT}" "${XML_OUTPUT_NATIVE}"
39 |
--------------------------------------------------------------------------------
/bin/publish-glean-swift.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This Source Code Form is subject to the terms of the Mozilla Public
4 | # License, v. 2.0. If a copy of the MPL was not distributed with this
5 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 |
7 | set -xe
8 |
9 | # Strip any `v` prefix from `vX.Y.Z`
10 | NEW_VERSION=$(echo "$1" | sed 's/^v//')
11 |
12 | # Get the supported iOS platform version
13 | # See https://developer.apple.com/documentation/packagedescription/supportedplatform/iosversion for valid iOS versions
14 | WORKSPACE_ROOT="$( cd "$(dirname "$0")/.." ; pwd -P )"
15 | FILE=glean-core/ios/Glean.xcodeproj/project.pbxproj
16 | IOS_PLATFORM_VERSION=v$(grep -m 1 \
17 | -Po "(?<=IPHONEOS_DEPLOYMENT_TARGET \= )[0-9]." \
18 | "${WORKSPACE_ROOT}/${FILE}")
19 |
20 | git clone https://github.com/mozilla/glean-swift glean-swift
21 | cd glean-swift
22 | bin/update.sh "$NEW_VERSION" --ios-version "$IOS_PLATFORM_VERSION"
23 | git push -q https://${GLEAN_SWIFT_GITHUB_TOKEN}@github.com/mozilla/glean-swift.git main
24 | git push -q https://${GLEAN_SWIFT_GITHUB_TOKEN}@github.com/mozilla/glean-swift.git "$NEW_VERSION"
25 |
--------------------------------------------------------------------------------
/bin/run-ios-build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | #
3 | # This Source Code Form is subject to the terms of the Mozilla Public
4 | # License, v. 2.0. If a copy of the MPL was not distributed with this
5 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 |
7 | set -euvx
8 |
9 | set -o pipefail && \
10 | xcodebuild \
11 | -workspace ./glean-core/ios/Glean.xcodeproj/project.xcworkspace \
12 | -scheme Glean \
13 | -sdk iphonesimulator \
14 | -destination 'platform=iOS Simulator,name=iPhone 15' \
15 | build | \
16 | tee raw_xcodebuild.log | \
17 | xcpretty && exit "${PIPESTATUS[0]}"
18 |
--------------------------------------------------------------------------------
/bin/run-ios-sample-app-build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | #
3 | # This Source Code Form is subject to the terms of the Mozilla Public
4 | # License, v. 2.0. If a copy of the MPL was not distributed with this
5 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 |
7 | set -euvx
8 |
9 | set -o pipefail && \
10 | xcodebuild \
11 | -workspace ./samples/ios/app/glean-sample-app.xcodeproj/project.xcworkspace \
12 | -scheme glean-sample-app \
13 | -sdk iphonesimulator \
14 | -destination 'platform=iOS Simulator,name=iPhone 15' \
15 | build | \
16 | tee raw_sample_xcodebuild.log | \
17 | xcpretty && exit "${PIPESTATUS[0]}"
18 |
--------------------------------------------------------------------------------
/bin/run-ios-sample-app-test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | #
3 | # This Source Code Form is subject to the terms of the Mozilla Public
4 | # License, v. 2.0. If a copy of the MPL was not distributed with this
5 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 |
7 | set -euvx
8 |
9 | set -o pipefail && \
10 | xcodebuild \
11 | -workspace ./samples/ios/app/glean-sample-app.xcodeproj/project.xcworkspace \
12 | -scheme glean-sample-app \
13 | -sdk iphonesimulator \
14 | -destination 'platform=iOS Simulator,name=iPhone 15' \
15 | test | \
16 | tee raw_sample_xcodetest.log | \
17 | xcpretty && exit "${PIPESTATUS[0]}"
18 |
--------------------------------------------------------------------------------
/bin/run-ios-tests.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | #
3 | # This Source Code Form is subject to the terms of the Mozilla Public
4 | # License, v. 2.0. If a copy of the MPL was not distributed with this
5 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 |
7 | set -euvx
8 |
9 | set -o pipefail && \
10 | xcodebuild \
11 | -workspace ./glean-core/ios/Glean.xcodeproj/project.xcworkspace \
12 | -scheme Glean \
13 | -sdk iphonesimulator \
14 | -destination 'platform=iOS Simulator,name=iPhone 15' \
15 | test | \
16 | tee raw_xcodetest.log | \
17 | xcpretty && exit "${PIPESTATUS[0]}"
18 |
--------------------------------------------------------------------------------
/bin/rust-wrapper-hack.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # This Source Code Form is subject to the terms of the Mozilla Public
4 | # License, v. 2.0. If a copy of the MPL was not distributed with this
5 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 |
7 | # A hack to not do anything when targetting darwin (macOS),
8 | # but still correctly build everything else.
9 | # Only to be used on Linux hosts.
10 |
11 | unset RUSTC
12 | if echo "$*" | grep -q "print=cfg"; then
13 | rustc $*
14 | elif echo "$*" | grep -q "target x86_64-apple-darwin"; then
15 | true
16 | else
17 | rustc $*
18 | fi
19 |
--------------------------------------------------------------------------------
/bin/update-schema.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This Source Code Form is subject to the terms of the Mozilla Public
4 | # License, v. 2.0. If a copy of the MPL was not distributed with this
5 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 |
7 | # Update the bundled schema version tests run against.
8 | #
9 | # The schema is pulled from mozilla-pipeline-schemas at the following URL:
10 | #
11 | # https://raw.githubusercontent.com/mozilla-services/mozilla-pipeline-schemas/$HASH/schemas/glean/glean/glean.1.schema.json
12 | #
13 | # References in the code base are updated.
14 | #
15 | # Usage: update-schema.sh
16 | #
17 | # Environment:
18 | #
19 | # VERB - Log commands that are run when set.
20 |
21 | set -eo pipefail
22 |
23 | run() {
24 | [ "${VERB:-0}" != 0 ] && echo "+ $*"
25 | "$@"
26 | }
27 |
28 | update() {
29 | COMMIT_HASH="$1"
30 | FULL_URL="$(printf "$SCHEMA_URL" "$COMMIT_HASH")"
31 | SCHEMA_PATH="${WORKSPACE_ROOT}/glean.1.schema.json"
32 |
33 | echo "Vendoring schema from ${FULL_URL}"
34 | run curl --silent --fail --show-error --location --retry 5 --retry-delay 10 "$FULL_URL" --output "$SCHEMA_PATH"
35 | }
36 |
37 | WORKSPACE_ROOT="$( cd "$(dirname "$0")/.." ; pwd -P )"
38 | SCHEMA_URL="https://raw.githubusercontent.com/mozilla-services/mozilla-pipeline-schemas/%s/schemas/glean/glean/glean.1.schema.json"
39 |
40 | if [ -z "$1" ]; then
41 | echo "Usage: $(basename $0) "
42 | echo
43 | echo "Update schema version to test"
44 | exit 1
45 | fi
46 |
47 | COMMIT_HASH="$1"
48 | update "$COMMIT_HASH"
49 |
--------------------------------------------------------------------------------
/build-scripts/xc-cargo.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | #
3 | # This is a small wrapper for running `cargo` inside of an XCode build,
4 | # which unfortunately doesn't seem to work quite right out-of-the-box.
5 | set -eEuvx
6 |
7 | # Xcode tries to be helpful and overwrites the PATH. Reset that.
8 | export PATH="${HOME}/.cargo/bin:$PATH"
9 | export LIBRARY_PATH="${DEVELOPER_SDK_DIR}/MacOSX.sdk/usr/lib:${LIBRARY_PATH:-}"
10 |
11 | "${@}"
12 |
--------------------------------------------------------------------------------
/deny.toml:
--------------------------------------------------------------------------------
1 | [licenses]
2 | allow = [
3 | "MPL-2.0",
4 | "Apache-2.0",
5 | "MIT",
6 | "BSD-2-Clause",
7 | "Zlib",
8 | "Unicode-3.0",
9 | ]
10 |
11 | [bans]
12 | # Avoid duplications.
13 | # Exceptions defined below with a reason.
14 | multiple-versions = "deny"
15 |
16 | skip = [
17 | # wasi 0.10 and 0.11 are allowed
18 | # (m-c patches 0.10 to 0.11)
19 | { name = "wasi", version = "0.11.0" },
20 | # bitflags 1.3.2 is a dependency of lmdb-rkv,
21 | # with bitflags in use by others.
22 | # This is overriden in m-c
23 | { name = "bitflags", version = "1.3.2" },
24 | ]
25 |
26 | # Avoid certain crates
27 | deny = [
28 | { name = "windows", version = "0.48.0" },
29 | ]
30 |
--------------------------------------------------------------------------------
/docs/dev/android/glean-parser-substitution.md:
--------------------------------------------------------------------------------
1 | # Substituting `glean_parser`
2 |
3 | By default the Glean Kotlin SDK requires an exact version of the [`glean_parser`].
4 | It's automatically installed as part of the Glean Gradle Plugin.
5 |
6 | For upgrading the required `glean_parser` see [Upgrading glean_parser](../upgrading-glean-parser.md).
7 |
8 | For local development the `glean_parser` can be replaced with a development version.
9 | To use `glean_parser` from a git repository, add this to the project's `build.gradle`:
10 |
11 | ```groovy
12 | ext.gleanParserOverride = "git+ssh://git@github.com/mozilla/glean_parser@main#glean-parser"
13 | ```
14 |
15 | Adjust the repository URL as needed. `main` can be any available branch.
16 | Ensure the suffix `#glean_parser` exists, as it tells the Python package management about the name.
17 |
18 |
19 |
20 | [`glean_parser`]: https://github.com/mozilla/glean_parser/
21 |
--------------------------------------------------------------------------------
/docs/dev/android/gradle-plugin-in-mc.md:
--------------------------------------------------------------------------------
1 | # Replacing the Glean Gradle plugin in mozilla-central
2 |
3 | > **Note**: If you only need to replace the `glean_parser` Python parts used in the build see [Substituting `glean_parser`](glean-parser-substitution.md).
4 | > The approached documented in this chapter is only necessary if you changed `GleanGradlePlugin.groovy`.
5 |
6 | If you need to replace the Glean Gradle Plugin used by any component in mozilla-central, follow these steps:
7 |
8 | 1. In your Glean repository increment the version number in `.buildconfig.yml` to something unused:
9 |
10 | ```yaml
11 | libraryVersion: 70.0.0
12 | ```
13 |
14 | 1. Build the Glean Gradle plugin and publish the plugin locally:
15 |
16 | ```
17 | ./gradlew glean-gradle-plugin:publishToMavenLocal
18 | ```
19 |
20 | 1. In your `mozilla-central` checkout, add the following line in `mobile/android/fenix/settings.gradle` file in the `pluginManagement` block:
21 |
22 | ```gradle
23 | mavenLocal()
24 | ```
25 |
26 | 1. Use the new version number where the plugin is imported in `mobile/android/fenix/build.gradle`:
27 |
28 | ```
29 | classpath "org.mozilla.telemetry:glean-gradle-plugin:70.0.0"
30 | ```
31 |
32 | This might need to be applied to the top-level `build.gradle` and other `build.gradle` files under `mobile/android` to apply to all components.
33 |
34 |
35 | Building Fenix will now use your locally published Glean Gradle Plugin.
36 |
--------------------------------------------------------------------------------
/docs/dev/android/index.md:
--------------------------------------------------------------------------------
1 | # Android bindings
2 |
3 | The Glean SDK contains the Kotlin bindings for use by Android applications.
4 | It makes use of the underlying [Rust component](../core/index.md) with a Kotlin-specific API on top.
5 | It also includes integrations into the Android platform.
6 |
--------------------------------------------------------------------------------
/docs/dev/android/logging.md:
--------------------------------------------------------------------------------
1 | # Logging
2 |
3 | Logs from `glean-core` are only passed through to the Android logging framework when `Glean.initialize` is called for the first time.
4 | This means any logging that might happen before that, e.g. from early metric collection will not be collected.
5 |
6 | If these logs are needed for debugging add the following initializer to `Glean.kt`:
7 |
8 | ```kotlin
9 | init {
10 | gleanEnableLogging()
11 | }
12 | ```
13 |
--------------------------------------------------------------------------------
/docs/dev/android/sdk-ndk-versions.md:
--------------------------------------------------------------------------------
1 | # Android SDK / NDK versions
2 |
3 | The Glean SDK implementation requires the following Android SDK/NDK tooling:
4 |
5 | * SDK API 35
6 | * Look for `android-35` in the SDK manager
7 | * or install with: `sdkmanager --verbose "platforms;android-35"`
8 | * Android Command line tools
9 | * Download link:
10 | * NDK r28b
11 | * Download link:
12 |
13 | For the full setup see [Setup the Android Build Environment](setup-android-build-environment.html).
14 |
15 | The versions are defined in the following files.
16 | All locations need to be updated on upgrades:
17 |
18 | * Documentation
19 | * this file (`docs/dev/core/internal/sdk-ndk-versions.md`)
20 | * `dev/android/setup-android-build-environment.md`
21 | * CI configuration
22 | * `.circleci/config.yml`
23 | * `sdkmanager 'build-tools;35.0.0'`
24 | * `image: circleci/android:2025.04.1-browsers`
25 | * `taskcluster/docker/linux/Dockerfile`.
26 | * `ENV ANDROID_BUILD_TOOLS "35.0.0"`
27 | * `ENV ANDROID_SDK_VERSION "12700392"`
28 | * `ENV ANDROID_PLATFORM_VERSION "35"`
29 | * `ENV ANDROID_NDK_VERSION "28.1.13356709"`
30 |
--------------------------------------------------------------------------------
/docs/dev/api/index.md:
--------------------------------------------------------------------------------
1 | The following language-specific API docs are available:
2 |
3 | - [Swift API docs](../../swift/index.html)
4 | - [Python API docs](../../python/glean/index.html)
5 | - [Rust core (internal) API docs](../../docs/index.html)
6 |
--------------------------------------------------------------------------------
/docs/dev/book.toml:
--------------------------------------------------------------------------------
1 | [book]
2 | title = "Glean - Cross-platform Telemetry library"
3 | authors = ["Glean Team"]
4 | src = "."
5 |
6 | [build]
7 | build-dir = "book"
8 | create-missing = false
9 |
10 | [output.html]
11 | additional-css = ["../shared/glean.css", "../shared/mermaid.css"]
12 | additional-js = ["../shared/tabs.js", "../shared/mermaid.min.js", "../shared/mermaid-init.js"]
13 | git-repository-url = "https://github.com/mozilla/glean"
14 | edit-url-template = "https://github.com/mozilla/glean/edit/main/docs/dev/{path}"
15 | git-branch = "main"
16 | mathjax-support = true
17 |
18 | [preprocessor.open-on-gh]
19 | command = "mdbook-open-on-gh"
20 |
21 | [preprocessor.mermaid]
22 | command = "mdbook-mermaid"
23 |
--------------------------------------------------------------------------------
/docs/dev/core/index.md:
--------------------------------------------------------------------------------
1 | # Rust component
2 |
3 | The majority of the Glean SDK is implemented as a Rust component, to be usable across all platforms.
4 |
5 | This includes:
6 |
7 | * Implementations of all metric types
8 | * A storage layer
9 | * A ping serializer
10 |
--------------------------------------------------------------------------------
/docs/dev/core/internal/clearing.md:
--------------------------------------------------------------------------------
1 | # Clearing metrics when disabling/enabling Glean
2 |
3 | When disabling upload (`Glean.setCollectionEnabled(false)`), metrics are also cleared to prevent their storage on the local device, and lessen the likelihood
4 | of accidentally sending them.
5 | There is an exceptions to this:
6 |
7 | - `first_run_date` is retained so it isn't reset if metrics are later re-enabled.
8 |
9 | When re-enabling metrics:
10 |
11 | - `first_run_date` is left as-is. (It should remain a correct time of first run of the application, unaffected by disabling/enabling the Glean SDK).
12 |
13 | - The `client_id` is set to a newly-generated random UUID. It has no connection to the `client_id` used prior to disabling the Glean SDK.
14 |
15 | - Application lifetime metrics owned by Glean are regenerated from scratch so that they will appear in subsequent pings. This is the same process that happens during every startup of the application when the Glean SDK is enabled. The application is also responsible for setting any application lifetime metrics that it manages at this time.
16 |
17 | - Ping lifetime metrics do not need special handling. They will begin recording again after metric uploading is re-enabled.
18 |
19 |
--------------------------------------------------------------------------------
/docs/dev/core/internal/debug-pings.md:
--------------------------------------------------------------------------------
1 | # Debug Pings
2 |
3 | For debugging and testing purposes Glean allows to tag pings, which are then available in the [Debug Ping Viewer][debug-ping-viewer][^1].
4 |
5 | Pings are sent to the same endpoint as all pings, with the addition of one HTTP header:
6 |
7 | ```
8 | X-Debug-ID:
9 | ```
10 |
11 | `` is a alphanumeric string with a maximum length of 20 characters, used to identify pings in the Debug Ping Viewer.
12 |
13 | See [Debugging products using the Glean SDK](../../../book/user/debugging/index.md) for detailed information how to use this mechanism in applications.
14 |
15 | [debug-ping-viewer]: https://debug-ping-preview.firebaseapp.com/
16 |
17 | ---
18 |
19 | [^1]: Requires a Mozilla login.
20 |
--------------------------------------------------------------------------------
/docs/dev/core/internal/index.md:
--------------------------------------------------------------------------------
1 | # Internal documentation
2 |
3 | This chapter describes aspects of the Glean SDKs that are internal implementation details.
4 |
5 |
6 | {{#include ../../../shared/blockquote-warning.html}}
7 |
8 | #### Note
9 |
10 | > As implementation details, this information is subject to change at any time.
11 | > External users should not rely on this information.
12 | > It is provided as a reference for contributing to Glean only.
13 |
14 | This includes:
15 |
16 | * [Reserved ping names](reserved-ping-names.md)
17 | * [Clearing metrics when disabling/enabling Glean](clearing.md)
18 | * [Database format](database.md)
19 | * [Payload format](payload.md)
20 | * [Directory structure](directory-structure.md)
21 | * [Debug Pings](debug-pings.md)
22 | * [Implementations](implementations.md)
23 |
--------------------------------------------------------------------------------
/docs/dev/core/internal/reserved-ping-names.md:
--------------------------------------------------------------------------------
1 | # Reserved ping names
2 |
3 | The Glean SDK reserves all ping names in `send_in_pings` starting with `glean_`.
4 |
5 | This currently includes, but is not limited to:
6 |
7 | * `glean_client_info`: metrics sent with this ping are added to every ping in its `client_info` section;
8 | * `glean_internal_info`: metrics sent with this ping are added to every ping in its `ping_info` section.
9 |
10 | Additionally, only Glean may specify `all-pings`. This special value has no effect in the client, but indicates to the backend infrastructure that a metric may appear in any ping.
11 |
--------------------------------------------------------------------------------
/docs/dev/core/new-metric-type/kotlin.md:
--------------------------------------------------------------------------------
1 | # Adding a new metric type - Kotlin
2 |
3 | ## Re-export generated API
4 |
5 | By default a metric type gets an auto-generated API from the definition in `glean.udl`.
6 | This API is exposed under the `internal` namespace.
7 | If this API is sufficient it needs to be re-exported.
8 |
9 | Create a new Kotlin file, e.g. `glean-core/android/src/main/java/mozilla/telemetry/glean/private/CounterMetricType.kt`:
10 |
11 | ```Kotlin
12 | package mozilla.telemetry.glean.private
13 |
14 | typealias CounterMetricType = mozilla.telemetry.glean.internal.CounterMetric
15 | ```
16 |
17 | ## Extend and modify API
18 |
19 | If the generated API is not sufficient, convenient or needs additional language-specific constructs or conversions the generated API can be wrapped.
20 |
21 | Create a new Kotlin file, e.g. `glean-core/android/src/main/java/mozilla/telemetry/glean/private/CounterMetricType.kt`.
22 | Then create a new class, that delegates functionality to the metric type class from the `internal` namespace.
23 |
24 | ```Kotlin
25 | package mozilla.telemetry.glean.private
26 |
27 | import mozilla.telemetry.glean.internal.CounterMetric
28 |
29 | class CounterMetricType(meta: CommonMetricData) {
30 | val inner = CounterMetric(meta)
31 |
32 | // Wrap existing functionality
33 | fun add(amount: Int = 1) {
34 | inner.add(amount)
35 | }
36 |
37 | // Add a new method
38 | fun addTwo() {
39 | inner.add(2)
40 | }
41 | }
42 | ```
43 |
44 | Remember to wrap all defined methods of the metric type.
45 |
--------------------------------------------------------------------------------
/docs/dev/core/new-metric-type/rust.md:
--------------------------------------------------------------------------------
1 | # Adding a new metric type - Rust
2 |
3 | ## Trait
4 |
5 | To ensure the API is stable across Rust consumers and re-exporters (like FOG),
6 | you must define a trait for the new metric in `glean-core/src/traits`.
7 | First, add your metric type to `mod.rs`:
8 |
9 | ```Rust
10 | mod counter;
11 |
12 | pub use self::counter::Counter;
13 | ```
14 |
15 | Then add the trait in e.g.
16 | [`counter.rs`](https://github.com/mozilla/glean/blob/HEAD/glean-core/src/traits/counter.rs).
17 |
18 | The trait includes `test_get_num_recorded_errors`
19 | and any metric operation included in the metric type's API
20 | (except `new`).
21 | The idea here is to only include operations that make sense for Rust consumers.
22 | If there are internal-only or language-specific APIs on the underlying metric,
23 | feel free to not include them on the trait.
24 |
25 | Spend some time on the comments.
26 | These will be the dev-facing API docs for Rust consumers.
27 |
28 | ## Rust Language Binding (RLB) Type
29 |
30 | The Rust Language Binding can simply re-export the core metric types.
31 | You can find the RLB metric re-exports in `glean-core/rlb/src/private`.
32 |
33 | Add your metric type to `mod.rs`:
34 |
35 | ```Rust
36 | pub use glean_core::Counter;
37 | ```
38 |
39 | ## Documentation
40 |
41 | Don't forget to document the new Rust API in the Book's page on the Metric Type
42 | (e.g. [Counter](../../../book/reference/metrics/counter.html)).
43 | Add a tab for Rust, and mimic any other language's example.
44 |
--------------------------------------------------------------------------------
/docs/dev/core/new-metric-type/swift.md:
--------------------------------------------------------------------------------
1 | # Adding a new metric type - Swift
2 |
3 | ## Re-export generated API
4 |
5 | By default a metric type gets an auto-generated API from the definition in `glean.udl`.
6 | If this API is sufficient it needs to be re-exported.
7 |
8 | Create a new Swift file, e.g. `glean-core/ios/Glean/Metrics/CounterMetric.swift`:
9 |
10 | ```Swift
11 | public typealias CounterMetricType = CounterMetric
12 | ```
13 |
14 | ## Extend and modify API
15 |
16 | If the generated API is not sufficient, convenient or needs additional language-specific constructs or conversions the generated API can be wrapped.
17 |
18 | Create a new Swift file, e.g. `glean-core/ios/Glean/Metrics/CounterMetric.swift`.
19 | Then create a new class, that delegates functionality to the generated metric type class.
20 |
21 | ```Swift
22 | public class CounterMetricType {
23 | let inner: CounterMetric
24 |
25 | // Wrap existing functionality
26 | public func add(_ amount: Int = 1) {
27 | inner.add(amount)
28 | }
29 |
30 | // Add a new method
31 | public func addTwo() {
32 | inner.add(2)
33 | }
34 | }
35 | ```
36 |
37 | Remember to wrap all defined methods of the metric type.
38 |
--------------------------------------------------------------------------------
/docs/dev/glean.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/dev/glean.jpeg
--------------------------------------------------------------------------------
/docs/dev/ios/index.md:
--------------------------------------------------------------------------------
1 | # iOS bindings
2 |
3 | The Glean SDK contains the Swift bindings for use by iOS applications.
4 | It makes use of the underlying [Rust component](../core/index.md) with a Swift-specific API on top.
5 | It also includes integrations into the iOS platform.
6 |
--------------------------------------------------------------------------------
/docs/dev/ios/setup-ios-build-environment.md:
--------------------------------------------------------------------------------
1 | # Setup the iOS Build Environment
2 |
3 | ## Prepare your build environment
4 |
5 | 1. Install Xcode 15.0 or higher.
6 | 2. Ensure you have Python 3 installed: `brew install python`
7 | 3. Install linting and formatting tools: `brew install swiftlint`
8 | 4. (Optional, only required for building on the CLI) Install [xcpretty](https://github.com/xcpretty/xcpretty): `gem install xcpretty`
9 |
10 | ### Setting up Rust
11 |
12 | Rust can be installed using `rustup`, with the following commands:
13 |
14 | - `curl https://sh.rustup.rs -sSf | sh`
15 | - `rustup update`
16 |
17 | Platform specific toolchains need to be installed for Rust. This can be
18 | done using the `rustup target` command. In order to enable building to real
19 | devices and iOS emulators, the following targets need to be installed:
20 |
21 | ```
22 | rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim
23 | ```
24 |
25 | ## Building
26 |
27 | This should be relatively straightforward and painless:
28 |
29 | 1. Ensure your repository is up-to-date.
30 | 2. Ensure Rust is up-to-date by running `rustup update`.
31 | 3. Run a build using the command `make build-swift`
32 | * To run tests use `make test-swift`
33 |
34 | The above can be skipped if using Xcode.
35 | The project directory can be imported and all the build details can be left to the IDE.
36 |
--------------------------------------------------------------------------------
/docs/dev/ios/upgrading-supported-ios-platform.md:
--------------------------------------------------------------------------------
1 | # Upgrade the supported Xcode Version
2 |
3 | When it is necessary to update the supported Xcode version in Glean, the `bin/update-xcode-version.sh` script
4 | can make this process easier by updating all of the necessary files and locations.
5 |
6 | ### Usage Example
7 |
8 | Example updating to support Xcode version 15.1:
9 |
10 | ```
11 | bin/update-xcode-version.sh 15.1
12 | ```
13 |
--------------------------------------------------------------------------------
/docs/dev/python/index.md:
--------------------------------------------------------------------------------
1 | # Python bindings
2 |
3 | The Glean SDK contains Python bindings for use in Python applications and test frameworks.
4 | It makes use of the underlying [Rust component](../core/index.md) with a Python-specific API on top.
5 |
--------------------------------------------------------------------------------
/docs/dev/upgrading-glean-parser.md:
--------------------------------------------------------------------------------
1 | # Upgrading glean_parser
2 |
3 | To upgrade the version of `glean_parser` used by the Glean SDK, run the `bin/update-glean-parser-version.sh` script, providing the version as a command line parameter:
4 |
5 | ```sh
6 | bin/update-glean-parser-version.sh 1.28.3
7 | ```
8 |
9 | This will update the version in all of the required places. Commit those changes to `git` and submit a pull request.
10 |
11 | No further steps are required to use the new version of `glean_parser` for code generation: all of the build integrations automatically update `glean_parser` to the correct version.
12 |
13 | For testing the Glean Python bindings, the virtual environment needs to be deleted to force an upgrade of `glean_parser`:
14 |
15 | ```sh
16 | rm -rf glean-core/python/.venv*
17 | ```
18 |
--------------------------------------------------------------------------------
/docs/shared/blockquote-info.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/shared/blockquote-stop.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/shared/blockquote-warning.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/shared/mermaid-init.js:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 | mermaid.initialize({startOnLoad:true});
5 |
--------------------------------------------------------------------------------
/docs/shared/tab_footer.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/docs/shared/tab_header.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/docs/user/_includes/glean-js-redirect-collected-metrics.md:
--------------------------------------------------------------------------------
1 | {{#include ../../../shared/blockquote-info.html}}
2 |
3 | # The Glean JavaScript SDK provides a slightly different set of metrics and pings
4 |
5 | > If you are looking for the metrics collected by Glean.js,
6 | > refer to the documentation over on the [`@mozilla/glean.js`](https://github.com/mozilla/glean.js/blob/main/docs/reference/metrics.md) repository.
7 |
--------------------------------------------------------------------------------
/docs/user/_includes/label-errors.md:
--------------------------------------------------------------------------------
1 | * [`invalid_label`](../../user/metrics/error-reporting.md):
2 | * If the label contains invalid characters. Data is still recorded to the special label `__other__`.
3 | * If the label exceeds the maximum number of allowed characters. Data is still recorded to the special label `__other__`.
4 |
--------------------------------------------------------------------------------
/docs/user/_includes/label-limits.md:
--------------------------------------------------------------------------------
1 | * Labels must conform to the [label format](index.md#label-format).
2 | * Each label must have a maximum of 111 characters.
3 | * The list of labels is limited to:
4 | * 16 different dynamic labels if no static labels are defined.
5 | Additional labels will all record to the special label `__other__`.
6 | These labels may contain any UTF-8 characters.
7 | * 100 labels if specified as static labels in `metrics.yaml`, see [Labels](#labels).
8 | Unknown labels will be recorded under the special label `__other__`.
9 | These labels may only be made of printable ASCII characters.
10 |
--------------------------------------------------------------------------------
/docs/user/_includes/labels-parameter.md:
--------------------------------------------------------------------------------
1 | #### `labels`
2 |
3 | Labeled metrics may have an optional `labels` parameter, containing a list of known labels.
4 | The labels in this list must match the following requirements:
5 |
6 | * Conform to the [label format](index.md#label-format).
7 | * Each label must have a maximum of 111 characters.
8 | * Each label must only contain printable ASCII characters.
9 | * This list itself is limited to 4096 labels.
10 |
11 | {{#include ../../shared/blockquote-warning.html}}
12 |
13 | ##### Important
14 |
15 | > If the labels are specified in the `metrics.yaml`, using any label not listed in that file
16 | > will be replaced with the special value `__other__`.
17 | >
18 | > If the labels are **not** specified in the `metrics.yaml`, only 16 different dynamic labels
19 | > may be used, after which the special value `__other__` will be used.
20 |
21 | Removing or changing labels, including their order in the registry file, is permitted. Avoid reusing labels
22 | that were removed in the past. It is best practice to add documentation about removed labels to the
23 | description field so that analysts will know of their existence and meaning in historical data.
24 | Special care must be taken when changing GeckoView metrics sent through the Glean SDK, as the
25 | index of the labels is used to report Gecko data through the Glean SDK.
26 |
--------------------------------------------------------------------------------
/docs/user/_includes/lifetimes-parameters.md:
--------------------------------------------------------------------------------
1 | ##### `ping` _(default)_
2 |
3 | The metric is cleared each time it is submitted in the ping. This is the most common case,
4 | and should be used for metrics that are highly dynamic, such as things computed
5 | in response to the user's interaction with the application.
6 |
7 | ##### `application`
8 |
9 | The metric is related to an application run, and is cleared after the application restarts
10 | and any Glean-owned ping, due at startup, is submitted. This should be used for things
11 | that are constant during the run of an application, such as the operating system version.
12 | In practice, these metrics are generally set during application startup. A common mistake---
13 | using the ping lifetime for these type of metrics---means that they will only be included
14 | in the first ping sent during a particular run of the application.
15 |
16 | ##### `user`
17 |
18 | **NOTE: Reach out to the Glean team before using this.**
19 |
20 | The metric is part of the user's profile and will live as long as the profile lives.
21 | This is often not the best choice unless the metric records a value that _really_ needs
22 | to be persisted for the full lifetime of the user profile, e.g. an identifier like the `client_id`,
23 | the day the product was first executed. It is rare to use this lifetime outside of some metrics
24 | that are built in to the Glean SDK.
25 |
--------------------------------------------------------------------------------
/docs/user/_includes/string-errors.md:
--------------------------------------------------------------------------------
1 | * [`invalid_overflow`](../../user/metrics/error-reporting.md):
2 | * If the string value is too long. (Prior to Glean v31.5.0 this was recorded as `invalid_value`.)
3 | * [`invalid_type`](../../user/metrics/error-reporting.md):
4 | * If a non-string value is provided.
5 |
--------------------------------------------------------------------------------
/docs/user/_includes/string-limits.md:
--------------------------------------------------------------------------------
1 | * String values must not exceed 255 bytes of UTF-8. Longer strings will be truncated.
2 | * Prior to Glean v60.4.0 the limit was 100 bytes.
3 |
--------------------------------------------------------------------------------
/docs/user/appendix/changelog/index.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | - [`mozilla/glean`](./sdk.md)
4 | - [`mozilla/glean.js`](./js.md)
5 |
--------------------------------------------------------------------------------
/docs/user/appendix/index.md:
--------------------------------------------------------------------------------
1 | # Appendix
2 |
3 | The following sections contain other material related to Glean.
4 |
--------------------------------------------------------------------------------
/docs/user/book.toml:
--------------------------------------------------------------------------------
1 | [book]
2 | title = "Glean SDKs - Cross-platform Telemetry Libraries"
3 | authors = ["Glean Team"]
4 | src = "."
5 |
6 | [build]
7 | build-dir = "book"
8 | create-missing = false
9 |
10 | [output.html]
11 | additional-css = ["../shared/glean.css", "../shared/mermaid.css"]
12 | additional-js = ["../shared/tabs.js", "../shared/mermaid.min.js", "../shared/mermaid-init.js", "chart.min.js", "chart-distributions.js", "chart-distributions-ui.js"]
13 | git-repository-url = "https://github.com/mozilla/glean"
14 | edit-url-template = "https://github.com/mozilla/glean/edit/main/docs/user/{path}"
15 | git-branch = "main"
16 | mathjax-support = true
17 |
18 | [output.html.fold]
19 | enable = true
20 | level = 0
21 |
22 | [preprocessor.open-on-gh]
23 | command = "mdbook-open-on-gh"
24 |
--------------------------------------------------------------------------------
/docs/user/glean.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/glean.jpeg
--------------------------------------------------------------------------------
/docs/user/language-bindings/android/gecko-content-processes-and-glean.md:
--------------------------------------------------------------------------------
1 | ## GeckoView Content Processes and Glean
2 |
3 | This is a brief overview of how GeckoView content processes record data in Glean, despite Glean being required to be called only from the main process.
4 |
5 | ### GeckoView Content Processes
6 |
7 | These are processes in which web page's content is rendered and data is collected such as [use counters](https://firefox-source-docs.mozilla.org/dom/use-counters.html).
8 |
9 | Content processes are [launched as a "child" of the main GeckoView UI process](https://firefox-source-docs.mozilla.org/dom/ipc/process_model.html).
10 |
11 | ### Recording Telemetry in Content Processes
12 |
13 | Content processes communicate to the main GeckoView process through Inter-Thread and Inter-Process Message Passing ([IPDL](https://firefox-source-docs.mozilla.org/ipc/ipdl.html). Because Glean doesn't know about processes, it requires only a single process to interact with the API in order to work properly so content processes record data on the main process through IPDL, specifically through the Firefox on Glean (FOG) [IPC implementation](https://firefox-source-docs.mozilla.org/toolkit/components/glean/index.html).
14 |
15 | As long as processes within gecko make use of these mechanisms, data recorded in them should make it into Glean whether it is running in Desktop or Android.
16 |
17 |
--------------------------------------------------------------------------------
/docs/user/language-bindings/android/index.md:
--------------------------------------------------------------------------------
1 | # Android-specific information
2 |
3 | The Glean Kotlin SDK can be used in Android applications.
4 | The integration into the build system for Android applications can be tuned to your needs.
5 | See the following chapters for details.
6 |
--------------------------------------------------------------------------------
/docs/user/language-bindings/ios/index.md:
--------------------------------------------------------------------------------
1 | # iOS-specific information
2 |
3 | The Glean Swift SDK can be used in iOS applications.
4 | The integration into the build system for iOS applications can be tuned to your needs.
5 | See the following chapters for details.
6 |
--------------------------------------------------------------------------------
/docs/user/language-bindings/javascript/index.md:
--------------------------------------------------------------------------------
1 | # Glean JavaScript SDK
2 |
3 | The Glean JavaScript SDK allows integration with three distinct JavaScript environments: websites,
4 | web extension and Node.js.
5 |
6 | It is available as [`@mozilla/glean` on npm](https://www.npmjs.com/package/@mozilla/glean).
7 | This package has different entry points to access the different SDKs.
8 |
9 | - `@mozilla/glean/web` gives access to the websites SDK
10 | - `@mozilla/glean/webext` gives access to the web extension SDK
11 | - `@mozilla/glean/node` gives access to the Node.js SDK
12 |
--------------------------------------------------------------------------------
/docs/user/language-bindings/javascript/plugins/index.md:
--------------------------------------------------------------------------------
1 | # Plugins
2 |
3 | The Glean JavaScript SDK accepts a plugin array as an initialization parameter.
4 |
5 | ```js
6 | import Glean from "@mozilla/glean/webext"
7 | // This is not a real available plugin,
8 | // it is a hypothetical one for illustration purposes.
9 | import HypotheticalPlugin from "@mozilla/glean/plugins/hypothetical"
10 |
11 | Glean.initialize(
12 | "my.fancy.modified.app",
13 | uploadStatus,
14 | {
15 | plugins: [
16 | new HypotheticalPlugin("with", "hypothetical", "arguments")
17 | ]
18 | }
19 | );
20 | ```
21 |
22 | Plugins attach to specific internal events on the SDK and can modify its behavior.
23 |
24 | A big advantage of plugins is that they can address very specific use cases of Glean without bloating the final size of the SDK or overloading Glean's configuration object.
25 |
26 | {{#include ../../../../shared/blockquote-info.html}}
27 |
28 | ## On writing your own plugins
29 |
30 | > It is not currently possible for users to write their own plugins,
31 | > as this feature is still in its infancy.
32 |
33 | ## Available plugins
34 |
35 | ### [PingEncryptionPlugin](./encryption.md)
36 |
37 | The `PingEncryptionPlugin` encrypts the pings payloads before pings are sent.
38 |
--------------------------------------------------------------------------------
/docs/user/reference/debug/index.md:
--------------------------------------------------------------------------------
1 | # Debugging
2 |
3 | Different platforms have different ways to enable each debug functionality. They may be
4 | enabled
5 |
6 | - through APIs exposed on the Glean singleton,
7 | - through environment variables set at run time,
8 | - or through platform specific debug tools.
9 |
10 | ## Platform Specific Information
11 |
12 | Check out the platform specific guides on how to use Glean's debug functionalities.
13 |
14 | 1. [Debugging applications using the Glean Android SDK](../../user/debugging/android.md)
15 | 2. [Debugging applications using the Glean iOS SDK](../../user/debugging/ios.md)
16 | 3. [Debugging applications using the Glean Python SDK](../../user/debugging/python.md)
17 | 4. [Debugging applications using the Glean JavaScript SDK](../../user/debugging/javascript.md)
18 |
19 | ## Features
20 |
21 | The Glean SDKs provides four debugging features.
22 |
23 | ### [Log Pings](./logPings.md)
24 |
25 | This is either true or false and will cause all subsequent pings that are submitted, to also be echoed to the device's log.
26 |
27 | ### [Debug View Tag](./debugViewTag.md)
28 |
29 | This will tag all subsequent outgoing pings with the provided value, in order to identify them in the [Glean Debug View](../../user/debugging/index.html#glean-debug-view).
30 |
31 | ### [Source Tags](./logPings.md)
32 |
33 | This will tag all subsequent outgoing pings with a maximum of 5 comma-separated tags.
34 |
35 | ### Send Pings
36 |
37 | _This feature is only available for the Kotlin and Swift SDKs and in Firefox Desktop via `about:glean`._
38 |
39 | This expects the name of a ping and forces its immediate submission.
40 |
--------------------------------------------------------------------------------
/docs/user/reference/debug/screenshots/debug_view_tag_screenshot_swift.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/reference/debug/screenshots/debug_view_tag_screenshot_swift.png
--------------------------------------------------------------------------------
/docs/user/reference/debug/screenshots/log_pings_screenshot_swift.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/reference/debug/screenshots/log_pings_screenshot_swift.png
--------------------------------------------------------------------------------
/docs/user/reference/debug/screenshots/source_tags_screenshot_swift.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/reference/debug/screenshots/source_tags_screenshot_swift.png
--------------------------------------------------------------------------------
/docs/user/reference/yaml/index.md:
--------------------------------------------------------------------------------
1 | # YAML Registry Format
2 |
3 | User defined Glean pings and metrics are declared in YAML files, which must be parsed by
4 | [`glean_parser`](https://pypi.org/project/glean-parser/) to generate public APIs
5 | for said metrics and pings.
6 |
7 | These files also serve the purpose of documenting metrics and pings. They are consumed by the
8 | [`probe-scraper`](https://github.com/mozilla/probe-scraper) tool, which generates a REST API to
9 | access metrics and pings information consumed by most other tools in the Glean ecosystem, such as
10 | [GLAM](https://glam.telemetry.mozilla.org/) and [the Glean Dictionary](https://dictionary.telemetry.mozilla.org/).
11 |
12 | Moreover, for products that do not wish to use the Glean Dictionary as their metrics and pings documentation source, `glean_parser` provides an option to generate Markdown documentation for metrics and pings based on these files. For more information of that, refer to the help output
13 | of the `translate` command, by running in your terminal:
14 |
15 | ```bash
16 | $ glean_parser translate --help
17 | ```
18 |
19 | ## `metrics.yaml` file
20 |
21 | For a full reference on the `metrics.yaml` format, refer to the
22 | [Metrics YAML Registry Format](metrics.md) page.
23 |
24 | ## `pings.yaml` file
25 |
26 | For a full reference on the `pings.yaml` format, refer to the
27 | [Pings YAML Registry Format](pings.md) page.
28 |
29 | ## `tags.yaml` file
30 |
31 | For a full reference on the `tags.yaml` format, refer to the
32 | [Tags YAML Registry Format](tags.md) page.
33 |
--------------------------------------------------------------------------------
/docs/user/user/howto/index.md:
--------------------------------------------------------------------------------
1 | # How-tos
2 |
3 | This chapter contains various how-tos and walkthroughs to help aid you in using Glean.
4 |
5 | ### [Server Knobs Walkthrough]
6 |
7 | A step-by-step guide in setting up and launching a Server Knobs Experiment.
8 |
9 | ### ["Real-Time" Events]
10 |
11 | A guide describing the different methods to collect and transmit data in a "real-time" fashion using Glean.
12 |
13 | ### [Telemetry/Data Bug Investigation Recommendations]
14 |
15 | Recommendations and tips on investigating data anomalies.
16 |
17 | [Server Knobs Walkthrough]: ./server-knobs-walkthrough/server-knobs-walkthrough.md
18 | ["Real-Time" Events]: ./real-time-events/real-time-events.md
19 | [Telemetry/Data Bug Investigation Recommendations]: ./investigating-data-issues/investigating-data-issues.md
20 |
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image1.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image10.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image11.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image12.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image13.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image14.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image15.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image16.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image17.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image18.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image19.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image2.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image20.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image21.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image21.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image3.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image4.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image5.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image6.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image7.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image8.png
--------------------------------------------------------------------------------
/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/docs/user/user/howto/server-knobs-walkthrough/images/sk_walkthrough_image9.png
--------------------------------------------------------------------------------
/docs/user/user/metrics/index.md:
--------------------------------------------------------------------------------
1 | # Metrics
2 |
3 | In this chapter we describe how to define and use the Glean SDK's metrics.
4 |
--------------------------------------------------------------------------------
/docs/user/user/pings/testing-custom-pings.md:
--------------------------------------------------------------------------------
1 | # Testing custom pings
2 |
3 | Applications defining [custom pings](custom.md) can use use the [ping testing API](../../reference/pings/index.md#testing-api) to test these pings in unit tests.
4 |
5 | ## General testing strategy
6 |
7 | The schedule of custom pings depends on the specific application implementation, since it is up to the SDK user to define the ping semantics. This makes the testing strategy a bit more complex, but usually boiling down to:
8 |
9 | 1. Triggering the code path that accumulates/records the data.
10 | 2. Defining a callback validation function using the [ping testing API](../../reference/pings/index.md#testbeforenextsubmit).
11 | 3. Finally triggering the code path that submits the custom ping or submitting the ping using the [`submit` API](../../reference/pings/index.md#submit).
12 |
--------------------------------------------------------------------------------
/docs/user/user/server-knobs/index.md:
--------------------------------------------------------------------------------
1 | # Server Knobs: Glean Data Control Plane
2 |
3 | Glean provides Server Knobs, a Data [Control Plane] through which Glean runtime settings can be changed remotely including the ability to enable, disable or throttle metrics and pings through a [Nimbus] rollout or experiment.
4 |
5 | Products can use this capability to control "data traffic", similar to how a network control plane controls "network traffic".
6 |
7 | Server Knobs provides the ability to do the following:
8 |
9 | - Allow runtime changes to data collection without needing to land code and ride release trains.
10 | - Eliminate the need for manual creation and maintenance of feature flags specific to data collection.
11 | - Sampling of measurements from a subset of the population so that we do not collect or ingest more data than is necessary from high traffic areas of an application instrumented with Glean metrics.
12 | - Operational safety through being able to react to high-volume or unwanted data.
13 | - Visibility into sampling and sampling rates for remotely configured metrics.
14 |
15 | ## Contents
16 |
17 | - [Controlling Metrics with Server Knobs]
18 | - [Controlling Pings with Server Knobs]
19 | - [Other Server Knobs]
20 |
21 | [Control Plane]: https://en.wikipedia.org/wiki/Control_plane
22 | [Nimbus]: https://experimenter.info
23 | [Controlling Metrics with Server Knobs]: ./metrics/index.md
24 | [Controlling Pings with Server Knobs]: ./pings/index.md
25 | [Other Server Knobs]: ./other/index.md
--------------------------------------------------------------------------------
/docs/user/user/server-knobs/metrics/experimenter-configuration.md:
--------------------------------------------------------------------------------
1 | # Experimenter Configuration
2 |
3 | The structure of this configuration is a key-value collection with the full metric identification of the Glean metric serving as the key in the format .
4 |
5 | The values of the key-value pair are booleans which represent whether the metric is enabled (`true`) or not (`false`).
6 |
7 | In the example below `gleanMetricConfiguration` is the name of the variable defined in the Nimbus feature.
8 |
9 | This configuration would be what is entered into the branch configuration setup in Experimenter when defining an experiment or rollout.
10 |
11 | ## Example Configuration:
12 |
13 | ```json
14 | {
15 | "gleanMetricConfiguration": {
16 | "metrics_enabled": {
17 | "urlbar.abandonment": true,
18 | "urlbar.engagement": true,
19 | "urlbar.impression": true
20 | }
21 | }
22 | }
23 | ```
24 |
--------------------------------------------------------------------------------
/docs/user/user/server-knobs/metrics/faq.md:
--------------------------------------------------------------------------------
1 | # Frequently Asked Questions
2 |
3 | * How can I tell if a given client id has the metric X on?
4 |
5 | Once we have established the functionality behind the data control plane, a dashboard for monitoring this will be provided. Details are to be determined.
6 |
7 | * Why isn't some client id reporting the metric that should be enabled for all the clients for that channel? (e.g. Some fraction of population may get stuck on “default” config)
8 |
9 | Nimbus must be able to both reach and supply a valid configuration to the audience. For some outliers this doesn't work and so may be "unreachable" at times.
10 |
--------------------------------------------------------------------------------
/docs/user/user/server-knobs/metrics/index.md:
--------------------------------------------------------------------------------
1 | # Data Control Plane (a.k.a. Server Knobs)
2 |
3 | Glean provides a Data [Control Plane] through which metrics can be enabled, disabled or throttled through a [Nimbus] rollout or experiment.
4 |
5 | Products can use this capability to control "data-traffic", similar to how a network control plane controls "network-traffic".
6 |
7 | This provides the ability to do the following:
8 |
9 | - Allow runtime changes to data collection without needing to land code and ride release trains.
10 | - Eliminate the need for manual creation and maintenance of feature flags specific to data collection.
11 | - Sampling of measurements from a subset of the population so that we do not collect or ingest more data than is necessary from high traffic areas of an application instrumented with Glean metrics.
12 | - Operational safety through being able to react to high-volume or unwanted data.
13 | - Visibility into sampling and sampling rates for remotely configured metrics.
14 |
15 | For information on controlling pings with Server Knobs, see the metrics documentation for [Server Knobs - Pings].
16 |
17 | ## Contents
18 | - [Example Scenarios](./example-scenarios.md)
19 | - [Product Integration](./product-integration.md)
20 | - [Experimenter Configuration](./experimenter-configuration.md)
21 | - [Advanced Topics](./advanced-topics.md)
22 | - [Frequently Asked Questions](./faq.md)
23 |
24 | [Control Plane]: https://en.wikipedia.org/wiki/Control_plane
25 | [Nimbus]: https://experimenter.info
26 | [Server Knobs - Pings]: ../pings/index.md
--------------------------------------------------------------------------------
/docs/user/user/server-knobs/other/index.md:
--------------------------------------------------------------------------------
1 | # Other Server Knobs
2 |
3 | Below are additional Glean parameters and settings that are exposed via Server Knobs for use in a [Nimbus] experiment or rollout.
4 |
5 | ## Contents
6 | - [Max Events per Event Ping]
7 |
8 | Additional Glean settings will be added to Server Knobs as needed or by request.
9 |
10 | > *For information on controlling metrics and pings via Server Knobs, please refer to [Controlling Metrics with Server Knobs] and [Controlling Pings with Server Knobs].*
11 |
12 | [Nimbus]: https://experimenter.info
13 | [Controlling Metrics with Server Knobs]: ../metrics/index.md
14 | [Controlling Pings with Server Knobs]: ../pings/index.md
15 | [Max Events per Event Ping]: ./max-events.md
--------------------------------------------------------------------------------
/docs/user/user/server-knobs/other/max-events.md:
--------------------------------------------------------------------------------
1 | # Max Events
2 |
3 | By default, Glean batches events together to submit on a single events ping.
4 | The `event_threshold` Server Knob controls how many events Glean will collect before submitting an events ping.
5 |
6 | For instance, if you wanted to disable batching in order to transmit an events ping after every event is recorded you could set `event_threshold: 1`.
7 |
8 | ## Example Configuration:
9 |
10 | ```json
11 | {
12 | "gleanMetricConfiguration": {
13 | "event_threshold": 1
14 | }
15 | }
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/user/user/server-knobs/pings/experimenter-configuration.md:
--------------------------------------------------------------------------------
1 | # Experimenter Configuration
2 |
3 | The structure of this configuration is a key-value collection with the name of the Glean ping serving as the keys and the values are booleans representing whether the ping is enabled (`true`) or not (`false`).
4 |
5 | In the example below, `gleanMetricConfiguration` is the name of the variable defined in the Nimbus feature.
6 |
7 | This configuration would be what is entered into the branch configuration setup in Experimenter when defining an experiment or rollout.
8 |
9 | ## Example Configuration:
10 |
11 | ```json
12 | {
13 | "gleanMetricConfiguration": {
14 | "pings_enabled": {
15 | "baseline": false,
16 | "events": false,
17 | "metrics": false
18 | }
19 | }
20 | }
21 | ```
22 |
--------------------------------------------------------------------------------
/docs/user/user/server-knobs/pings/index.md:
--------------------------------------------------------------------------------
1 | # Data Control Plane (a.k.a. Server Knobs)
2 |
3 | Glean provides a Data [Control Plane] through which pings can be enabled or disabled through a [Nimbus] rollout or experiment.
4 |
5 | Products can use this capability to control "data-traffic", similar to how a network control plane controls "network-traffic".
6 |
7 | This provides the ability to do the following:
8 |
9 | - Allow runtime changes to data collection without needing to land code and ride release trains.
10 | - Eliminate the need for manual creation and maintenance of feature flags specific to data collection.
11 | - Sampling of measurements from a subset of the population so that we do not collect or ingest more data than is necessary from high traffic areas of an application instrumented with Glean metrics.
12 | - Operational safety through being able to react to high-volume or unwanted data.
13 | - Visibility into sampling and sampling rates for remotely configured metrics.
14 |
15 | For information on controlling metrics with Server Knobs, see the metrics documentation for [Server Knobs - Metrics].
16 |
17 | ## Contents
18 | - [Product Integration](./product-integration.md)
19 | - [Experimenter Configuration](./experimenter-configuration.md)
20 |
21 | [Control Plane]: https://en.wikipedia.org/wiki/Control_plane
22 | [Nimbus]: https://experimenter.info
23 | [Server Knobs - Metrics]: ../metrics/index.md
--------------------------------------------------------------------------------
/docs/user/user/server-knobs/pings/product-integration.md:
--------------------------------------------------------------------------------
1 | # Product Integration
2 |
3 | Glean provides a general Nimbus feature named `glean` that can be used for configuration of pings. Simply select the `glean` feature along with your Nimbus feature from the Experimenter UI when configuring the experiment or rollout (see [Nimbus] documentation for more information on multi-feature experiments).
4 |
5 | The `glean` Nimbus feature requires the `gleanMetricConfiguration` variable to be used to provide the required metric configuration. The format of the configuration is defined in the [Experimenter Configuration] section.
6 | If a ping is not included, it will default to the value found in the pings.yaml.
7 | Note that this can also serve as an override for Glean builtin pings disabled using the Configuration property `enable_internal_pings=false` during initialization.
8 |
9 | [Experimenter Configuration]: ./experimenter-configuration.md
10 | [Nimbus]: https://experimenter.info
11 | [Nimbus Desktop Feature API]: https://experimenter.info/desktop-feature-api
12 |
--------------------------------------------------------------------------------
/glean-core/android-native/proguard-rules-consumer.pro:
--------------------------------------------------------------------------------
1 | # ProGuard rules for consumers of this library.
2 |
3 | # JNA specific rules
4 | # See https://github.com/java-native-access/jna/blob/master/www/FrequentlyAskedQuestions.md#jna-on-android
5 | -dontwarn java.awt.*
6 | -keep class com.sun.jna.* { *; }
7 | -keepclassmembers class * extends com.sun.jna.* { public *; }
8 |
--------------------------------------------------------------------------------
/glean-core/android-native/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/glean-core/android-native/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/glean-core/android/metrics.yaml:
--------------------------------------------------------------------------------
1 | # This Source Code Form is subject to the terms of the Mozilla Public
2 | # License, v. 2.0. If a copy of the MPL was not distributed with this
3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 |
5 | # This file defines the metrics that are recorded by the Glean SDK.
6 | # APIs to use these metrics are automatically generated at build time using
7 | # the `glean_parser` PyPI package.
8 |
9 | # Metrics in this file may make use of SDK reserved ping names. See
10 | # https://mozilla.github.io/glean/book/dev/core/internal/reserved-ping-names.html
11 | # for additional information.
12 |
13 | ---
14 | $schema: moz://mozilla.org/schemas/glean/metrics/2-0-0
15 |
16 | glean.internal.metrics:
17 | android_sdk_version:
18 | type: string
19 | lifetime: application
20 | send_in_pings:
21 | - glean_client_info
22 | description: |
23 | The optional Android specific SDK version of the software running on this
24 | hardware device.
25 | bugs:
26 | - https://bugzilla.mozilla.org/1525606
27 | data_reviews:
28 | - https://bugzilla.mozilla.org/show_bug.cgi?id=1525606#c14
29 | data_sensitivity:
30 | - technical
31 | notification_emails:
32 | - glean-team@mozilla.com
33 | expires: never
34 |
--------------------------------------------------------------------------------
/glean-core/android/proguard-rules-consumer.pro:
--------------------------------------------------------------------------------
1 | # ProGuard rules for consumers of this library.
2 |
3 | # JNA specific rules
4 | # See https://github.com/java-native-access/jna/blob/master/www/FrequentlyAskedQuestions.md#jna-on-android
5 | -dontwarn java.awt.*
6 | -keep class com.sun.jna.* { *; }
7 | -keepclassmembers class * extends com.sun.jna.* { public *; }
8 |
9 | # Glean specific rules
10 | -keep class mozilla.telemetry.** { *; }
11 |
12 | # The Glean SDK ships with classes used for tests as well. They are disabled
13 | # and not directly usable in production code: they throw if used there. They
14 | # can be used in tests just fine but, outside of tests, the test dependency
15 | # they use won't be there, hence the warning. It's safe to suppress these.
16 | -dontwarn mozilla.telemetry.glean.testing.**
17 |
--------------------------------------------------------------------------------
/glean-core/android/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/net/BaseUploader.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.net
6 |
7 | /**
8 | * The logic for uploading pings: this leaves the actual upload implementation
9 | * to the user-provided delegate.
10 | */
11 | class BaseUploader(d: PingUploader) : PingUploader by d {
12 | /**
13 | * This function triggers the actual upload: logs the ping and calls the implementation
14 | * specific upload function.
15 | *
16 | * @param request the ping upload request, locked within a capability check
17 | *
18 | * @return return the status code of the upload response
19 | */
20 | internal fun doUpload(request: CapablePingUploadRequest): UploadResult {
21 | return upload(request)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/net/PingUploader.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.net
6 |
7 | /**
8 | * Store a list of headers as a String to String [Pair], with the first entry
9 | * being the header name and the second its value.
10 | */
11 | typealias HeadersList = Map
12 |
13 | /**
14 | * The interface defining how to send pings.
15 | */
16 | interface PingUploader {
17 | /**
18 | * Synchronously upload a ping to a server.
19 | *
20 | * @param request the ping upload request, locked within a uploader capability check
21 | *
22 | * @return return the status code of the upload response,
23 | */
24 | fun upload(request: CapablePingUploadRequest): UploadResult
25 | }
26 |
27 | data class PingUploadRequest(
28 | val url: String,
29 | val data: ByteArray,
30 | val headers: HeadersList,
31 | val uploaderCapabilities: List,
32 | )
33 |
34 | class CapablePingUploadRequest(val request: PingUploadRequest) {
35 | fun capable(f: (uploaderCapabilities: List) -> Boolean): PingUploadRequest? {
36 | if (f(request.uploaderCapabilities)) {
37 | return request
38 | }
39 | return null
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/net/Upload.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.net
6 |
7 | typealias PingUploadTask = mozilla.telemetry.glean.internal.PingUploadTask
8 | typealias PingRequest = mozilla.telemetry.glean.internal.PingRequest
9 | typealias UploadResult = mozilla.telemetry.glean.internal.UploadResult
10 | typealias HttpStatus = mozilla.telemetry.glean.internal.UploadResult.HttpStatus
11 | typealias UnrecoverableFailure = mozilla.telemetry.glean.internal.UploadResult.UnrecoverableFailure
12 | typealias RecoverableFailure = mozilla.telemetry.glean.internal.UploadResult.RecoverableFailure
13 | typealias Incapable = mozilla.telemetry.glean.internal.UploadResult.Incapable
14 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/private/BooleanMetricType.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.private
6 |
7 | /**
8 | * This implements the developer facing API for recording boolean metrics.
9 | *
10 | * Instances of this class type are automatically generated by the parsers at build time,
11 | * allowing developers to record values that were previously registered in the metrics.yaml file.
12 | *
13 | * The boolean API only exposes the [set] method.
14 | */
15 | typealias BooleanMetricType = mozilla.telemetry.glean.internal.BooleanMetric
16 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/private/CounterMetricType.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.private
6 |
7 | /**
8 | * This implements the developer facing API for recording counter metrics.
9 | *
10 | * Instances of this class type are automatically generated by the parsers at build time,
11 | * allowing developers to record values that were previously registered in the metrics.yaml file.
12 | *
13 | * The counter API only exposes the [add] method, which takes care of validating the input
14 | * data and making sure that limits are enforced.
15 | */
16 | typealias CounterMetricType = mozilla.telemetry.glean.internal.CounterMetric
17 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/private/DenominatorMetricType.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.private
6 |
7 | /**
8 | * This implements the developer facing API for recording a denominator of a rate metric,
9 | * where the denominator is external.
10 | * It is essentially a wrapper around `CounterMetricType`.
11 | *
12 | * Instances of this class type are automatically generated by the parsers at build time,
13 | * allowing developers to record values that were previously registered in the metrics.yaml file.
14 | *
15 | * The denominator API exposes the [add] method,
16 | * which takes care of validating the input data and making sure that limits are enforced.
17 | */
18 | typealias DenominatorMetricType = mozilla.telemetry.glean.internal.DenominatorMetric
19 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/private/HistogramBase.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.private
6 |
7 | /**
8 | * A common interface to be implemented by all the histogram-like metric types
9 | * supported by the Glean SDK.
10 | */
11 | interface HistogramBase {
12 | /**
13 | * Accumulates the provided samples in the metric.
14 | *
15 | * Please note that this assumes that the provided samples are already in the
16 | * "unit" declared by the instance of the implementing metric type (e.g. if the
17 | * implementing class is a [TimingDistributionMetricType] and the instance this
18 | * method was called on is using [TimeUnit.SECOND], then `samples` are assumed
19 | * to be in that unit).
20 | *
21 | * @param samples the [List] holding the samples to be recorded by the metric.
22 | */
23 | fun accumulateSamples(samples: List)
24 | }
25 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/private/MemoryDistributionMetricType.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.private
6 |
7 | import androidx.annotation.VisibleForTesting
8 | import mozilla.telemetry.glean.internal.MemoryDistributionMetric
9 | import mozilla.telemetry.glean.testing.ErrorType
10 |
11 | /**
12 | * This implements the developer facing API for recording memory distribution metrics.
13 | *
14 | * Instances of this class type are automatically generated by the parsers at build time,
15 | * allowing developers to record values that were previously registered in the metrics.yaml file.
16 | */
17 | class MemoryDistributionMetricType(meta: CommonMetricData, memoryUnit: MemoryUnit) : HistogramBase {
18 | val inner = MemoryDistributionMetric(meta, memoryUnit)
19 |
20 | /**
21 | * Delegate common methods to the underlying type directly.
22 | */
23 |
24 | fun accumulate(sample: Long) = inner.accumulate(sample)
25 |
26 | override fun accumulateSamples(samples: List) = inner.accumulateSamples(samples)
27 |
28 | /**
29 | * Testing-only methods get an annotation
30 | */
31 |
32 | @VisibleForTesting(otherwise = VisibleForTesting.NONE)
33 | @JvmOverloads
34 | fun testGetValue(pingName: String? = null) = inner.testGetValue(pingName)
35 |
36 | @VisibleForTesting(otherwise = VisibleForTesting.NONE)
37 | fun testGetNumRecordedErrors(error: ErrorType) = inner.testGetNumRecordedErrors(error)
38 | }
39 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/private/NumeratorMetricType.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.private
6 |
7 | /**
8 | * This implements the developer facing API for recording the numerator of a rate metric
9 | * with an external denominator.
10 | *
11 | * Instances of this class type are automatically generated by the parsers at build time,
12 | * allowing developers to record values that were previously registered in the metrics.yaml file.
13 | *
14 | * The numerator API exposes the [addToNumerator] method,
15 | * which takes care of validating the input data and making sure that limits are enforced.
16 | */
17 | typealias NumeratorMetricType = mozilla.telemetry.glean.internal.NumeratorMetric
18 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/private/QuantityMetricType.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.private
6 |
7 | /**
8 | * This implements the developer facing API for recording quantity metrics.
9 | *
10 | * Instances of this class type are automatically generated by the parsers at build time,
11 | * allowing developers to record values that were previously registered in the metrics.yaml file.
12 | *
13 | * The quantity API only exposes the [set] method.
14 | */
15 | typealias QuantityMetricType = mozilla.telemetry.glean.internal.QuantityMetric
16 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/private/RateMetricType.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.private
6 |
7 | /**
8 | * This implements the developer facing API for recording rate metrics.
9 | *
10 | * Instances of this class type are automatically generated by the parsers at build time,
11 | * allowing developers to record values that were previously registered in the metrics.yaml file.
12 | *
13 | * The rate API exposes the [addToNumerator] and [addToDenominator] method, which takes care of validating the input
14 | * data and making sure that limits are enforced.
15 | */
16 | typealias RateMetricType = mozilla.telemetry.glean.internal.RateMetric
17 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/private/StringListMetricType.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.private
6 |
7 | /**
8 | * This implements the developer facing API for recording string list metrics.
9 | *
10 | * Instances of this class type are automatically generated by the parsers at build time,
11 | * allowing developers to record values that were previously registered in the metrics.yaml file.
12 | *
13 | * The string list API only exposes the [add] and [set] methods, which takes care of validating the input
14 | * data and making sure that limits are enforced.
15 | */
16 | typealias StringListMetricType = mozilla.telemetry.glean.internal.StringListMetric
17 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/private/StringMetricType.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.private
6 |
7 | /**
8 | * This implements the developer facing API for recording string metrics.
9 | *
10 | * Instances of this class type are automatically generated by the parsers at build time,
11 | * allowing developers to record values that were previously registered in the metrics.yaml file.
12 | *
13 | * The string API only exposes the [set] method, which takes care of validating the input
14 | * data and making sure that limits are enforced.
15 | */
16 | typealias StringMetricType = mozilla.telemetry.glean.internal.StringMetric
17 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/private/TextMetricType.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.private
6 |
7 | /**
8 | * This implements the developer facing API for recording text metrics.
9 | *
10 | * Instances of this class type are automatically generated by the parsers at build time,
11 | * allowing developers to record values that were previously registered in the metrics.yaml file.
12 | *
13 | * The text API only exposes the [set] method, which takes care of validating the input
14 | * data and making sure that limits are enforced.
15 | */
16 | typealias TextMetricType = mozilla.telemetry.glean.internal.TextMetric
17 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/private/TimespanMetricType.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.private
6 |
7 | /**
8 | * This implements the developer facing API for recording timespans.
9 | *
10 | * Instances of this class type are automatically generated by the parsers at build time,
11 | * allowing developers to record values that were previously registered in the metrics.yaml file.
12 | *
13 | * The timespans API exposes the [start], [stop] and [cancel] methods.
14 | */
15 | typealias TimespanMetricType = mozilla.telemetry.glean.internal.TimespanMetric
16 |
17 | /**
18 | * Convenience method to simplify measuring a function or block of code
19 | *
20 | * If the measured function throws, the measurement is canceled and the exception rethrown.
21 | */
22 | @Suppress("TooGenericExceptionCaught")
23 | fun TimespanMetricType.measure(funcToMeasure: () -> U): U {
24 | this.start()
25 |
26 | val returnValue = try {
27 | funcToMeasure()
28 | } catch (e: Exception) {
29 | this.cancel()
30 | throw e
31 | }
32 |
33 | this.stop()
34 | return returnValue
35 | }
36 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/private/UrlMetricType.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.private
6 |
7 | /**
8 | * This implements the developer facing API for recording URL metrics.
9 | *
10 | * Instances of this class type are automatically generated by the parsers at build time,
11 | * allowing developers to record values that were previously registered in the metrics.yaml file.
12 | *
13 | * The URL API only exposes the [set] method, which takes care of validating the input
14 | * data and making sure that limits are enforced.
15 | */
16 | typealias UrlMetricType = mozilla.telemetry.glean.internal.UrlMetric
17 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/private/UuidMetricType.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.private
6 |
7 | import androidx.annotation.VisibleForTesting
8 | import mozilla.telemetry.glean.internal.UuidMetric
9 | import java.util.UUID
10 |
11 | /**
12 | * This implements the developer facing API for recording UUID metrics.
13 | *
14 | * Instances of this class type are automatically generated by the parsers at build time,
15 | * allowing developers to record values that were previously registered in the metrics.yaml file.
16 | *
17 | * The UUID API exposes the [generateAndSet] and [set] methods.
18 | *
19 | * The internal constructor is only used by [LabeledMetricType] directly.
20 | */
21 | class UuidMetricType(meta: CommonMetricData) {
22 | val inner = UuidMetric(meta)
23 |
24 | @VisibleForTesting(otherwise = VisibleForTesting.NONE)
25 | @JvmOverloads
26 | fun testGetValue(pingName: String? = null): UUID? {
27 | return inner.testGetValue(pingName)?.let { UUID.fromString(it) }
28 | }
29 |
30 | fun set(value: UUID) = inner.set(value.toString())
31 |
32 | fun generateAndSet(): UUID {
33 | val uuid = inner.generateAndSet()
34 | return UUID.fromString(uuid)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/testing/ErrorType.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.testing
6 |
7 | /**
8 | * Different types of errors that can be reported through Glean's error reporting metrics.
9 | */
10 | typealias ErrorType = mozilla.telemetry.glean.internal.ErrorType
11 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/utils/DataPathUtils.kt:
--------------------------------------------------------------------------------
1 | package mozilla.telemetry.glean.utils
2 |
3 | import java.io.File
4 |
5 | /**
6 | * Check if the data path provided is valid and writable.
7 | *
8 | * @param dataPath A [String] provided by the user to specify the path to store data.
9 | * @return True if the database path is valid and writable.
10 | */
11 | fun canWriteToDatabasePath(dataPath: String): Boolean {
12 | // Do not allow empty strings.
13 | if (dataPath.isEmpty()) {
14 | return false
15 | }
16 |
17 | // If the file exists we need to ensure we can write to it.
18 | val file = File(dataPath)
19 | if (file.exists()) {
20 | if (!file.canWrite()) {
21 | return false
22 | }
23 | }
24 |
25 | // The database path is valid and writable.
26 | return true
27 | }
28 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/utils/GzipUtils.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.utils
6 |
7 | import java.io.BufferedReader
8 | import java.io.ByteArrayInputStream
9 | import java.util.zip.GZIPInputStream
10 |
11 | /**
12 | * Decompress the GZIP returned by the glean-core layer.
13 | *
14 | * @param data the gzipped [ByteArray] to decompress
15 | * @return a [String] containing the uncompressed data.
16 | */
17 | fun decompressGZIP(data: ByteArray): String {
18 | return GZIPInputStream(ByteArrayInputStream(data)).bufferedReader().use(BufferedReader::readText)
19 | }
20 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/utils/JsonUtils.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.utils
6 |
7 | import org.json.JSONArray
8 | import org.json.JSONObject
9 |
10 | /**
11 | * Returns the value mapped by {@code key} if it exists, and
12 | * if the value returned is not null. If it's null, it returns null
13 | */
14 | fun JSONObject.tryGetLong(key: String): Long? = if (isNull(key)) null else getLong(key)
15 |
16 | /**
17 | * Convenience method to convert a JSONArray into a sequence.
18 | *
19 | * @param getter callback to get the value for an index in the array.
20 | */
21 | inline fun JSONArray.asSequence(crossinline getter: JSONArray.(Int) -> V): Sequence {
22 | val indexRange = 0 until length()
23 | return indexRange.asSequence().map { i -> getter(i) }
24 | }
25 |
26 | /**
27 | * Convenience method to convert a JSONArray into a sequence.
28 | */
29 | fun JSONArray.asSequence(): Sequence = asSequence { i -> get(i) }
30 |
31 | /**
32 | * Convenience method to convert a JSONArray into a List
33 | *
34 | * @return list with the JSONArray values, or an empty list if the JSONArray was null
35 | */
36 | @Suppress("UNCHECKED_CAST")
37 | fun JSONArray?.toList(): List {
38 | val array = this ?: return emptyList()
39 | return array.asSequence().map { it as T }.toList()
40 | }
41 |
--------------------------------------------------------------------------------
/glean-core/android/src/main/java/mozilla/telemetry/glean/utils/ThreadUtils.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.utils
6 |
7 | import android.os.Looper
8 |
9 | /**
10 | * Utilities related to threads.
11 | */
12 | object ThreadUtils {
13 | private val uiThread = Looper.getMainLooper().thread
14 |
15 | /**
16 | * Assert that this code is run on the main (UI) thread.
17 | */
18 | fun assertOnUiThread() {
19 | val currentThread = Thread.currentThread()
20 | val currentThreadId = currentThread.id
21 | val expectedThreadId = uiThread.id
22 |
23 | if (currentThreadId == expectedThreadId) {
24 | return
25 | }
26 |
27 | throw IllegalThreadStateException("Expected UI thread, but running on " + currentThread.name)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/glean-core/android/src/test/java/android/util/Log.java:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package android.util;
6 |
7 | /**
8 | * The purpose of this class is to avoid the "android.util.Log not mocked" exception when running
9 | * tests with the Android Log utility.
10 | *
11 | * This solution can be attributed to this Stack Overflow answer:
12 | * https://stackoverflow.com/a/46793567
13 | */
14 | public class Log {
15 | public static int d(String tag, String msg) {
16 | System.out.println("DEBUG: " + tag + ": " + msg);
17 | return 0;
18 | }
19 |
20 | public static int i(String tag, String msg) {
21 | System.out.println("INFO: " + tag + ": " + msg);
22 | return 0;
23 | }
24 |
25 | public static int w(String tag, String msg) {
26 | System.out.println("WARN: " + tag + ": " + msg);
27 | return 0;
28 | }
29 |
30 | public static int e(String tag, String msg) {
31 | System.out.println("ERROR: " + tag + ": " + msg);
32 | return 0;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/glean-core/android/src/test/java/mozilla/telemetry/glean/utils/DataPathUtilsTest.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 | */
5 |
6 | package mozilla.telemetry.glean.utils
7 |
8 | import android.content.Context
9 | import androidx.test.core.app.ApplicationProvider
10 | import androidx.test.ext.junit.runners.AndroidJUnit4
11 | import org.junit.Assert.assertFalse
12 | import org.junit.Assert.assertTrue
13 | import org.junit.Test
14 | import org.junit.runner.RunWith
15 |
16 | @RunWith(AndroidJUnit4::class)
17 | class DataPathUtilsTest {
18 | private val context: Context
19 | get() = ApplicationProvider.getApplicationContext()
20 |
21 | @Test
22 | fun `Cannot write to invalid database path`() {
23 | val customDataPath = ""
24 | assertFalse(canWriteToDatabasePath(customDataPath))
25 | }
26 |
27 | @Test
28 | fun `Can write to valid database path`() {
29 | val dataPath = context.applicationInfo.dataDir + "/valid_db_path"
30 | assertTrue(canWriteToDatabasePath(dataPath))
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/glean-core/android/src/test/java/mozilla/telemetry/glean/utils/DateUtilsTest.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 | */
5 |
6 | package mozilla.telemetry.glean.utils
7 |
8 | import androidx.test.ext.junit.runners.AndroidJUnit4
9 | import mozilla.telemetry.glean.private.TimeUnit
10 | import org.junit.Assert.assertEquals
11 | import org.junit.Test
12 | import org.junit.runner.RunWith
13 |
14 | @RunWith(AndroidJUnit4::class)
15 | class DateUtilsTest {
16 | @Test
17 | fun `test roundtripping ISO date formats`() {
18 | for (timeUnit in listOf(
19 | TimeUnit.NANOSECOND,
20 | TimeUnit.MICROSECOND,
21 | TimeUnit.MILLISECOND,
22 | TimeUnit.SECOND,
23 | TimeUnit.MINUTE,
24 | TimeUnit.HOUR,
25 | TimeUnit.DAY,
26 | )) {
27 | val dateString = getISOTimeString(truncateTo = timeUnit)
28 | val parsedDate = parseISOTimeString(dateString)!!
29 | val regenDateString = getISOTimeString(parsedDate, truncateTo = timeUnit)
30 | assertEquals(dateString, regenDateString)
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/glean-core/android/src/test/java/mozilla/telemetry/glean/utils/GzipUtilsTest.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 | */
5 |
6 | package mozilla.telemetry.glean.utils
7 |
8 | import org.junit.Assert.assertEquals
9 | import org.junit.Test
10 | import java.io.ByteArrayOutputStream
11 | import java.util.zip.GZIPOutputStream
12 |
13 | class GzipUtilsTest {
14 | private val testPing: String = "{ 'ping': 'test' }"
15 |
16 | @Test
17 | fun `gzip must be correctly decompressed`() {
18 | // Compress the test ping.
19 | val byteOutputStream = ByteArrayOutputStream()
20 | GZIPOutputStream(byteOutputStream).bufferedWriter(Charsets.UTF_8).use { it.write(testPing) }
21 | val compressedTestPing = byteOutputStream.toByteArray()
22 |
23 | // Decompress the result and check if it's valid.
24 | val decompressedPing = decompressGZIP(compressedTestPing)
25 | assertEquals(testPing, decompressedPing)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/glean-core/android/src/test/java/mozilla/telemetry/glean/utils/KArgumentCaptor.kt:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | package mozilla.telemetry.glean.utils
6 |
7 | import org.mockito.ArgumentCaptor
8 | import kotlin.reflect.KClass
9 |
10 | /**
11 | * Creates a [KArgumentCaptor] for given type.
12 | */
13 | inline fun argumentCaptor(): KArgumentCaptor {
14 | return KArgumentCaptor(ArgumentCaptor.forClass(T::class.java), T::class)
15 | }
16 |
17 | @Suppress("UnusedPrivateMember")
18 | class KArgumentCaptor(
19 | private val captor: ArgumentCaptor,
20 | private val tClass: KClass<*>,
21 | ) {
22 |
23 | /**
24 | * The first captured value of the argument.
25 | * @throws IndexOutOfBoundsException if the value is not available.
26 | */
27 | val value: T
28 | get() = captor.value
29 |
30 | val allValues: List
31 | get() = captor.allValues
32 |
33 | @Suppress("UNCHECKED_CAST")
34 | fun capture(): T {
35 | return captor.capture() ?: castNull()
36 | }
37 | }
38 |
39 | /**
40 | * Uses a quirk in the bytecode generated by Kotlin
41 | * to cast [null] to a non-null type.
42 | *
43 | * See https://youtrack.jetbrains.com/issue/KT-8135.
44 | */
45 | @Suppress("UNCHECKED_CAST")
46 | private fun castNull(): T = null as T
47 |
--------------------------------------------------------------------------------
/glean-core/android/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker:
--------------------------------------------------------------------------------
1 | mock-maker-inline
2 |
--------------------------------------------------------------------------------
/glean-core/android/src/test/resources/robolectric.properties:
--------------------------------------------------------------------------------
1 | # Provide a ShadowLog to remove the flood of 'CursorWindowStats' et al
2 | # from our logs.
3 | shadows=mozilla.telemetry.glean.shadows.ShadowLog
--------------------------------------------------------------------------------
/glean-core/build.rs:
--------------------------------------------------------------------------------
1 | fn main() {
2 | uniffi::generate_scaffolding("./src/glean.udl").unwrap();
3 | }
4 |
--------------------------------------------------------------------------------
/glean-core/build/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "glean-build"
3 | version = "17.1.0"
4 | edition = "2021"
5 | description = "Glean SDK Rust build helper"
6 | repository = "https://github.com/mozilla/glean"
7 | readme = "README.md"
8 | license = "MPL-2.0"
9 | keywords = ["telemetry", "glean"]
10 | include = [
11 | "/README.md",
12 | "/LICENSE",
13 | "/src",
14 | "/Cargo.toml",
15 | ]
16 | rust-version = "1.82"
17 |
18 | [dependencies]
19 | xshell-venv = "1.1.0"
20 |
21 | [dev-dependencies]
22 | tempfile = "3.8.0"
23 |
--------------------------------------------------------------------------------
/glean-core/bundle-android/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "glean-bundle-android"
3 | # No need to ever change this version
4 | version = "1.0.0"
5 | authors = ["The Glean Team "]
6 | edition = "2021"
7 | description = "Dynamic library build of glean-ffi, for use in Android builds"
8 | repository = "https://github.com/mozilla/glean"
9 | license = "MPL-2.0"
10 |
11 | # This crate is never published to crates.io
12 | publish = false
13 |
14 | # We use the name `xul` for now, because we ship this through mozilla-central
15 | # and it is consumed as `libxul.so`.
16 | [lib]
17 | name = "xul"
18 | crate-type = ["cdylib"]
19 | # We re-use the source from `glean-bundle`,
20 | # no need to duplicate it, no risk of diverging
21 | path = "../bundle/src/lib.rs"
22 |
23 | [dependencies.glean-core]
24 | # No version specified, we build against what's available here.
25 | path = ".."
26 |
27 | [features]
28 | enable_env_logger = ["glean-core/enable_env_logger"]
29 |
--------------------------------------------------------------------------------
/glean-core/bundle/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "glean-bundle"
3 | # No need to ever change this version
4 | version = "1.0.0"
5 | authors = ["The Glean Team "]
6 | edition = "2021"
7 | description = "Static/Dynamic library build of glean-ffi, for use in mobile builds"
8 | repository = "https://github.com/mozilla/glean"
9 | license = "MPL-2.0"
10 |
11 | # This crate is never published to crates.io
12 | publish = false
13 |
14 | # We use the same name as glean-ffi.
15 | # The Kotlin/Swift/Python bindings will use this name.
16 | [lib]
17 | name = "glean_ffi"
18 | crate-type = ["staticlib", "cdylib"]
19 |
20 | [dependencies.glean-core]
21 | # No version specified, we build against what's available here.
22 | path = ".."
23 |
24 | # Needed in order for maturin to find it during builds from `sdist`
25 | [dev-dependencies.uniffi-bindgen]
26 | path = "../../tools/embedded-uniffi-bindgen"
27 |
--------------------------------------------------------------------------------
/glean-core/bundle/src/glean.udl:
--------------------------------------------------------------------------------
1 | ../../src/glean.udl
--------------------------------------------------------------------------------
/glean-core/bundle/src/lib.rs:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | pub use glean_core;
6 |
7 | /// Workaround to force a re-export of the `no_mangle` symbols from `glean_core`
8 | ///
9 | /// Due to how linking works and hides symbols the symbols from `glean_core` might not be
10 | /// re-exported and thus not usable.
11 | /// By forcing use of _at least one_ symbol in an exported function the functions will also be
12 | /// rexported.
13 | /// This is only required for debug builds (and `debug_assertions` is the closest thing we have to
14 | /// check that).
15 | /// In release builds we rely on LTO builds to take care of it.
16 | /// Our tests should ensure this actually happens.
17 | ///
18 | /// See https://github.com/rust-lang/rust/issues/50007
19 | #[cfg(debug_assertions)]
20 | #[no_mangle]
21 | pub extern "C" fn _glean_force_reexport_donotcall() {
22 | glean_core::glean_enable_logging();
23 | }
24 |
--------------------------------------------------------------------------------
/glean-core/bundle/uniffi.toml:
--------------------------------------------------------------------------------
1 | ../uniffi.toml
--------------------------------------------------------------------------------
/glean-core/ios/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/glean-core/ios/.gitkeep
--------------------------------------------------------------------------------
/glean-core/ios/Glean.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/glean-core/ios/Glean.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/glean-core/ios/Glean.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "pins" : [
3 | {
4 | "identity" : "gzipswift",
5 | "kind" : "remoteSourceControl",
6 | "location" : "https://github.com/1024jp/GzipSwift",
7 | "state" : {
8 | "revision" : "7a7f17761c76a932662ab77028a4329f67d645a4",
9 | "version" : "5.2.0"
10 | }
11 | },
12 | {
13 | "identity" : "ohhttpstubs",
14 | "kind" : "remoteSourceControl",
15 | "location" : "https://github.com/alisoftware/OHHTTPStubs",
16 | "state" : {
17 | "revision" : "12f19662426d0434d6c330c6974d53e2eb10ecd9",
18 | "version" : "9.1.0"
19 | }
20 | }
21 | ],
22 | "version" : 2
23 | }
24 |
--------------------------------------------------------------------------------
/glean-core/ios/Glean/Dispatchers.swift:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | import Foundation
6 |
7 | /// This class manages a single background operation queue.
8 | class Dispatchers {
9 | /// This is the shared singleton access to the Glean Dispatchers
10 | static let shared = Dispatchers()
11 |
12 | // Don't let other instances be created, we only want singleton access through the static `shared`
13 | // property
14 | private init() {}
15 |
16 | // This is a task queue for background operations that are required to be executed in order.
17 | // It is currently set to be a serial queue by setting the `maxConcurrentOperationsCount` to 1.
18 | // This queue is intended for API operations that are subject to the behavior and constraints of the
19 | // API.
20 | lazy var serialOperationQueue: OperationQueue = {
21 | var queue = OperationQueue()
22 | queue.name = "Glean serial dispatch queue"
23 | queue.maxConcurrentOperationCount = 1
24 | return queue
25 | }()
26 |
27 | func launchAsync(block: @escaping () -> Void) {
28 | serialOperationQueue.addOperation(BlockOperation(block: block))
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/glean-core/ios/Glean/Glean.h:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | #import
6 |
7 | //! Project version number for Glean.
8 | FOUNDATION_EXPORT double GleanVersionNumber;
9 |
10 | //! Project version string for Glean.
11 | FOUNDATION_EXPORT const unsigned char GleanVersionString[];
12 |
13 | // In this header, you should import all the public headers of your framework using statements like #import
14 |
15 | #import "gleanFFI.h"
16 |
--------------------------------------------------------------------------------
/glean-core/ios/Glean/GleanMetrics.swift:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | /// Namespace for user metrics
6 | ///
7 | /// This is extended by user code (generated by the `glean_parser`).
8 | ///
9 | /// # Example
10 | ///
11 | /// ```swift
12 | /// extension GleanMetrics {
13 | /// enum Search {
14 | /// /// Running ping counter for this ping. This works as a sequence number to allow
15 | /// /// detecting for missing send_in_pings.
16 | /// static let counts = CounterMetricType(
17 | /// category: "search",
18 | /// name: "counts",
19 | /// sendInPings: ["metrics"],
20 | /// lifetime: .application,
21 | /// disabled: false
22 | /// )
23 | /// }
24 | /// }
25 | /// ```
26 | ///
27 | /// This will be used by the user as following:
28 | ///
29 | /// ```swift
30 | /// import Glean
31 | ///
32 | /// GleanMetrics.Search.counts.add(1)
33 | /// ```
34 | public enum GleanMetrics {}
35 |
--------------------------------------------------------------------------------
/glean-core/ios/Glean/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 |
22 |
23 |
--------------------------------------------------------------------------------
/glean-core/ios/Glean/Metrics/BooleanMetric.swift:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | /// This implements the developer facing API for recording boolean metrics.
6 | ///
7 | /// Instances of this class type are automatically generated by the parsers at build time,
8 | /// allowing developers to record values that were previously registered in the metrics.yaml file.
9 | ///
10 | /// The boolean API only exposes the `BooleanMetricType.set(_:)` method, which takes care of validating the input
11 | /// data and making sure that limits are enforced.
12 | public typealias BooleanMetricType = BooleanMetric
13 |
--------------------------------------------------------------------------------
/glean-core/ios/Glean/Metrics/CounterMetric.swift:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | /// This implements the developer facing API for recording counter metrics.
6 | ///
7 | /// Instances of this class type are automatically generated by the parsers at build time,
8 | /// allowing developers to record values that were previously registered in the metrics.yaml file.
9 | ///
10 | /// The counter API only exposes the `CounterMetricType.add(_:)` method, which takes care of validating the input
11 | /// data and making sure that limits are enforced.
12 | public typealias CounterMetricType = CounterMetric
13 |
--------------------------------------------------------------------------------
/glean-core/ios/Glean/Metrics/MemoryDistributionMetric.swift:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | /// This implements the developer facing API for recording memory distribution metrics.
6 | ///
7 | /// Instances of this class type are automatically generated by the parsers at build time,
8 | /// allowing developers to record values that were previously registered in the metrics.yaml file.
9 | ///
10 | /// The memory distribution API only exposes the `MemoryDistributionMetricType.accumulate()` method.
11 | public typealias MemoryDistributionMetricType = MemoryDistributionMetric
12 |
--------------------------------------------------------------------------------
/glean-core/ios/Glean/Metrics/QuantityMetric.swift:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | /// This implements the developer facing API for recording quantity metrics.
6 | ///
7 | /// Instances of this class type are automatically generated by the parsers at build time,
8 | /// allowing developers to record values that were previously registered in the metrics.yaml file.
9 | ///
10 | /// The quantity API only exposes the `QuantityMetricType.set(_:)` method, which takes care of validating the input
11 | /// data and making sure that requirements are enforced.
12 | public typealias QuantityMetricType = QuantityMetric
13 |
--------------------------------------------------------------------------------
/glean-core/ios/Glean/Metrics/StringListMetric.swift:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | /// This implements the developer facing API for recording string list metrics.
6 | ///
7 | /// Instances of this class type are automatically generated by the parsers at build time,
8 | /// allowing developers to record values that were previously registered in the metrics.yaml file.
9 | ///
10 | /// The string list API only exposes the `StringListMetricType.add(_:)` and `StringListMetricType.set(_:)` methods,
11 | /// which takes care of validating the input
12 | /// data and making sure that limits are enforced.
13 | public typealias StringListMetricType = StringListMetric
14 |
--------------------------------------------------------------------------------
/glean-core/ios/Glean/Metrics/StringMetric.swift:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | /// This implements the developer facing API for recording string metrics.
6 | ///
7 | /// Instances of this class type are automatically generated by the parsers at build time,
8 | /// allowing developers to record values that were previously registered in the metrics.yaml file.
9 | ///
10 | /// The string API only exposes the `StringMetricType.set(_:)` method, which takes care of validating the input
11 | /// data and making sure that limits are enforced.
12 | public typealias StringMetricType = StringMetric
13 |
--------------------------------------------------------------------------------
/glean-core/ios/Glean/Metrics/TextMetric.swift:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | /// This implements the developer facing API for recording text metrics.
6 | ///
7 | /// Instances of this class type are automatically generated by the parsers at build time,
8 | /// allowing developers to record values that were previously registered in the metrics.yaml file.
9 | ///
10 | /// The text API only exposes the `TextMetricType.set(_:)` method, which takes care of validating the input
11 | /// data and making sure that limits are enforced.
12 | public typealias TextMetricType = TextMetric
13 |
--------------------------------------------------------------------------------
/glean-core/ios/Glean/Scheduler/GleanLifecycleObserver.swift:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | import Foundation
6 | import UIKit
7 |
8 | private typealias GleanBaseline = GleanMetrics.GleanBaseline
9 |
10 | class GleanLifecycleObserver {
11 | init() {
12 | NotificationCenter.default.addObserver(
13 | self,
14 | selector: #selector(GleanLifecycleObserver.appWillEnterForeground(notification:)),
15 | name: UIApplication.willEnterForegroundNotification,
16 | object: nil
17 | )
18 |
19 | NotificationCenter.default.addObserver(
20 | self,
21 | selector: #selector(GleanLifecycleObserver.appDidEnterBackground(notification:)),
22 | name: UIApplication.didEnterBackgroundNotification,
23 | object: nil
24 | )
25 |
26 | // We handle init the same as an foreground event,
27 | // as we won't get the enter-foreground notification.
28 | Glean.shared.handleForegroundEvent()
29 | }
30 |
31 | @objc func appWillEnterForeground(notification _: NSNotification) {
32 | // Note that this is sending the length of the last foreground session
33 | // because it belongs to the baseline ping and that ping is sent every
34 | // time the app goes to background.
35 | Glean.shared.handleForegroundEvent()
36 | }
37 |
38 | @objc func appDidEnterBackground(notification _: NSNotification) {
39 | Glean.shared.handleBackgroundEvent()
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/glean-core/ios/GleanTests/Config/ConfigurationTests.swift:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | @testable import Glean
6 | import XCTest
7 |
8 | class ConfigurationTests: XCTestCase {
9 | private var config: Configuration?
10 |
11 | override func setUp() {
12 | config = Configuration()
13 | }
14 |
15 | override func tearDown() {
16 | config = nil
17 | }
18 |
19 | func testInit() {
20 | XCTAssertEqual(
21 | config?.serverEndpoint,
22 | Configuration.Constants.defaultTelemetryEndpoint,
23 | "Default endpoint is set"
24 | )
25 | XCTAssertNil(
26 | config?.maxEvents,
27 | "Default max events are set"
28 | )
29 | XCTAssertNil(
30 | config?.channel,
31 | "Default channel is set"
32 | )
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/glean-core/ios/GleanTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/glean-core/ios/GleanTests/Utils/DataPathUtilsTests.swift:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 |
5 | @testable import Glean
6 | import XCTest
7 |
8 | class DataPathMetricTests: XCTestCase {
9 | override func setUp() {
10 | resetGleanDiscardingInitialPings(testCase: self, tag: "PingTests")
11 | }
12 |
13 | func testCannotWriteToInvalidDatabasePath() {
14 | let customDataPath = ""
15 | XCTAssertFalse(canWriteToDatabasePath(customDataPath))
16 | }
17 |
18 | func testCanWriteToValidDatabasePath() {
19 | let paths = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)
20 | let documentsDirectory = paths[0]
21 | let dataPath = documentsDirectory.appendingPathComponent("valid_db_path").relativePath
22 | XCTAssertTrue(canWriteToDatabasePath(dataPath))
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/glean-core/ios/base.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../xcconfig/common.xcconfig"
2 |
3 | INFOPLIST_FILE = Glean/Info.plist
4 |
--------------------------------------------------------------------------------
/glean-core/ios/debug.xcconfig:
--------------------------------------------------------------------------------
1 | buildvariant = debug
2 | #include "base.xcconfig"
3 |
--------------------------------------------------------------------------------
/glean-core/ios/release.xcconfig:
--------------------------------------------------------------------------------
1 | buildvariant = release
2 | #include "base.xcconfig"
3 |
--------------------------------------------------------------------------------
/glean-core/megazord.uniffi.toml:
--------------------------------------------------------------------------------
1 | [bindings.swift]
2 | ffi_module_name = "MozillaRustComponents"
3 | ffi_module_filename = "gleanFFI"
4 | generate_module_map = false
5 | omit_argument_labels = true
6 |
--------------------------------------------------------------------------------
/glean-core/python/.gitignore:
--------------------------------------------------------------------------------
1 | .venv*
2 |
3 | # Byte-compiled / optimized / DLL files
4 | __pycache__/
5 | *.py[cod]
6 | *$py.class
7 |
8 | # C extensions
9 | *.so
10 | *.dylib
11 | *.dll
12 |
13 | # Distribution / packaging
14 | .Python
15 | build/
16 | develop-eggs/
17 | dist/
18 | downloads/
19 | eggs/
20 | .eggs/
21 | lib/
22 | lib64/
23 | parts/
24 | sdist/
25 | var/
26 | wheels/
27 | pip-wheel-metadata/
28 | share/python-wheels/
29 | *.egg-info/
30 | .installed.cfg
31 | *.egg
32 | MANIFEST
33 |
--------------------------------------------------------------------------------
/glean-core/python/glean/_builtins.py:
--------------------------------------------------------------------------------
1 | # This Source Code Form is subject to the terms of the Mozilla Public
2 | # License, v. 2.0. If a copy of the MPL was not distributed with this
3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 |
5 |
6 | """
7 | This module loads the built-in metrics and pings.
8 | """
9 |
10 | import sys
11 |
12 | if sys.version_info >= (3, 9):
13 | import importlib.resources as importlib_resources
14 | else:
15 | import importlib_resources
16 |
17 | from ._loader import load_metrics, load_pings
18 |
19 | # Python <3.12 makes this something like `glean._builtin`,
20 | # above that it's just `glean`.
21 | pkg_name = __name__.split(".")[0]
22 |
23 | ref = importlib_resources.files(pkg_name) / "metrics.yaml"
24 | with importlib_resources.as_file(ref) as path:
25 | metrics = load_metrics(path, config={"allow_reserved": True})
26 |
27 | ref = importlib_resources.files(pkg_name) / "pings.yaml"
28 | with importlib_resources.as_file(ref) as path:
29 | pings = load_pings(path, config={"allow_reserved": True})
30 |
31 |
32 | __all__ = ["metrics", "pings"]
33 |
--------------------------------------------------------------------------------
/glean-core/python/glean/_subprocess/__init__.py:
--------------------------------------------------------------------------------
1 | # This Source Code Form is subject to the terms of the Mozilla Public
2 | # License, v. 2.0. If a copy of the MPL was not distributed with this
3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 |
--------------------------------------------------------------------------------
/glean-core/python/glean/_subprocess/_process_dispatcher_helper.py:
--------------------------------------------------------------------------------
1 | # This Source Code Form is subject to the terms of the Mozilla Public
2 | # License, v. 2.0. If a copy of the MPL was not distributed with this
3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 |
5 | """
6 | The main entry point for work performed on a worker process by
7 | _dispatcher_subprocess.
8 |
9 | This needs to be here and not at the top-level of the package to avoid
10 | ambiguity between the `glean` and `glean.glean` import paths.
11 | """
12 |
13 | if __name__ == "__main__": # pragma: no cover
14 | import base64
15 | import logging
16 | import os
17 | import pickle
18 | import sys
19 |
20 | # Run coverage in the subprocess if necessary
21 | if "GLEAN_COVERAGE" in os.environ and "COVERAGE_PROCESS_START" in os.environ:
22 | import coverage # type: ignore
23 |
24 | config_path = os.environ.get("COVERAGE_PROCESS_START") or False
25 |
26 | cov = coverage.Coverage(data_suffix=True, config_file=config_path)
27 | cov.start()
28 | cov._warn_no_data = False
29 | cov._warn_unimported_source = False
30 | cov._auto_save = True
31 |
32 | __builtins__.IN_GLEAN_SUBPROCESS = True # type: ignore
33 |
34 | simple_log_level, func, args = pickle.loads(base64.b64decode(sys.argv[1]))
35 |
36 | if simple_log_level is not None:
37 | logging.basicConfig(level=simple_log_level)
38 |
39 | success = func(*args)
40 |
41 | if success:
42 | sys.exit(0)
43 | else:
44 | sys.exit(1)
45 |
--------------------------------------------------------------------------------
/glean-core/python/glean/metrics.yaml:
--------------------------------------------------------------------------------
1 | ../../metrics.yaml
--------------------------------------------------------------------------------
/glean-core/python/glean/net/__init__.py:
--------------------------------------------------------------------------------
1 | # This Source Code Form is subject to the terms of the Mozilla Public
2 | # License, v. 2.0. If a copy of the MPL was not distributed with this
3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 |
5 |
6 | """
7 | Network functionality for Glean.
8 | """
9 |
10 | from .base_uploader import BaseUploader
11 | from .http_client import HttpClientUploader
12 | from .ping_uploader import PingUploader
13 | from .ping_upload_worker import PingUploadWorker
14 |
15 |
16 | __all__ = [
17 | "BaseUploader",
18 | "HttpClientUploader",
19 | "PingUploader",
20 | "PingUploadWorker",
21 | ]
22 |
--------------------------------------------------------------------------------
/glean-core/python/glean/net/base_uploader.py:
--------------------------------------------------------------------------------
1 | # This Source Code Form is subject to the terms of the Mozilla Public
2 | # License, v. 2.0. If a copy of the MPL was not distributed with this
3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 |
5 | """
6 | A base class for ping uploaders.
7 | """
8 |
9 | from typing import Union, TYPE_CHECKING
10 |
11 |
12 | from .ping_uploader import PingUploader, UploadResult
13 |
14 |
15 | if TYPE_CHECKING:
16 | from .ping_upload_worker import CapablePingUploadRequest
17 |
18 |
19 | class BaseUploader(PingUploader):
20 | """
21 | The logic for uploading pings. This leaves the actual upload implementation
22 | to the user-provided delegate.
23 | """
24 |
25 | def do_upload(
26 | self,
27 | capable_request: "CapablePingUploadRequest",
28 | ) -> Union[
29 | UploadResult,
30 | UploadResult.UNRECOVERABLE_FAILURE,
31 | UploadResult.RECOVERABLE_FAILURE,
32 | UploadResult.HTTP_STATUS,
33 | UploadResult.INCAPABLE,
34 | ]:
35 | """
36 | This function triggers the actual upload.
37 |
38 | It logs the ping and calls the implementation-specific upload function.
39 |
40 | Args:
41 | capable_request (CapablePingUploadRequest): The ping upload request, locked behind a capability check.
42 |
43 | Returns:
44 | result (UploadResult): the status code of the upload response.
45 | """
46 |
47 | return self.upload(capable_request)
48 |
49 |
50 | __all__ = ["BaseUploader"]
51 |
--------------------------------------------------------------------------------
/glean-core/python/glean/net/ping_uploader.py:
--------------------------------------------------------------------------------
1 | # This Source Code Form is subject to the terms of the Mozilla Public
2 | # License, v. 2.0. If a copy of the MPL was not distributed with this
3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 |
5 |
6 | import sys
7 | from typing import Union
8 |
9 | from .._uniffi import UploadResult
10 | from .ping_upload_worker import CapablePingUploadRequest
11 |
12 | if sys.version_info >= (3, 8):
13 | from typing import Protocol
14 | else:
15 | Protocol = object
16 |
17 |
18 | class PingUploader(Protocol):
19 | def upload(
20 | self, capable_request: CapablePingUploadRequest
21 | ) -> Union[
22 | UploadResult,
23 | UploadResult.UNRECOVERABLE_FAILURE,
24 | UploadResult.RECOVERABLE_FAILURE,
25 | UploadResult.HTTP_STATUS,
26 | UploadResult.INCAPABLE,
27 | ]:
28 | """
29 | Upload a ping to a server.
30 |
31 | Args:
32 | capable_request (CapablePingUploadRequest): The ping upload request, locked behind a capability check.
33 |
34 | Returns:
35 | result (UploadResult): the status code of the upload response.
36 | """
37 | pass
38 |
39 |
40 | __all__ = [
41 | "CapablePingUploadRequest",
42 | "PingUploader",
43 | "UploadResult",
44 | ]
45 |
--------------------------------------------------------------------------------
/glean-core/python/glean/pings.yaml:
--------------------------------------------------------------------------------
1 | ../../pings.yaml
--------------------------------------------------------------------------------
/glean-core/python/requirements_dev.txt:
--------------------------------------------------------------------------------
1 | coverage[toml]==7.2.2
2 | jsonschema==3.2.0
3 | mypy==1.4.1
4 | pdoc3==0.11.6; python_version > '3.8'
5 | pip
6 | pytest-localserver==0.8.0
7 | MarkupSafe==2.0.1
8 | pytest-runner==5.3.2
9 | pytest==8.2.2
10 | ruff==0.7.2
11 | semver==2.13.0
12 | setuptools-git==1.2
13 | twine==6.0.1
14 | wheel==0.45.1
15 | maturin==1.8.7
16 | patchelf>=0.17; sys_platform == "linux"
17 |
--------------------------------------------------------------------------------
/glean-core/python/tests/data/events_with_types.yaml:
--------------------------------------------------------------------------------
1 | # Any copyright is dedicated to the Public Domain.
2 | # https://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | ---
5 | $schema: moz://mozilla.org/schemas/glean/metrics/2-0-0
6 |
7 | core:
8 | preference_toggled:
9 | type: event
10 | description: |
11 | Just testing events
12 | bugs:
13 | - https://bugzilla.mozilla.org/1123456789
14 | data_reviews:
15 | - http://example.com/reviews
16 | notification_emails:
17 | - CHANGE-ME@example.com
18 | extra_keys:
19 | preference:
20 | type: string
21 | description: "This is key one"
22 | enabled:
23 | type: boolean
24 | description: "This is key two"
25 | swapped:
26 | type: quantity
27 | description: "This is key three"
28 | And1WithUnusualCASING:
29 | type: boolean
30 | description: "This is key four"
31 | expires: never
32 |
--------------------------------------------------------------------------------
/glean-core/python/tests/data/glinter.yaml:
--------------------------------------------------------------------------------
1 | # Any copyright is dedicated to the Public Domain.
2 | # https://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | ---
5 | $schema: moz://mozilla.org/schemas/glean/metrics/1-0-0
6 |
7 | test:
8 | client_id:
9 | type: counter
10 | description: >
11 | A metric in the glean category should be a glinter error.
12 | bugs:
13 | - 1137353
14 | data_reviews:
15 | - http://example.com/reviews
16 | - http://example.com/other_reviews
17 | notification_emails:
18 | - CHANGE-ME@example.com
19 | send_in_pings:
20 | - core
21 | expires: 2100-01-01
22 |
--------------------------------------------------------------------------------
/glean-core/python/tests/data/pings.yaml:
--------------------------------------------------------------------------------
1 | # This Source Code Form is subject to the terms of the Mozilla Public
2 | # License, v. 2.0. If a copy of the MPL was not distributed with this
3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 |
5 | ---
6 | $schema: moz://mozilla.org/schemas/glean/pings/2-0-0
7 |
8 | kebab-case:
9 | description: |
10 | Make sure we can load a kebab-case named ping from Python
11 | include_client_id: true
12 | send_if_empty: true
13 | bugs:
14 | - https://example.com
15 | data_reviews:
16 | - https://example.comd
17 | notification_emails:
18 | - glean-team@mozilla.com
19 |
20 | nofollows-defined:
21 | description: |
22 | A sample custom ping with follows_collection_enabled=False.
23 | include_client_id: false
24 | send_if_empty: true
25 | bugs:
26 | - https://bugzilla.mozilla.org/123456789
27 | data_reviews:
28 | - N/A
29 | notification_emails:
30 | - CHANGE-ME@example.com
31 | metadata:
32 | follows_collection_enabled: false
33 | include_info_sections: false
34 |
35 | uploader-capabilities:
36 | description: |
37 | A sample custom ping with an uploader_capabilities.
38 | include_client_id: false
39 | send_if_empty: true
40 | bugs:
41 | - https://bugzilla.mozilla.org/123456789
42 | data_reviews:
43 | - N/A
44 | notification_emails:
45 | - CHANGE-ME@example.com
46 | uploader_capabilities:
47 | - some_capability
48 |
--------------------------------------------------------------------------------
/glean-core/python/tests/metrics/test_text.py:
--------------------------------------------------------------------------------
1 | # This Source Code Form is subject to the terms of the Mozilla Public
2 | # License, v. 2.0. If a copy of the MPL was not distributed with this
3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 |
5 | from pathlib import Path
6 |
7 | from glean import metrics
8 | from glean.metrics import Lifetime, CommonMetricData
9 | from glean.testing import ErrorType
10 |
11 |
12 | ROOT = Path(__file__).parent
13 |
14 |
15 | def test_text_smoke():
16 | metric = metrics.TextMetricType(
17 | CommonMetricData(
18 | category="test",
19 | name="text",
20 | lifetime=Lifetime.PING,
21 | send_in_pings=["store1"],
22 | dynamic_label=None,
23 | disabled=False,
24 | ),
25 | )
26 |
27 | metric.set("hello world")
28 | assert 0 == metric.test_get_num_recorded_errors(ErrorType.INVALID_OVERFLOW)
29 |
30 | assert "hello world" == metric.test_get_value()
31 |
32 |
33 | def test_text_truncation():
34 | metric = metrics.TextMetricType(
35 | CommonMetricData(
36 | category="test",
37 | name="text",
38 | lifetime=Lifetime.PING,
39 | send_in_pings=["store1"],
40 | dynamic_label=None,
41 | disabled=False,
42 | ),
43 | )
44 |
45 | test_string = "01234567890" * (200 * 1024)
46 | metric.set(test_string)
47 |
48 | assert test_string[: (200 * 1024)] == metric.test_get_value()
49 | assert 1 == metric.test_get_num_recorded_errors(ErrorType.INVALID_OVERFLOW)
50 |
--------------------------------------------------------------------------------
/glean-core/python/tests/test_loader.py:
--------------------------------------------------------------------------------
1 | # This Source Code Form is subject to the terms of the Mozilla Public
2 | # License, v. 2.0. If a copy of the MPL was not distributed with this
3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 |
5 |
6 | from pathlib import Path
7 |
8 |
9 | from glean import load_metrics, load_pings
10 | from glean.metrics.ping import PingType
11 | from glean import _builtins
12 |
13 |
14 | ROOT = Path(__file__).parent
15 |
16 |
17 | def test_builtin_pings():
18 | assert set(dir(_builtins.pings)).issuperset(
19 | set(["metrics", "baseline", "events", "deletion_request"])
20 | )
21 |
22 |
23 | def test_working_metric():
24 | metrics = load_metrics(ROOT / "data" / "core.yaml", config={"allow_reserved": True})
25 |
26 | assert metrics.core_ping.flash_usage.__doc__.startswith("The number of times the flash plugin")
27 |
28 | metrics.core_ping.flash_usage.add(1)
29 |
30 | assert 1 == metrics.core_ping.flash_usage.test_get_value()
31 |
32 |
33 | def test_kebab_case_pings():
34 | pings = load_pings(ROOT / "data" / "pings.yaml")
35 |
36 | assert isinstance(pings.kebab_case, PingType)
37 |
--------------------------------------------------------------------------------
/glean-core/python/tests/test_subprocess.py:
--------------------------------------------------------------------------------
1 | # This Source Code Form is subject to the terms of the Mozilla Public
2 | # License, v. 2.0. If a copy of the MPL was not distributed with this
3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 |
5 |
6 | def test_subprocess_works():
7 | import glean # noqa: F401
8 | import subprocess
9 | import sys
10 |
11 | # Importing glean shouldn't affect subprocess.
12 | output = subprocess.check_output([sys.executable, "-c", "print('hello')"]).decode().strip()
13 | assert output == "hello"
14 |
--------------------------------------------------------------------------------
/glean-core/rlb/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "glean"
3 | version = "64.4.0"
4 | authors = ["Jan-Erik Rediger ", "The Glean Team "]
5 | description = "Glean SDK Rust language bindings"
6 | repository = "https://github.com/mozilla/glean"
7 | readme = "README.md"
8 | license = "MPL-2.0"
9 | edition = "2021"
10 | keywords = ["telemetry", "glean"]
11 | include = [
12 | "/README.md",
13 | "/LICENSE",
14 | "/src",
15 | "/tests",
16 | "/Cargo.toml",
17 | ]
18 | rust-version = "1.82"
19 |
20 | [badges]
21 | circle-ci = { repository = "mozilla/glean", branch = "main" }
22 | maintenance = { status = "actively-developed" }
23 |
24 | [dependencies.glean-core]
25 | path = ".."
26 | version = "64.4.0"
27 |
28 | [dependencies]
29 | crossbeam-channel = "0.5"
30 | inherent = "1"
31 | log = "0.4.8"
32 | once_cell = "1.18.0"
33 | whatsys = "0.3.0"
34 | malloc_size_of = { version = "0.2.1", package = "wr_malloc_size_of", default-features = false, features = ["once_cell"] }
35 |
36 | [dev-dependencies]
37 | env_logger = { version = "0.10.0", default-features = false, features = ["humantime"] }
38 | flate2 = "1.0.19"
39 | jsonschema-valid = "0.5.0"
40 | libc = "0.2"
41 | serde_json = "1.0.44"
42 | tempfile = "3.1.0"
43 |
--------------------------------------------------------------------------------
/glean-core/rlb/README.md:
--------------------------------------------------------------------------------
1 | # Glean
2 |
3 | The `Glean SDK` is a modern approach for a Telemetry library and is part of the [Glean project](https://docs.telemetry.mozilla.org/concepts/glean/glean.html).
4 |
5 | ## `glean`
6 |
7 | This library provides a Rust language bindings on top of `glean-core`, targeted to Rust consumers.
8 |
9 | ## Documentation
10 |
11 | All documentation is available online:
12 |
13 | * [The Glean SDK Book][book]
14 | * [API documentation][apidocs]
15 |
16 | [book]: https://mozilla.github.io/glean/
17 | [apidocs]: https://mozilla.github.io/glean/docs/glean/index.html
18 |
19 | ## Example
20 |
21 | ```rust,no_run
22 | use glean::{ConfigurationBuilder, Error, metrics::*};
23 |
24 | let cfg = ConfigurationBuilder::new(true, "/tmp/data", "org.mozilla.glean_core.example").build();
25 | glean::initialize(cfg)?;
26 |
27 | let prototype_ping = PingType::new("prototype", true, true, vec![]);
28 |
29 | glean::register_ping_type(&prototype_ping);
30 |
31 | prototype_ping.submit(None);
32 | ```
33 |
34 | ## License
35 |
36 | This Source Code Form is subject to the terms of the Mozilla Public
37 | License, v. 2.0. If a copy of the MPL was not distributed with this
38 | file, You can obtain one at http://mozilla.org/MPL/2.0/
39 |
--------------------------------------------------------------------------------
/glean-core/rlb/src/net/http_uploader.rs:
--------------------------------------------------------------------------------
1 | // This Source Code Form is subject to the terms of the Mozilla Public
2 | // License, v. 2.0. If a copy of the MPL was not distributed with this
3 | // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4 |
5 | use crate::net::{CapablePingUploadRequest, PingUploader, UploadResult};
6 |
7 | /// A simple mechanism to upload pings over HTTPS.
8 | #[derive(Debug)]
9 | pub struct HttpUploader;
10 |
11 | impl PingUploader for HttpUploader {
12 | /// Uploads a ping to a server.
13 | ///
14 | /// # Arguments
15 | ///
16 | /// * `upload_request` - the requested upload.
17 | fn upload(&self, upload_request: CapablePingUploadRequest) -> UploadResult {
18 | let upload_request = upload_request.capable(|_| true).unwrap();
19 | log::debug!("TODO bug 1675468: submitting to {:?}", upload_request.url);
20 | UploadResult::http_status(200)
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/glean-core/rlb/src/private/mod.rs:
--------------------------------------------------------------------------------
1 | // This Source Code Form is subject to the terms of the Mozilla Public
2 | // License, v. 2.0. If a copy of the MPL was not distributed with this
3 | // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4 |
5 | //! The different metric types supported by the Glean SDK to handle data.
6 |
7 | mod event;
8 | mod object;
9 | mod ping;
10 |
11 | pub use event::EventMetric;
12 | pub use glean_core::BooleanMetric;
13 | pub use glean_core::CounterMetric;
14 | pub use glean_core::DenominatorMetric;
15 | pub use glean_core::NumeratorMetric;
16 | pub use glean_core::QuantityMetric;
17 | pub use glean_core::RateMetric;
18 | pub use glean_core::RecordedExperiment;
19 | pub use glean_core::StringListMetric;
20 | pub use glean_core::StringMetric;
21 | pub use glean_core::TextMetric;
22 | pub use glean_core::TimespanMetric;
23 | pub use glean_core::UrlMetric;
24 | pub use glean_core::UuidMetric;
25 | pub use glean_core::{AllowLabeled, LabeledMetric};
26 | pub use glean_core::{CustomDistributionMetric, LocalCustomDistribution};
27 | pub use glean_core::{Datetime, DatetimeMetric};
28 | pub use glean_core::{LocalMemoryDistribution, MemoryDistributionMetric};
29 | pub use glean_core::{LocalTimingDistribution, TimingDistributionMetric};
30 | pub use object::ObjectMetric;
31 | pub use ping::PingType;
32 |
33 | // Re-export types that are used by the glean_parser-generated code.
34 | #[doc(hidden)]
35 | pub mod __export {
36 | pub use once_cell::sync::Lazy;
37 | }
38 |
--------------------------------------------------------------------------------
/glean-core/rlb/tests/near-empty-c0ffee-db.safe.bin:
--------------------------------------------------------------------------------
1 | ping app user glean_client_info#client_id9 0 $ c0ffeec0-ffee-c0ff-eec0-ffeec0ffeec0 glean_client_info#first_run_date2 ) 2025-03-06T00:00:00+01:00 glean_internal_info#dirtybit
--------------------------------------------------------------------------------
/glean-core/rlb/tests/persist_ping_lifetime_nopanic.rs:
--------------------------------------------------------------------------------
1 | // This Source Code Form is subject to the terms of the Mozilla Public
2 | // License, v. 2.0. If a copy of the MPL was not distributed with this
3 | // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4 |
5 | //! This integration test should model how the RLB is used when embedded in another Rust application
6 | //! (e.g. FOG/Firefox Desktop).
7 | //!
8 | //! We write a single test scenario per file to avoid any state keeping across runs
9 | //! (different files run as different processes).
10 |
11 | mod common;
12 |
13 | use glean::{Configuration, ConfigurationBuilder};
14 | use std::path::PathBuf;
15 |
16 | fn cfg_new(tmpname: PathBuf) -> Configuration {
17 | ConfigurationBuilder::new(true, tmpname, "firefox-desktop")
18 | .with_server_endpoint("invalid-test-host")
19 | .with_delay_ping_lifetime_io(true)
20 | .build()
21 | }
22 |
23 | /// Test scenario: `persist_ping_lifetime_data` called after shutdown.
24 | #[test]
25 | fn delayed_ping_data() {
26 | common::enable_test_logging();
27 |
28 | // Create a custom configuration to delay ping-lifetime io
29 | let dir = tempfile::tempdir().unwrap();
30 | let tmpname = dir.path().to_path_buf();
31 |
32 | common::initialize(cfg_new(tmpname));
33 | glean::persist_ping_lifetime_data();
34 |
35 | glean::shutdown();
36 | glean::persist_ping_lifetime_data();
37 | }
38 |
--------------------------------------------------------------------------------
/glean-core/rlb/tests/test-pending-gets-removed.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Test harness for testing the RLB processes from the outside.
4 | #
5 | # Some behavior can only be observed when properly exiting the process running Glean,
6 | # e.g. when an uploader runs in another thread.
7 | # On exit the threads will be killed, regardless of their state.
8 |
9 | # Remove the temporary data path on all exit conditions
10 | cleanup() {
11 | if [ -n "$datapath" ]; then
12 | rm -r "$datapath"
13 | fi
14 | }
15 | trap cleanup INT ABRT TERM EXIT
16 |
17 | set -e
18 |
19 | tmp="${TMPDIR:-/tmp}"
20 | datapath=$(mktemp -d "${tmp}/pending-gets-removed.XXXX")
21 |
22 | # Build it once
23 | cargo build -p glean --example pending-gets-removed
24 |
25 | cmd="cargo run -q -p glean --example pending-gets-removed -- $datapath"
26 |
27 | $cmd 1
28 | count=$(ls -1q "$datapath/pending_pings" | wc -l)
29 | if [[ "$count" -ne 2 ]]; then
30 | echo "1: test result: FAILED."
31 | exit 101
32 | fi
33 |
34 | $cmd 2
35 | count=$(ls -1q "$datapath/pending_pings" | wc -l)
36 | if [[ "$count" -ne 1 ]]; then
37 | echo "2: test result: FAILED."
38 | exit 101
39 | fi
40 |
41 | if ! grep -q "/submit/glean-pending-removed/nofollows/" "$datapath/pending_pings"/*; then
42 | echo "3: test result: FAILED."
43 | exit 101
44 | fi
45 |
46 | $cmd 3
47 | count=$(ls -1q "$datapath/pending_pings" | wc -l)
48 | if [[ "$count" -ne 0 ]]; then
49 | echo "4: test result: FAILED."
50 | exit 101
51 | fi
52 |
53 | echo "test result: ok."
54 | exit 0
55 |
--------------------------------------------------------------------------------
/glean-core/rlb/tests/test-ping-lifetime-flush.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Test harness for testing the RLB processes from the outside.
4 | #
5 | # Some behavior can only be observed when properly exiting the process running Glean,
6 | # e.g. when an uploader runs in another thread.
7 | # On exit the threads will be killed, regardless of their state.
8 |
9 | # Remove the temporary data path on all exit conditions
10 | cleanup() {
11 | if [ -n "$datapath" ]; then
12 | rm -r "$datapath"
13 | fi
14 | }
15 | trap cleanup INT ABRT TERM EXIT
16 |
17 | tmp="${TMPDIR:-/tmp}"
18 | datapath=$(mktemp -d "${tmp}/glean_ping_lifetime_flush.XXXX")
19 |
20 | cmd="cargo run -p glean --example ping-lifetime-flush -- $datapath"
21 |
22 | # First run "crashes" -> no increment stored
23 | $cmd accumulate_one_and_pretend_crash
24 | count=$(ls -1q "$datapath/sent_pings" | wc -l)
25 | if [[ "$count" -ne 0 ]]; then
26 | echo "test result: FAILED."
27 | exit 101
28 | fi
29 |
30 | # Second run increments, waits, increments -> increment flushed to disk.
31 | # No ping is sent.
32 | $cmd accumulate_ten_and_wait
33 | count=$(ls -1q "$datapath/sent_pings" | wc -l)
34 | if [[ "$count" -ne 0 ]]; then
35 | echo "test result: FAILED."
36 | exit 101
37 | fi
38 |
39 | # Third run sends the ping.
40 | $cmd submit_ping
41 | count=$(ls -1q "$datapath/sent_pings" | wc -l)
42 | if [[ "$count" -ne 1 ]]; then
43 | echo "test result: FAILED."
44 | exit 101
45 | fi
46 |
47 | if ! grep -q '"test.metrics.sample_counter":20' "$datapath"/sent_pings/*; then
48 | echo "test result: FAILED."
49 | exit 101
50 | fi
51 |
52 | echo "test result: ok."
53 | exit 0
54 |
--------------------------------------------------------------------------------
/glean-core/rlb/tests/test-shutdown-blocking.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Test harness for testing the RLB processes from the outside.
4 | #
5 | # Some behavior can only be observed when properly exiting the process running Glean,
6 | # e.g. when an uploader runs in another thread.
7 | # On exit the threads will be killed, regardless of their state.
8 |
9 | # Remove the temporary data path on all exit conditions
10 | cleanup() {
11 | if [ -n "$datapath" ]; then
12 | rm -r "$datapath"
13 | fi
14 | }
15 | trap cleanup INT ABRT TERM EXIT
16 |
17 | tmp="${TMPDIR:-/tmp}"
18 | datapath=$(mktemp -d "${tmp}/glean_long_running.XXXX")
19 |
20 | cargo run -p glean --example long-running -- "$datapath"
21 | count=$(ls -1q "$datapath/pending_pings" | wc -l)
22 |
23 | if [[ "$count" -eq 0 ]]; then
24 | echo "test result: ok."
25 | exit 0
26 | else
27 | echo "test result: FAILED."
28 | exit 101
29 | fi
30 |
--------------------------------------------------------------------------------
/glean-core/rlb/tests/test-thread-crashing.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Test harness for testing the RLB processes from the outside.
4 | #
5 | # Some behavior can only be observed when properly exiting the process running Glean,
6 | # e.g. when an uploader runs in another thread.
7 | # On exit the threads will be killed, regardless of their state.
8 |
9 | # Remove the temporary data path on all exit conditions
10 | cleanup() {
11 | if [ -n "$datapath" ]; then
12 | rm -r "$datapath"
13 | fi
14 | }
15 | trap cleanup INT ABRT TERM EXIT
16 |
17 | tmp="${TMPDIR:-/tmp}"
18 | datapath=$(mktemp -d "${tmp}/crashing_threads.XXXX")
19 |
20 | RUSTFLAGS="-C panic=abort" \
21 | RUST_LOG=debug \
22 | cargo run -p glean --example crashing-threads -- "$datapath"
23 | ret=$?
24 | count=$(ls -1q "$datapath/pending_pings" | wc -l)
25 |
26 | # We expect 1 `prototype` ping:
27 | if [[ $ret -eq 0 ]] && [[ "$count" -eq 1 ]]; then
28 | echo "test result: ok."
29 | exit 0
30 | else
31 | echo "Assertions:"
32 | echo " ret - expected: 0, was: $ret"
33 | echo " count - expected: 1, was: $count"
34 | echo "test result: FAILED."
35 | exit 101
36 | fi
37 |
--------------------------------------------------------------------------------
/glean-core/src/glean_metrics.rs:
--------------------------------------------------------------------------------
1 | // This Source Code Form is subject to the terms of the Mozilla Public
2 | // License, v. 2.0. If a copy of the MPL was not distributed with this
3 | // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4 |
5 | // ** IMPORTANT **
6 | //
7 | // This file is required in order to include the ones generated by
8 | // 'glean-parser' from the SDK registry files.
9 |
10 | pub mod error {
11 | use crate::metrics::CounterMetric;
12 | use crate::{CommonMetricData, Lifetime};
13 | use once_cell::sync::Lazy;
14 |
15 | #[allow(non_upper_case_globals)]
16 | pub static preinit_tasks_overflow: Lazy = Lazy::new(|| {
17 | CounterMetric::new(CommonMetricData {
18 | category: "glean.error".into(),
19 | name: "preinit_tasks_overflow".into(),
20 | send_in_pings: vec!["metrics".into()],
21 | lifetime: Lifetime::Ping,
22 | disabled: false,
23 | ..Default::default()
24 | })
25 | });
26 | }
27 |
--------------------------------------------------------------------------------
/glean-core/src/traits/boolean.rs:
--------------------------------------------------------------------------------
1 | // This Source Code Form is subject to the terms of the Mozilla Public
2 | // License, v. 2.0. If a copy of the MPL was not distributed with this
3 | // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4 |
5 | use crate::ErrorType;
6 |
7 | /// A description for the [`BooleanMetric`](crate::metrics::BooleanMetric) type.
8 | ///
9 | /// When changing this trait, make sure all the operations are
10 | /// implemented in the related type in `../metrics/`.
11 | pub trait Boolean {
12 | /// Sets to the specified boolean value.
13 | ///
14 | /// # Arguments
15 | ///
16 | /// * `value` - the value to set.
17 | fn set(&self, value: bool);
18 |
19 | /// **Exported for test purposes.**
20 | ///
21 | /// Gets the currently stored value as a boolean.
22 | ///
23 | /// This doesn't clear the stored value.
24 | ///
25 | /// # Arguments
26 | ///
27 | /// * `ping_name` - represents the optional name of the ping to retrieve the
28 | /// metric for. Defaults to the first value in `send_in_pings`.
29 | fn test_get_value<'a, S: Into