├── .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 | pingappuserglean_client_info#client_id9 0 $c0ffeec0-ffee-c0ff-eec0-ffeec0ffeec0 glean_client_info#first_run_date2 )2025-03-06T00:00:00+01:00glean_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>>(&self, ping_name: S) -> Option; 30 | 31 | /// **Exported for test purposes.** 32 | /// 33 | /// Gets the number of recorded errors for the given metric and error type. 34 | /// 35 | /// # Arguments 36 | /// 37 | /// * `error` - The type of error 38 | /// 39 | /// # Returns 40 | /// 41 | /// The number of errors reported. 42 | fn test_get_num_recorded_errors(&self, error: ErrorType) -> i32; 43 | } 44 | -------------------------------------------------------------------------------- /glean-core/src/traits/ping.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 | /// A description for the [`PingType`](crate::metrics::PingType) type. 6 | /// 7 | /// When changing this trait, make sure all the operations are 8 | /// implemented in the related type in `../metrics/`. 9 | pub trait Ping { 10 | /// Submits the ping for eventual uploading 11 | /// 12 | /// # Arguments 13 | /// 14 | /// * `reason` - the reason the ping was triggered. Included in the 15 | /// `ping_info.reason` part of the payload. 16 | fn submit(&self, reason: Option<&str>); 17 | } 18 | -------------------------------------------------------------------------------- /glean-core/uniffi.toml: -------------------------------------------------------------------------------- 1 | [bindings.kotlin] 2 | package_name = "mozilla.telemetry.glean.internal" 3 | cdylib_name = "xul" 4 | 5 | [bindings.swift] 6 | cdylib_name = "glean_ffi" 7 | omit_argument_labels = true 8 | 9 | [bindings.python] 10 | cdylib_name = "glean_ffi" 11 | -------------------------------------------------------------------------------- /gradle-plugin/README.md: -------------------------------------------------------------------------------- 1 | This directory contains a Gradle plugin for build-time functionality, 2 | such as generating specific metrics and documentation. 3 | 4 | See `docs/user/user/adding-glean-to-your-project/index.md` for information about using this 5 | plugin. 6 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | 15 | libGroupId=org.mozilla.telemetry 16 | libRepositoryName=glean 17 | libProjectName=glean 18 | libProjectDescription=Firefox Glean Telemetry 19 | libUrl=https://github.com/mozilla/glean 20 | libVcsUrl=https://github.com/mozilla/glean.git 21 | 22 | libLicense=MPL-2.0 23 | libLicenseUrl=https://www.mozilla.org/en-US/MPL/2.0/ 24 | 25 | android.useAndroidX=true 26 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /lint-baseline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 13 | 14 | 15 | 20 | 24 | 25 | 26 | 31 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["maturin>=1.0,<2.0"] 3 | build-backend = "maturin" 4 | 5 | [project] 6 | name = "glean-sdk" 7 | version = "64.4.0" 8 | requires-python = ">=3.8" 9 | classifiers = [ 10 | "Intended Audience :: Developers", 11 | "Natural Language :: English", 12 | "Programming Language :: Rust", 13 | "Programming Language :: Python :: Implementation :: CPython", 14 | "Programming Language :: Python :: 3", 15 | ] 16 | description = "Mozilla's Glean Telemetry SDK: The Machine that Goes 'Ping!'" 17 | readme = "README.md" 18 | license = { file = "LICENSE" } 19 | maintainers = [ 20 | {name = "The Glean Team", email = "glean-team@mozilla.com"} 21 | ] 22 | 23 | dependencies = [ 24 | "semver>=2.13.0", 25 | "glean_parser~=17.1", 26 | "importlib_resources>=1.3; python_version=='3.8'" 27 | ] 28 | 29 | [project.urls] 30 | homepage = "https://mozilla.github.io/glean/" 31 | repository = "https://github.com/mozilla/glean" 32 | changelog = "https://mozilla.github.io/glean/book/appendix/changelog/sdk.html" 33 | 34 | [tool.maturin] 35 | python-source = "glean-core/python" 36 | module-name = "glean._uniffi" 37 | bindings = "uniffi" 38 | manifest-path = "glean-core/bundle/Cargo.toml" 39 | include = [{ path = "tools/embedded-uniffi-bindgen/**/*", format = "sdist" }] 40 | 41 | [tool.coverage.run] 42 | source = ["glean"] 43 | 44 | [tool.ruff] 45 | extend-exclude = ["glean-core/python/glean/_uniffi/glean.py"] 46 | line-length = 100 47 | -------------------------------------------------------------------------------- /samples/android/app/README.md: -------------------------------------------------------------------------------- 1 | # Glean Sample Application 2 | 3 | A simple app showcasing the Glean SDK. 4 | 5 | ## Running tests 6 | 7 | 1. [Setup the Android Build Environment](https://mozilla.github.io/glean/dev/android/setup-android-build-environment.html#setup-the-android-build-environment) 8 | 2. Run `./gradlew :glean-sample-app:connectedAndroidTest` 9 | 10 | Since the tests are instrumented they need a connected device or emulator 11 | present to complete. 12 | 13 | ## License 14 | 15 | This Source Code Form is subject to the terms of the Mozilla Public 16 | License, v. 2.0. If a copy of the MPL was not distributed with this 17 | file, You can obtain one at http://mozilla.org/MPL/2.0/ 18 | -------------------------------------------------------------------------------- /samples/android/app/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 | # This file defines the built-in pings that are recorded by the Glean SDK. They 6 | # are automatically converted to Kotlin code at build time using the 7 | # `glean_parser` PyPI package. 8 | 9 | --- 10 | 11 | $schema: moz://mozilla.org/schemas/glean/pings/2-0-0 12 | 13 | sample: 14 | description: | 15 | A sample custom ping. 16 | include_client_id: true 17 | bugs: 18 | - https://bugzilla.mozilla.org/123456789 19 | data_reviews: 20 | - N/A 21 | notification_emails: 22 | - CHANGE-ME@example.com 23 | background: 24 | description: | 25 | A sample custom ping sent from the background process. 26 | include_client_id: true 27 | bugs: 28 | - https://bugzilla.mozilla.org/123456789 29 | data_reviews: 30 | - N/A 31 | notification_emails: 32 | - CHANGE-ME@example.com 33 | -------------------------------------------------------------------------------- /samples/android/app/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 | -------------------------------------------------------------------------------- /samples/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/samples/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/samples/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/samples/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/samples/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/glean/df50f8b9a9c60dc311b559ee4b2b8366aecca3b0/samples/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | Glean - Metrics Demo 7 | Record Text 8 | Submit Ping 9 | Enter some text here 10 | 11 | Every time you click on the button above, the text is added to the test-string-list metric 12 | and a counter metric type called testCounter is incremented. Both of these will be included 13 | when the ping is sent. The counter and the string list are utilizing the `user` lifetime 14 | and should persist from launch to launch of the app.\n\nAn event metric is also being used 15 | to attach a dictionary of values to the extras of the event ping. See MainActivity for 16 | where all of this is happening. 17 | 18 | 19 | Glean is enabled 20 | 21 | 22 | -------------------------------------------------------------------------------- /samples/android/app/src/main/res/xml/backup_rules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /samples/android/app/tags.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/tags/1-0-0 7 | 8 | testing: 9 | description: | 10 | Metrics used for testing Glean behavior. 11 | -------------------------------------------------------------------------------- /samples/ios/app/.gitignore: -------------------------------------------------------------------------------- 1 | glean-sample-app/Generated 2 | Pipfile 3 | Pipfile.lock 4 | -------------------------------------------------------------------------------- /samples/ios/app/README.md: -------------------------------------------------------------------------------- 1 | # A Glean sample app 2 | 3 | A minimal example showcasing the integration of Glean into an iOS application. 4 | This app does nothing, but enable Glean. 5 | 6 | Glean sends a [`baseline`][] ping when the app is sent to background. 7 | 8 | [`baseline`]: https://mozilla.github.io/glean/book/user/pings/baseline.html 9 | 10 | ## Build 11 | 12 | 1. Install Xcode 15.0 or higher. 13 | 14 | 2. Install the latest [Xcode developer tools](https://developer.apple.com/xcode/downloads/) from Apple. 15 | 16 | 3. Build the XCFramework to be consumed. Run the following from the root directory of this repository: 17 | 18 | ``` 19 | ./bin/build-xcframework.sh 20 | ``` 21 | 22 | 4. Open `samples/ios/app/glean-sample-app.xcodeproj` in Xcode. 23 | 24 | 5. Build/Run the `glean-sample-app` scheme in Xcode. 25 | -------------------------------------------------------------------------------- /samples/ios/app/base.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../../xcconfig/common.xcconfig" 2 | 3 | INFOPLIST_FILE = glean-sample-app/Info.plist 4 | PRODUCT_BUNDLE_IDENTIFIER = org.mozilla.glean-sample-app 5 | PRODUCT_NAME = Glean-Sample-App 6 | -------------------------------------------------------------------------------- /samples/ios/app/debug.xcconfig: -------------------------------------------------------------------------------- 1 | buildvariant = debug 2 | #include "base.xcconfig" 3 | -------------------------------------------------------------------------------- /samples/ios/app/glean-sample-app.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /samples/ios/app/glean-sample-app.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /samples/ios/app/glean-sample-app.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" : "swifter", 14 | "kind" : "remoteSourceControl", 15 | "location" : "https://github.com/httpswift/swifter", 16 | "state" : { 17 | "revision" : "9483a5d459b45c3ffd059f7b55f9638e268632fd", 18 | "version" : "1.5.0" 19 | } 20 | } 21 | ], 22 | "version" : 2 23 | } 24 | -------------------------------------------------------------------------------- /samples/ios/app/glean-sample-app/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /samples/ios/app/glean-sample-appTests/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 | -------------------------------------------------------------------------------- /samples/ios/app/glean-sample-appTests/glean_sample_appTests.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_sample_app 6 | import XCTest 7 | 8 | // swiftlint:disable type_name 9 | class glean_sample_appTests: XCTestCase { 10 | // swiftlint:enable type_name 11 | 12 | override func setUp() { 13 | // Put setup code here. This method is called before the invocation of each test method in the class. 14 | } 15 | 16 | override func tearDown() { 17 | // Put teardown code here. This method is called after the invocation of each test method in the class. 18 | } 19 | 20 | func testExample() { 21 | // This is an example of a functional test case. 22 | // Use XCTAssert and related functions to verify your tests produce the correct results. 23 | } 24 | 25 | func testPerformanceExample() { 26 | // This is an example of a performance test case. 27 | measure { 28 | // Put the code you want to measure the time of here. 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /samples/ios/app/glean-sample-appUITests/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 | -------------------------------------------------------------------------------- /samples/ios/app/glean-sample-appUITests/MockServer.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 Gzip 7 | import Swifter 8 | 9 | // Create a new Glean endpoint HTTP server on localhost and react only for the specified ping type 10 | func mockServer(expectPingType: String, port: UInt16 = 0, callback: @escaping ([String: Any]?) -> Void) -> HttpServer { 11 | let server = HttpServer() 12 | 13 | server["/submit/:appid/:ping/:schema/:pinguuid"] = { request in 14 | let pingName = request.params[":ping"]! 15 | if pingName == expectPingType { 16 | var data = Data(request.body) 17 | 18 | // Swifter lowercases all headers. 19 | if request.headers["content-encoding"] == "gzip" { 20 | data = try! data.gunzipped() 21 | } 22 | 23 | let json = try! JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] 24 | callback(json) 25 | } 26 | return HttpResponse.ok(.text("OK")) 27 | } 28 | // For logging purposes: 29 | server.middleware.append { request in 30 | print("Middleware: \(request.address ?? "unknown address") -> \(request.method) -> \(request.path)") 31 | return nil 32 | } 33 | 34 | try! server.start(port) 35 | return server 36 | } 37 | -------------------------------------------------------------------------------- /samples/ios/app/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 | # This file defines the built-in pings that are recorded by the Glean SDK. 6 | # They are automatically converted to Kotlin code at build time using 7 | # the `glean_parser` PyPI package. 8 | 9 | --- 10 | 11 | $schema: moz://mozilla.org/schemas/glean/pings/2-0-0 12 | 13 | sample: 14 | description: | 15 | A sample custom ping. 16 | include_client_id: true 17 | bugs: 18 | - https://bugzilla.mozilla.org/123456789 19 | data_reviews: 20 | - N/A 21 | notification_emails: 22 | - CHANGE-ME@example.com 23 | reasons: 24 | button_tap: The button was tapped 25 | -------------------------------------------------------------------------------- /samples/ios/app/release.xcconfig: -------------------------------------------------------------------------------- 1 | buildvariant = release 2 | #include "base.xcconfig" 3 | -------------------------------------------------------------------------------- /samples/ios/app/sdk_generator.sh: -------------------------------------------------------------------------------- 1 | ../../../glean-core/ios/sdk_generator.sh -------------------------------------------------------------------------------- /samples/python/Makefile: -------------------------------------------------------------------------------- 1 | PYENV := .venv 2 | 3 | .PHONY: help 4 | help: 5 | @grep -E '^[0-9a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \ 6 | sort | \ 7 | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' 8 | 9 | $(PYENV)/bin/python3: 10 | python3 -m venv $(PYENV) 11 | $@ -m pip install --upgrade pip 12 | 13 | setup: $(PYENV)/bin/python3 ## Setup a Python virtual environment 14 | @: 15 | 16 | dev: setup deps ## Setup package for development 17 | $(PYENV)/bin/python3 -m pip install -e . 18 | 19 | deps: ## Install required dependencies 20 | $(PYENV)/bin/python3 -m pip install -r requirements.txt 21 | 22 | run: dev ## Run the sample app 23 | $(PYENV)/bin/python3 -m glean-sample 24 | -------------------------------------------------------------------------------- /samples/python/README.md: -------------------------------------------------------------------------------- 1 | # A minimal Glean sample app 2 | 3 | ## Development 4 | 5 | ``` 6 | make dev 7 | . .venv/bin/activate 8 | ``` 9 | 10 | ## Run the sample app 11 | 12 | ``` 13 | make run 14 | ``` 15 | -------------------------------------------------------------------------------- /samples/python/glean-sample/__main__.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 | import logging 6 | 7 | from glean import Configuration, Glean, load_metrics, load_pings 8 | 9 | 10 | config = Configuration() 11 | 12 | Glean.initialize( 13 | application_id="glean-sample-app", 14 | application_version="0.1.0", 15 | upload_enabled=True, 16 | data_dir="./data", 17 | log_level=logging.DEBUG, 18 | configuration=config, 19 | ) 20 | 21 | metrics = load_metrics("metrics.yaml") 22 | pings = load_pings("pings.yaml") 23 | 24 | metrics.test.metrics.sample_boolean.set(True) 25 | 26 | balloons = metrics.party.BalloonsObject() 27 | balloons.append(metrics.party.BalloonsObjectItem(colour="red", diameter=5)) 28 | balloons.append(metrics.party.BalloonsObjectItem(colour="green")) 29 | metrics.party.balloons.set(balloons) 30 | 31 | # Set some invalid object. 32 | # Does not throw an exception, but will record an error 33 | metrics.party.balloons.set([]) 34 | 35 | pings.prototype.submit() 36 | 37 | Glean.shutdown() 38 | -------------------------------------------------------------------------------- /samples/python/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. They are 6 | # automatically converted to Python code at run time using the `glean_parser` 7 | # PyPI package. 8 | 9 | --- 10 | 11 | $schema: moz://mozilla.org/schemas/glean/metrics/2-0-0 12 | 13 | test.metrics: 14 | sample_boolean: 15 | type: boolean 16 | description: | 17 | Just testing booleans 18 | bugs: 19 | - https://bugzilla.mozilla.org/123456789 20 | data_reviews: 21 | - N/A 22 | notification_emails: 23 | - CHANGE-ME@example.com 24 | expires: never 25 | send_in_pings: 26 | - prototype 27 | 28 | party: 29 | balloons: 30 | type: object 31 | description: | 32 | Just testing objects 33 | bugs: 34 | - https://bugzilla.mozilla.org/1839640 35 | data_reviews: 36 | - N/A 37 | notification_emails: 38 | - CHANGE-ME@example.com 39 | expires: never 40 | send_in_pings: 41 | - prototype 42 | structure: 43 | type: array 44 | items: 45 | type: object 46 | properties: 47 | colour: 48 | type: string 49 | diameter: 50 | type: number 51 | -------------------------------------------------------------------------------- /samples/python/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 | # This file defines the built-in pings that are recorded by the Glean SDK. They 6 | # are automatically converted to Python code at run time using the 7 | # `glean_parser` PyPI package. 8 | 9 | --- 10 | 11 | $schema: moz://mozilla.org/schemas/glean/pings/2-0-0 12 | 13 | prototype: 14 | description: | 15 | A sample custom ping. 16 | include_client_id: true 17 | bugs: 18 | - https://bugzilla.mozilla.org/123456789 19 | data_reviews: 20 | - N/A 21 | notification_emails: 22 | - CHANGE-ME@example.com 23 | -------------------------------------------------------------------------------- /samples/python/pyproject.toml: -------------------------------------------------------------------------------- 1 | [project] 2 | name = "glean-sample" 3 | version = "0.0.1" 4 | -------------------------------------------------------------------------------- /samples/python/requirements.txt: -------------------------------------------------------------------------------- 1 | ../.. 2 | -------------------------------------------------------------------------------- /samples/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sample" 3 | version = "0.1.0" 4 | edition = "2021" 5 | publish = false 6 | license = "MIT" 7 | 8 | [dependencies] 9 | env_logger = { version = "0.10.0", default-features = false, features = ["humantime"] } 10 | flate2 = "1.0.19" 11 | glean = { path = "../../glean-core/rlb" } 12 | serde_json = "1.0.44" 13 | tempfile = "3.3.0" 14 | 15 | [build-dependencies] 16 | glean-build = { path = "../../glean-core/build" } 17 | -------------------------------------------------------------------------------- /samples/rust/build.rs: -------------------------------------------------------------------------------- 1 | use glean_build::Builder; 2 | 3 | fn main() { 4 | Builder::default() 5 | .file("metrics.yaml") 6 | .file("pings.yaml") 7 | .generate() 8 | .expect("Error generating Glean Rust bindings"); 9 | } 10 | -------------------------------------------------------------------------------- /samples/rust/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 | # This file defines the built-in pings that are recorded by the Glean SDK. They 6 | # are automatically converted to Rust code at build time using the 7 | # `glean_parser` PyPI package. 8 | 9 | --- 10 | 11 | $schema: moz://mozilla.org/schemas/glean/pings/2-0-0 12 | 13 | prototype: 14 | description: | 15 | A sample custom ping. 16 | include_client_id: true 17 | bugs: 18 | - https://bugzilla.mozilla.org/123456789 19 | data_reviews: 20 | - N/A 21 | notification_emails: 22 | - CHANGE-ME@example.com 23 | 24 | usage-reporting: 25 | description: | 26 | A sample custom ping. 27 | include_client_id: false 28 | send_if_empty: true 29 | bugs: 30 | - https://bugzilla.mozilla.org/123456789 31 | data_reviews: 32 | - N/A 33 | notification_emails: 34 | - CHANGE-ME@example.com 35 | metadata: 36 | follows_collection_enabled: false 37 | include_info_sections: false 38 | uploader_capabilities: 39 | - ohttp 40 | -------------------------------------------------------------------------------- /taskcluster/config.yml: -------------------------------------------------------------------------------- 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 | trust-domain: glean 6 | task-priority: highest 7 | 8 | taskgraph: 9 | register: glean_taskgraph:register 10 | repositories: 11 | glean: 12 | name: "Glean" 13 | cached-task-prefix: project.glean 14 | decision-parameters: 'glean_taskgraph:get_decision_parameters' 15 | 16 | workers: 17 | aliases: 18 | b-linux: 19 | provisioner: 'glean-{level}' 20 | implementation: docker-worker 21 | os: linux 22 | worker-type: 'b-linux-gcp' 23 | images: 24 | provisioner: 'glean-{level}' 25 | implementation: docker-worker 26 | os: linux 27 | worker-type: 'images-gcp' 28 | signing: 29 | provisioner: scriptworker-k8s 30 | implementation: scriptworker-signing 31 | os: scriptworker 32 | worker-type: 33 | by-level: 34 | "3": glean-3-signing 35 | default: glean-t-signing 36 | beetmover: 37 | provisioner: scriptworker-k8s 38 | implementation: scriptworker-beetmover 39 | os: scriptworker 40 | worker-type: 'glean-{level}-beetmover' 41 | 42 | scriptworker: 43 | scope-prefix: project:mozilla:glean:releng 44 | -------------------------------------------------------------------------------- /taskcluster/docker/linux/runbuild.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | cd /glean 6 | 7 | source taskcluster/scripts/rustup-setup.sh 8 | echo "rust.targets=linux-x86-64\n" > local.properties 9 | 10 | ./gradlew clean assembleDebugUnitTest testDebugUnitTest 11 | -------------------------------------------------------------------------------- /taskcluster/docker/linux/runlocally.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Run the Android build in Docker. 4 | # This should run exactly the same as the Taskcluster build, using a local Docker setup. 5 | # It only runs the Android Arm build & test. 6 | # The Docker image is rebuild everytime (Docker is smart enough to skip cached steps though). 7 | # Note: the Docker image is ~15 GB. 8 | 9 | WORKSPACE_ROOT="$( cd "$(dirname "$0")/../../.." ; pwd -P )" 10 | 11 | # Build docker image to use 12 | pushd "${WORKSPACE_ROOT}/taskcluster/docker/linux" 13 | docker build -t gleanlinux . 14 | 15 | # Run the Android build 16 | pushd "${WORKSPACE_ROOT}" 17 | docker run --rm -v "$(pwd):/glean" gleanlinux /glean/taskcluster/docker/linux/runbuild.sh 18 | -------------------------------------------------------------------------------- /taskcluster/glean_taskgraph/loader/build_config.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 | # XXX: This loader generates a new build task for every component defined in 6 | # `.buildconfig.yml` 7 | 8 | 9 | import os 10 | 11 | from copy import deepcopy 12 | from taskgraph.loader.transform import loader as base_loader 13 | 14 | from ..build_config import get_components 15 | 16 | 17 | def loader(kind, path, config, params, loaded_tasks): 18 | config['tasks'] = { 19 | component['name']: { 20 | 'attributes': { 21 | 'buildconfig': component 22 | } 23 | } 24 | for component in get_components() 25 | } 26 | 27 | return base_loader(kind, path, config, params, loaded_tasks) 28 | -------------------------------------------------------------------------------- /taskcluster/glean_taskgraph/target_tasks.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 taskgraph.target_tasks import register_target_task, filter_for_tasks_for 7 | 8 | 9 | @register_target_task('pr-skip') 10 | def target_tasks_pr_skip(full_task_graph, parameters, graph_config): 11 | return [] 12 | 13 | 14 | @register_target_task('pr-full') 15 | def target_tasks_default(full_task_graph, parameters, graph_config): 16 | """Target the tasks which have indicated they should be run on this project 17 | via the `run_on_projects` attributes.""" 18 | def filter(task): 19 | return filter_for_tasks_for(task, parameters) \ 20 | and task.attributes.get("run-on-pr-type", "all") in ("full-ci", "all") 21 | 22 | return [l for l, task in full_task_graph.tasks.items() if filter(task)] 23 | 24 | 25 | @register_target_task('pr-normal') 26 | def target_tasks_default(full_task_graph, parameters, graph_config): 27 | """Target the tasks which have indicated they should be run on this project 28 | via the `run_on_projects` attributes.""" 29 | def filter(task): 30 | return filter_for_tasks_for(task, parameters) \ 31 | and task.attributes.get("run-on-pr-type", "all") in ("normal-ci", "all") 32 | 33 | return [l for l, task in full_task_graph.tasks.items() if filter(task)] 34 | -------------------------------------------------------------------------------- /taskcluster/glean_taskgraph/transforms/module_build.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 taskgraph.transforms.base import TransformSequence 7 | 8 | from ..build_config import get_version, get_extensions 9 | 10 | 11 | transforms = TransformSequence() 12 | 13 | 14 | @transforms.add 15 | def build_task(config, tasks): 16 | for task in tasks: 17 | module_info = task["attributes"]["buildconfig"] 18 | name = module_info["name"] 19 | version = get_version() 20 | 21 | for i,item in enumerate(task["run"]["gradlew"]): 22 | task["run"]["gradlew"][i] = task["run"]["gradlew"][i].format(module_name=name) 23 | task["description"] = task["description"].format(module_name=name) 24 | task["worker"]["artifacts"] = artifacts = [] 25 | 26 | all_extensions = get_extensions(name) 27 | for publication_name, extensions in all_extensions.items(): 28 | for extension in extensions: 29 | artifact_filename = f"{publication_name}-{version}{extension}" 30 | artifacts.append({ 31 | "name": f"public/build/{artifact_filename}", 32 | "path": f"/builds/worker/checkouts/vcs/build/maven/org/mozilla/telemetry/{publication_name}/{version}/{artifact_filename}", 33 | "type": "file", 34 | }) 35 | 36 | yield task 37 | -------------------------------------------------------------------------------- /taskcluster/glean_taskgraph/transforms/multi_dep.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 taskgraph.transforms.base import TransformSequence 7 | 8 | transforms = TransformSequence() 9 | 10 | 11 | @transforms.add 12 | def build_name_and_attributes(config, tasks): 13 | for task in tasks: 14 | task["dependencies"] = { 15 | dep.kind: dep.label 16 | for dep in _get_all_deps(task) 17 | } 18 | primary_dep = task["primary-dependency"] 19 | copy_of_attributes = primary_dep.attributes.copy() 20 | task.setdefault("attributes", copy_of_attributes) 21 | # run_on_tasks_for is set as an attribute later in the pipeline 22 | task.setdefault("run-on-tasks-for", copy_of_attributes['run_on_tasks_for']) 23 | task["name"] = _get_dependent_job_name_without_its_kind(primary_dep) 24 | 25 | yield task 26 | 27 | 28 | def _get_dependent_job_name_without_its_kind(dependent_job): 29 | return dependent_job.label[len(dependent_job.kind) + 1:] 30 | 31 | 32 | def _get_all_deps(task): 33 | if task.get("dependent-tasks"): 34 | return task["dependent-tasks"].values() 35 | 36 | return [task["primary-dependency"]] 37 | -------------------------------------------------------------------------------- /taskcluster/kinds/beetmover/kind.yml: -------------------------------------------------------------------------------- 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 | loader: glean_taskgraph.loader.multi_dep:loader 6 | 7 | transforms: 8 | - glean_taskgraph.transforms.multi_dep:transforms 9 | - glean_taskgraph.transforms.beetmover:transforms 10 | - taskgraph.transforms.task:transforms 11 | 12 | kind-dependencies: 13 | - module-build 14 | - signing 15 | 16 | primary-dependency: module-build 17 | group-by: component 18 | 19 | task-template: 20 | run-on-tasks-for: [github-release] 21 | description: 'Publish release module {}' 22 | worker-type: beetmover 23 | worker: 24 | app-name: telemetry 25 | bucket: 26 | by-level: 27 | "3": 28 | maven-production 29 | default: 30 | maven-staging 31 | routes: 32 | - notify.email.glean-team@mozilla.com.on-failed 33 | -------------------------------------------------------------------------------- /taskcluster/kinds/docker-image/kind.yml: -------------------------------------------------------------------------------- 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 | loader: taskgraph.loader.transform:loader 7 | 8 | transforms: 9 | - taskgraph.transforms.docker_image:transforms 10 | - taskgraph.transforms.cached_tasks:transforms 11 | - taskgraph.transforms.task:transforms 12 | 13 | tasks: 14 | linux: {} 15 | -------------------------------------------------------------------------------- /taskcluster/kinds/rust/kind.yml: -------------------------------------------------------------------------------- 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 | loader: taskgraph.loader.transform:loader 6 | 7 | transforms: 8 | - taskgraph.transforms.run:transforms 9 | - taskgraph.transforms.task:transforms 10 | 11 | task-defaults: 12 | worker-type: b-linux 13 | worker: 14 | docker-image: {in-tree: linux} 15 | max-run-time: 1800 16 | run: 17 | using: run-commands 18 | 19 | tasks: 20 | beta-tests: 21 | description: 'Rust (beta): Tests' 22 | run: 23 | pre-commands: 24 | - ['.', './taskcluster/scripts/rustup-setup.sh', 'beta'] 25 | - ['rustup', 'component', 'add', 'clippy'] 26 | commands: 27 | - ['cargo', 'clippy', '--version'] 28 | - ['cargo', 'clippy', '--verbose', '--all', '--all-targets', '--all-features', '--', '-D', 'warnings'] 29 | extra: 30 | excludeBranches: 31 | - release 32 | -------------------------------------------------------------------------------- /taskcluster/kinds/signing/kind.yml: -------------------------------------------------------------------------------- 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 | loader: glean_taskgraph.loader.multi_dep:loader 6 | 7 | transforms: 8 | - glean_taskgraph.transforms.multi_dep:transforms 9 | - glean_taskgraph.transforms.signing:transforms 10 | - taskgraph.transforms.task:transforms 11 | 12 | kind-dependencies: 13 | - module-build 14 | 15 | primary-dependency: module-build 16 | group-by: component 17 | 18 | task-template: 19 | run-on-tasks-for: [github-release] 20 | description: 'Sign release module {}' 21 | worker-type: signing 22 | worker: 23 | cert: 24 | by-level: 25 | "3": 26 | release-signing 27 | default: 28 | dep-signing 29 | routes: 30 | - notify.email.glean-team@mozilla.com.on-failed 31 | -------------------------------------------------------------------------------- /taskcluster/scripts/macos.manifest: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "size": 31991917, 4 | "visibility": "internal", 5 | "digest": "c5c0be09972b56b5980dc9d06b61ff49cf58c4572913437256a79b202e19e936af3c0ab0924df72b9f648d518c257597f84800a84bb80e68af4eabdaf1df5f24", 6 | "algorithm": "sha512", 7 | "unpack": true, 8 | "filename": "MacOSX10.12.sdk.tar.xz" 9 | }, 10 | { 11 | "size": 68798037, 12 | "visibility": "internal", 13 | "digest": "5bdc3270d0b660889b66194aa8cbcdbdb9163188bf976f31cc87837e6b0b5590db8d76cc17e9ea863b50f6735779cfd4338a4121997888b13139f4af1fdbb504", 14 | "algorithm": "sha512", 15 | "unpack": true, 16 | "filename": "MacOSX11.0.sdk.tar.zst" 17 | } 18 | ] 19 | -------------------------------------------------------------------------------- /taskcluster/scripts/rustup-setup.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 -eux 8 | 9 | export RUST_BACKTRACE='1' 10 | export RUSTFLAGS='-Dwarnings' 11 | export CARGO_INCREMENTAL='0' 12 | export CI='1' 13 | export RUST_LOG='glean_core=debug,glean_ffi=debug' 14 | export CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse 15 | 16 | # Rust 17 | RUSTUP_PLATFORM='x86_64-unknown-linux-gnu' 18 | RUSTUP_VERSION='1.21.1' 19 | RUSTUP_SHA256='ad1f8b5199b3b9e231472ed7aa08d2e5d1d539198a15c5b1e53c746aad81d27b' 20 | curl -sfSL --retry 5 --retry-delay 10 -O "https://static.rust-lang.org/rustup/archive/${RUSTUP_VERSION}/${RUSTUP_PLATFORM}/rustup-init" 21 | echo "${RUSTUP_SHA256} *rustup-init" | sha256sum -c - 22 | chmod +x rustup-init 23 | ./rustup-init -y --no-modify-path --default-toolchain none 24 | rm rustup-init 25 | export PATH=$HOME/.cargo/bin:$PATH 26 | export RUST_ANDROID_GRADLE_PYTHON_COMMAND=python3 27 | 28 | TOOLCHAIN="${1:-stable}" 29 | 30 | # No argument -> default stable install 31 | if [ "${TOOLCHAIN}" = "stable" ]; then 32 | echo "Installing Rust stable & Android targets" 33 | rustup toolchain install stable --profile minimal --component llvm-tools 34 | rustup default stable 35 | rustup target add x86_64-linux-android i686-linux-android armv7-linux-androideabi aarch64-linux-android 36 | else 37 | echo "Installing Rust ${TOOLCHAIN}" 38 | rustup toolchain add "${TOOLCHAIN}" --profile minimal --component llvm-tools 39 | rustup default "${TOOLCHAIN}" 40 | fi 41 | 42 | set +eu 43 | -------------------------------------------------------------------------------- /tools/analysis/ping-patterns/config.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 | Configuration constants for the analysis script. 7 | """ 8 | 9 | 10 | import datetime 11 | 12 | 13 | FIRST_DATE = datetime.datetime.fromisoformat("2019-11-01") 14 | """ 15 | The earliest date to include in the analysis. This helps to remove clients with 16 | wildly incorrect clocks. 17 | """ 18 | 19 | FIXES = [ 20 | ("Double scheduling of metrics ping", 191115), # Double-schedule of metrics ping 21 | ("Proguard rule to retain lifetime API", 191116), # Proguard rule 22 | ("Avoid reflection in the lifetime API", 191120), # Non-reflection-based API 23 | ] 24 | """ 25 | A list of Fenix revisions to highlight in the output. Each entry is a tuple 26 | `(description, version)` where `version` is in Fenix nightly version format: 27 | YYMMDD. 28 | """ 29 | 30 | FIXES = sorted(FIXES, key=lambda x: x[1]) 31 | -------------------------------------------------------------------------------- /tools/docker-winbuild/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM cimg/python:3.9 2 | 3 | RUN sudo apt-get update -qq \ 4 | && sudo apt-get install -qy --no-install-recommends \ 5 | wine64 \ 6 | gcc-mingw-w64 7 | 8 | RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal \ 9 | && echo 'export PATH=$HOME/.cargo/bin:$PATH' >> ~/.profile 10 | 11 | RUN export PATH=$HOME/.cargo/bin:$PATH \ 12 | && rustup target add x86_64-pc-windows-gnu \ 13 | && echo '[target.x86_64-pc-windows-gnu]' >> ~/.cargo/config.toml \ 14 | && echo 'linker = "/usr/bin/x86_64-w64-mingw32-gcc"' >> ~/.cargo/config.toml 15 | 16 | RUN wine64-stable wineboot \ 17 | && mkdir ~/winpython \ 18 | && cd ~/winpython \ 19 | && wget https://www.python.org/ftp/python/3.9.13/python-3.9.13-embed-amd64.zip \ 20 | && unzip python-3.9.13-embed-amd64.zip -d ~/winpython \ 21 | && rm python-3.9.13-embed-amd64.zip \ 22 | && echo "export WINPYTHON=\"wine64-stable $HOME/winpython/python.exe\"" >> ~/.profile \ 23 | && echo "export PYTHONHASHSEED=4" >> ~/.profile \ 24 | && echo "export WINEDEBUG=-all" >> ~/.profile \ 25 | && wget https://bootstrap.pypa.io/get-pip.py \ 26 | && wine64-stable ~/winpython/python.exe get-pip.py \ 27 | && echo "import site" >> ~/winpython/python39._pth \ 28 | && echo "import sys; sys.path.insert(0, '')" >> ~/winpython/sitecustomize.py \ 29 | && echo "import ctypes; ctypes.cdll.LoadLibrary('Z:/home/circleci/project/wine_shims/bcryptprimitives.dll')" >> ~/winpython/sitecustomize.py 30 | 31 | ADD init.sh /home/circleci/init.sh 32 | ADD build.sh /home/circleci/build.sh 33 | 34 | RUN sudo chown circleci:circleci ~/*.sh 35 | 36 | ENTRYPOINT ~/init.sh 37 | -------------------------------------------------------------------------------- /tools/docker-winbuild/README.md: -------------------------------------------------------------------------------- 1 | # Run glean-py Windows tests in Docker 2 | 3 | This should be equivalent to what is running on CI. 4 | 5 | ## Build the image 6 | 7 | ``` 8 | docker build -t gleanwin . 9 | ``` 10 | 11 | ## Run a build & test 12 | 13 | ``` 14 | docker run -t -i --rm gleanwin 15 | ``` 16 | 17 | Inside the container: 18 | 19 | ``` 20 | ~/build.sh 21 | ``` 22 | 23 | This builds the target, installs it for use in the wine environment and runs the Python tests. 24 | 25 | To rerun the tests: 26 | 27 | ``` 28 | $WINPYTHON -m pytest -s glean-core/python/tests 29 | ``` 30 | -------------------------------------------------------------------------------- /tools/docker-winbuild/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd ~/project 4 | 5 | make setup-python 6 | make build-python-wheel GLEAN_BUILD_TARGET=x86_64-pc-windows-gnu 7 | 8 | # Bit of a cleanup to reduce install time 9 | sed \ 10 | -e '/^mypy/d' \ 11 | -e '/^ruff/d' \ 12 | -e '/^twine/d' \ 13 | -e '/^coverage/d' \ 14 | -e '/^jsonschema/d' \ 15 | -i \ 16 | glean-core/python/requirements_dev.txt 17 | 18 | find ~/.cache/pip -name "*.whl" -exec $WINPYTHON -m pip install {} \; 19 | $WINPYTHON -m pip install -r glean-core/python/requirements_dev.txt --no-warn-script-location 20 | $WINPYTHON -m pip install --force-reinstall target/wheels/*.whl --no-warn-script-location 21 | 22 | $WINPYTHON -m pytest -s glean-core/python/tests 23 | -------------------------------------------------------------------------------- /tools/docker-winbuild/init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | git clone --depth=1 https://github.com/mozilla/glean ~/project 4 | 5 | PATH=$HOME/.cargo/bin:$PATH \ 6 | rustc tools/patches/bcryptprimitives.rs -Copt-level=3 -Clto=fat --out-dir ~/project/wine_shims --target x86_64-pc-windows-gnu 7 | 8 | exec bash -l 9 | -------------------------------------------------------------------------------- /tools/embedded-uniffi-bindgen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "uniffi-bindgen" 3 | version = "0.1.0" 4 | edition = "2021" 5 | license = "MPL-2.0" 6 | publish = false 7 | 8 | [dependencies] 9 | anyhow = "1" 10 | camino = "1.1.1" 11 | uniffi = { version = "0.29.0", default-features = false, features = ["bindgen"] } 12 | glob = "0.3.2" 13 | 14 | [lib] 15 | test = false 16 | doctest = false 17 | doc = false 18 | -------------------------------------------------------------------------------- /tools/embedded-uniffi-bindgen/src/lib.rs: -------------------------------------------------------------------------------- 1 | // intentionally left empty. only exists to make a warning go away 2 | -------------------------------------------------------------------------------- /tools/patches/bcryptprimitives.rs: -------------------------------------------------------------------------------- 1 | // via https://github.com/rust-lang/rust/commit/07633821ed63360d4d7464998c29f4f588930a03 2 | // Shim for bcryptprimitives.dll. The Wine version shipped with Ubuntu 22.04 3 | // doesn't support it yet. Authored by @ChrisDenton 4 | 5 | #![crate_type = "cdylib"] 6 | #![allow(nonstandard_style)] 7 | 8 | #[no_mangle] 9 | pub unsafe extern "system" fn ProcessPrng(mut pbData: *mut u8, mut cbData: usize) -> i32 { 10 | while cbData > 0 { 11 | let size = core::cmp::min(cbData, u32::MAX as usize); 12 | RtlGenRandom(pbData, size as u32); 13 | cbData -= size; 14 | pbData = pbData.add(size); 15 | } 16 | 1 17 | } 18 | 19 | #[link(name = "advapi32")] 20 | extern "system" { 21 | #[link_name = "SystemFunction036"] 22 | pub fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: u32) -> u8; 23 | } 24 | --------------------------------------------------------------------------------