summaryrefslogtreecommitdiffstats
path: root/third_party/rust/glean-core
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/glean-core')
-rw-r--r--third_party/rust/glean-core/.cargo-checksum.json2
-rw-r--r--third_party/rust/glean-core/Cargo.toml4
-rw-r--r--third_party/rust/glean-core/src/core/mod.rs6
-rw-r--r--third_party/rust/glean-core/src/glean.udl10
-rw-r--r--third_party/rust/glean-core/src/internal_pings.rs4
-rw-r--r--third_party/rust/glean-core/src/lib.rs38
-rw-r--r--third_party/rust/glean-core/src/lib_unit_tests.rs4
-rw-r--r--third_party/rust/glean-core/src/metrics/boolean.rs12
-rw-r--r--third_party/rust/glean-core/src/metrics/counter.rs12
-rw-r--r--third_party/rust/glean-core/src/metrics/custom_distribution.rs38
-rw-r--r--third_party/rust/glean-core/src/metrics/datetime.rs10
-rw-r--r--third_party/rust/glean-core/src/metrics/denominator.rs11
-rw-r--r--third_party/rust/glean-core/src/metrics/event.rs7
-rw-r--r--third_party/rust/glean-core/src/metrics/experiment.rs9
-rw-r--r--third_party/rust/glean-core/src/metrics/labeled.rs2
-rw-r--r--third_party/rust/glean-core/src/metrics/memory_distribution.rs11
-rw-r--r--third_party/rust/glean-core/src/metrics/mod.rs11
-rw-r--r--third_party/rust/glean-core/src/metrics/numerator.rs8
-rw-r--r--third_party/rust/glean-core/src/metrics/object.rs135
-rw-r--r--third_party/rust/glean-core/src/metrics/ping.rs28
-rw-r--r--third_party/rust/glean-core/src/metrics/quantity.rs11
-rw-r--r--third_party/rust/glean-core/src/metrics/rate.rs11
-rw-r--r--third_party/rust/glean-core/src/metrics/string.rs11
-rw-r--r--third_party/rust/glean-core/src/metrics/string_list.rs11
-rw-r--r--third_party/rust/glean-core/src/metrics/text.rs11
-rw-r--r--third_party/rust/glean-core/src/metrics/timespan.rs11
-rw-r--r--third_party/rust/glean-core/src/metrics/timing_distribution.rs43
-rw-r--r--third_party/rust/glean-core/src/metrics/url.rs11
-rw-r--r--third_party/rust/glean-core/src/metrics/uuid.rs11
-rw-r--r--third_party/rust/glean-core/src/ping/mod.rs44
-rw-r--r--third_party/rust/glean-core/src/traits/custom_distribution.rs16
-rw-r--r--third_party/rust/glean-core/src/traits/mod.rs6
-rw-r--r--third_party/rust/glean-core/src/traits/object.rs53
-rw-r--r--third_party/rust/glean-core/src/traits/timing_distribution.rs25
-rw-r--r--third_party/rust/glean-core/src/upload/directory.rs78
-rw-r--r--third_party/rust/glean-core/src/upload/mod.rs343
-rw-r--r--third_party/rust/glean-core/src/upload/request.rs37
-rw-r--r--third_party/rust/glean-core/tests/custom_distribution.rs20
-rw-r--r--third_party/rust/glean-core/tests/event.rs2
-rw-r--r--third_party/rust/glean-core/tests/object.rs104
-rw-r--r--third_party/rust/glean-core/tests/ping.rs14
-rw-r--r--third_party/rust/glean-core/tests/ping_maker.rs26
-rw-r--r--third_party/rust/glean-core/tests/timing_distribution.rs6
43 files changed, 1041 insertions, 226 deletions
diff --git a/third_party/rust/glean-core/.cargo-checksum.json b/third_party/rust/glean-core/.cargo-checksum.json
index 859a8ecdae..54674fc768 100644
--- a/third_party/rust/glean-core/.cargo-checksum.json
+++ b/third_party/rust/glean-core/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"85eba7a464630582734247336bb970481f894c7b6e418d6eb5c868693af35a14","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"026495898699b54608eb4ec16074ffafc57920d80ccb59961c501a1ea28c9985","build.rs":"4857bea99c6b8c08db8818efa9d3738716f52d3acb68159323957ae52892a3eb","src/common_metric_data.rs":"72051c4349885d4a94fc41bb4edda88d31551f2f9ebcdb4e868a98161bc76233","src/core/mod.rs":"4749e71ba495d5aed48cb4d311e0beb7e9d53c10b18ab33938e8fd9c3cfa5666","src/core_metrics.rs":"a877e42e0f8b932adb52a5681ad76fd977808cb48c7eeb29b1e4bbe804f1ea96","src/coverage.rs":"49613fd310bd24d779472720975fbe6c97ec370a95eb55f10afa43f67539c942","src/database/mod.rs":"3917bad7773696a43ab58e7860d5a8f1d63dca7c27920343aa8786acc5a586cd","src/debug.rs":"90158cc5d488ba67b60d06647e54e59a1d7bdeb906087e4fe4cfab4373c1cc6c","src/dispatcher/global.rs":"f69cd81a90a37c306d4e0ce8177ea5a3ae2ffda5b431ae46b9a22c9e38891271","src/dispatcher/mod.rs":"440a331a7beeaa6e9824c2fd4306c09ce2a115a358d5beb830dba4d69aec3563","src/error.rs":"b93c7d3e243b21bb9eafc95f17860aba1a942b2f2b0a7f43307690f05fece516","src/error_recording.rs":"d7858647808d81173558e12de88f3fbe4e589969e3bd246bfb388f90f8ff3814","src/event_database/mod.rs":"9d4d3e4b075dc585c00317304401b2c9115f39db8fdbd9f1c93d3fc6fd350fd5","src/fd_logger.rs":"0c9def6fa53db1a2ab93c85795f8a7df57797bcfd3978146923e151752e291a6","src/glean.udl":"13150d3344874d8d801aaa76880ba191ab99e337af5ac5c3cbb55bc70e5daa8a","src/glean_metrics.rs":"9414fb1453d19f6832df33e4c6ef7383d62203e47026bf5bc9552b083101ddd1","src/histogram/exponential.rs":"58bb1770bae45770d92995515d328eb50a7e78726224f779446ae7d1632a6a3e","src/histogram/functional.rs":"1a63a305b48bcef7bc38136b40d916df4bb8f098dc602514ada54a9b091f6951","src/histogram/linear.rs":"4342a1733175d7f97b2b41adb18100537c206100c9fccb5bd13bd782c9cb3c9a","src/histogram/mod.rs":"eeb7aff80806ab76cdce101dc08887b5552f8b4bdf64683f64f767e0f06a889d","src/internal_metrics.rs":"263779535963a804c8c7fa6f8e284ac8ec7f415ceeadbb6a8f913a1e7073ae18","src/internal_pings.rs":"f7a3a3aef3661ae0066ba1d2890a5e8e6871a7a8016b5f7b4da077663bc0c0d0","src/lib.rs":"778a3778ce89db007b175e08b3a4bfd1104585709ba6d5c1e3972d388f3a6f8e","src/lib_unit_tests.rs":"f053c04aab63ddb86303bca7ceea5bbf104bc7de7c89213e7cadf0157db57645","src/metrics/boolean.rs":"0591043a88e81c77b694cc8124b9e4996e81a46df1402e1bdf364d2885d8215e","src/metrics/counter.rs":"57544e9fa971086b89a4844ab9cbc55ee5b79c9d391c7d9d9ac74a7bc844b076","src/metrics/custom_distribution.rs":"9ca60176837e216da3655b2a3ba08a296444aaa7d966ddd498478fdfb2b21049","src/metrics/datetime.rs":"ca12a426fbc564847d64e6ddcaa3f298065ba4bca0372c638058c20909f626d5","src/metrics/denominator.rs":"7bacb81ea2b81da8775f61544022d35d91f159e1aa494944eaf9536cacc18b4d","src/metrics/event.rs":"62d450e4db227b6c12b9179933e4b3a9df92abc4aa7da14c9274dc82e549e210","src/metrics/experiment.rs":"48aaf06b32a691500dbc51be95955071947d7760e3b81d30ac8d8d0161c1df3f","src/metrics/labeled.rs":"c6e2200694e3cd623e8369420d3b35759b117ef9e8188fd33afaa81685fdce28","src/metrics/memory_distribution.rs":"e9456afc7759980d06d1e2e3620a3117995d27d16bc3c5a05ea8c023475ae47a","src/metrics/memory_unit.rs":"d7a678e5242febd021283b30c0099a9e62729944816a3f17d2d91e2808bc0570","src/metrics/metrics_enabled_config.rs":"87fed12219c756ecf1e5c8cd6a21f26999b6bbcf3ffc1b5467b0a58ca5ad35d8","src/metrics/mod.rs":"759ba845d4598e3fea4877d2687da958b15480ec453562c48dac7872ab300ee8","src/metrics/numerator.rs":"442236e1d63b31299f3f073bead683101de995845a638834201c6f30fc03ea90","src/metrics/ping.rs":"5a7b483450fdc145ee8e73f7efef27a9e2b8b551ef5682fc08fcb445a92b5c0d","src/metrics/quantity.rs":"915ab10cf1e1666fc2c707bc51232843e914d93eea2a249eb15df28b6a74cd2b","src/metrics/rate.rs":"38a6986387ec3927dbd81d8a881e257674e91bb97ccd43eb6285f691d5e06531","src/metrics/recorded_experiment.rs":"33958abee79d8b55dec4cb5d20742640423713010f76314075cefde18b5c118a","src/metrics/string.rs":"f7ffc07c23bedc1b8579121d931468b0713834fc037f7945267257fdbdf9a5d0","src/metrics/string_list.rs":"4eeb320cb24dec60c5551c6c9630dbbb292725a5d4c10df8f6c6e2a111eea25e","src/metrics/text.rs":"d727bcc14d2c4f946a517ac0110f585bfbe4898f813bdbad68756505529300f6","src/metrics/time_unit.rs":"b7578010c6270a45b30342b59189a862b2ede9dd24e9afae3e90fa6b970b3d24","src/metrics/timespan.rs":"ae1a2966f0a5446327ad2b9ca0738992976350ad334a5e11fd4ee611a690394e","src/metrics/timing_distribution.rs":"57d4b3f19e7382f80cc596406d3d1c191f61bc3c81f92bf137a13c2fa174c822","src/metrics/url.rs":"9bec842b7a811f01c1f0a0deb54b2dac2f8488882e7e9251cd91d18e6b500939","src/metrics/uuid.rs":"f824019fe3e8d8945490b7eb0ac1c6b7b2ffc991543f4b6332d12827955cf420","src/ping/mod.rs":"e805bfa51007c30c5a549be8d8f7ccbe502db4a8ad5727abaf298a9348f584c0","src/scheduler.rs":"129863e31205404a3d1708627a62583324c347d143f976216f769893ec541ea0","src/storage/mod.rs":"04dc1a94be1d59097cd87b14386952a6ec8b9115bc06397ae389a323f6f55dcc","src/system.rs":"e3d1b54e1d39cafe6f4dc7ff5021b08c879733f909951b0e1332b3efa9ed97bd","src/traits/boolean.rs":"be0e130f8043215705becc956d45b126c340568f1b24a396c0af9b4334a41ced","src/traits/counter.rs":"c686d26e131d854cd7a7df83c900ca7c17a03c663a30cf58ab48c7259476ce85","src/traits/custom_distribution.rs":"159a5e26fb2326f5bcdc46979aa9c6481c5f0e93ecf957f668bb3f6988d8b00f","src/traits/datetime.rs":"636ac1456b1b042e38cf5ae6193c5b232ea0b80df62f583a2097891baef9641b","src/traits/event.rs":"3f48aa336854141784d121f7fa9e283f6ff708a9214f9c0aade3a68cc38dda99","src/traits/labeled.rs":"c633c68e70a44e73f8aff88aaab1029c0faded3cad08d822590ed8838f24b4fd","src/traits/memory_distribution.rs":"55bb8f45e948319fbba9d28a50d8742da134b066a42e480887db7c7e435f4096","src/traits/mod.rs":"d0aa19a7cd97326fd2e026635406a5a9403953ced4954443a2bcbca32d868554","src/traits/numerator.rs":"6e4f236bdc448f1bde7a8c249dcd086204c2c69990d3f444e746290929226ed3","src/traits/ping.rs":"8831c106c03afeb458b0b028fa1ce61f056ebf8e82bc0a171a1bff255d920748","src/traits/quantity.rs":"6ffe25c913bef4315573d747308c182de740b2a4e02ba22cd21d0c33ba521f31","src/traits/rate.rs":"f000790440e0f389f0b160526a9a9a266e58d1405915ae56ac550f482858222c","src/traits/string.rs":"0c3c88382ff2e8eba89c7cfe129c4b84e31140af717819533c14919541ad790c","src/traits/string_list.rs":"14e56b62c2c2be1dd8013f12001f235b084abd2a0d5aa2f7932843877af49ac0","src/traits/text.rs":"8af7d3a0c87cfd8c6d33d6ad47532b431055bbdd395f9110da5630222c23cf93","src/traits/timespan.rs":"52be325a9c061916f34c5b638a07a93b4a14aa89fe365783103d2e06b998f547","src/traits/timing_distribution.rs":"76a7b8640128769763a275e831ed1f1e9ba9bfaab5ff10de638d5be3c57b5421","src/traits/url.rs":"c27f7add23214ff051078b65b88120b620560d2841a1056c7214d5237e86b9e4","src/traits/uuid.rs":"81322e71c7e847bacaf827a2cd58f6193bdc208355524207f7f38db039da6aa8","src/upload/directory.rs":"5fa2c64a2bc561883ec01ed274179d91ff86d40d4d9837661be1b85cd067177c","src/upload/mod.rs":"d281050d7ab29980d48a44240256c21e82858dd795b60549fb46cfd5ce7a0214","src/upload/policy.rs":"c250957a37783e74af8002cd80ba06ef9780a389fb0f61b8b665b79688f0a360","src/upload/request.rs":"a16fbe823228e73a2acc6f4324d6c635be22dfefb19ae71146245d9236baa87a","src/upload/result.rs":"7efbbe50e8d36beb3f23e7bfd172d22e1c003472d2dd8055b06f6050c36437c5","src/util.rs":"ee7500434d9758a320dd410f18d7e18da956591e19d2555db87eef9623e4b916","tests/boolean.rs":"76d6014ff108cb6514d9bceb1b2b14749a55b09921f4595a5e30f1bd3546e9f0","tests/common/mod.rs":"c1d980a9cff0b64f452ebbe43f24d70aa685b80b48db08fc4338a60466b07a5e","tests/counter.rs":"3663a3f5ec5c0bd2b758a9920cd20cc619a12566b445e4421ec7c98232bf5a32","tests/custom_distribution.rs":"53530972243670ef58c85a906b70931d14e81ae2e1f69092c71a27e561edff6c","tests/datetime.rs":"ec3c9760e70bb2cbc61ab23281c891bc1ec493c5c545466c29fd13e4f05c2c96","tests/event.rs":"bf5b8d3ee9d12d12e91b71dd46a813a2cf17f0544f6d2e3b14f6f931ce276fa1","tests/labeled.rs":"e9ea6dba17059d68114efce0c23373be9ceed922bf5e638a2158a6422c75a1c1","tests/memory_distribution.rs":"a5a7aa955e60823ea29a6f4bc96c61e41f1e41f08958aa4854668cf8fe04cde6","tests/ping.rs":"a0fbaed178459c6e3ed3363d966d4a9119cbbcf94574f336f2e7c37eb4b59324","tests/ping_maker.rs":"40dfa0f45af6a35364c068bc53f540b27c95483204104377e0f619a9b10bc711","tests/quantity.rs":"55e7dca346fd1d27f0974b78ca3fb12427cb5da2ee637afc08a54f360f947361","tests/rate.rs":"1de571b9f0ee9a9006cbc8a31f91352d3ff1190b50840f0f668b470a7cd2a3a5","tests/storage.rs":"f0c8312bd789d7bda502cd45f35fef6b8591652bd194d07da4d81935ebe69b48","tests/string.rs":"7ece988a4b8efe6932ccb90bfe2f3c8aaea983777e99d7de6028bf6a29459ee6","tests/string_list.rs":"77188a2b90663c3f8dac5da89a6cb6b1d16a9f8c66ccd032d02966dfd14a3486","tests/text.rs":"1d43f6b90a43124311cacf0a6ee16f9e1e9263bcd11fee8b996d6efd81633638","tests/timespan.rs":"d50d75c7d75da3a878d67331cb0df8ae5e6a099ffab474361f71a408e02528d7","tests/timing_distribution.rs":"dbe2c8efa5dfb8037765b50433568c04ba111953822584da1c4931837fdfc060","tests/uuid.rs":"052ad26a6927c56272219340211cf4a059d200f14287b482fe8621d7bce3cc54","uniffi.toml":"6ddc98b686b0925a81abd9d1c769e5c98ac29771b210a1c535931a46dec9a8e3"},"package":"6831cadd28b625bc296732d71dc7c978f208ba27911cad072785f87f23b1e634"} \ No newline at end of file
+{"files":{"Cargo.toml":"2dde200f0e0e4e523634f8c2c8c1c2ca75af83163ac7b0ba8f62f3096fd0c97d","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"026495898699b54608eb4ec16074ffafc57920d80ccb59961c501a1ea28c9985","build.rs":"4857bea99c6b8c08db8818efa9d3738716f52d3acb68159323957ae52892a3eb","src/common_metric_data.rs":"72051c4349885d4a94fc41bb4edda88d31551f2f9ebcdb4e868a98161bc76233","src/core/mod.rs":"8f5e98a108ec5d1849402af1de90b5f53ba839240743c2c5283a49a4045e1293","src/core_metrics.rs":"a877e42e0f8b932adb52a5681ad76fd977808cb48c7eeb29b1e4bbe804f1ea96","src/coverage.rs":"49613fd310bd24d779472720975fbe6c97ec370a95eb55f10afa43f67539c942","src/database/mod.rs":"3917bad7773696a43ab58e7860d5a8f1d63dca7c27920343aa8786acc5a586cd","src/debug.rs":"90158cc5d488ba67b60d06647e54e59a1d7bdeb906087e4fe4cfab4373c1cc6c","src/dispatcher/global.rs":"f69cd81a90a37c306d4e0ce8177ea5a3ae2ffda5b431ae46b9a22c9e38891271","src/dispatcher/mod.rs":"440a331a7beeaa6e9824c2fd4306c09ce2a115a358d5beb830dba4d69aec3563","src/error.rs":"b93c7d3e243b21bb9eafc95f17860aba1a942b2f2b0a7f43307690f05fece516","src/error_recording.rs":"d7858647808d81173558e12de88f3fbe4e589969e3bd246bfb388f90f8ff3814","src/event_database/mod.rs":"9d4d3e4b075dc585c00317304401b2c9115f39db8fdbd9f1c93d3fc6fd350fd5","src/fd_logger.rs":"0c9def6fa53db1a2ab93c85795f8a7df57797bcfd3978146923e151752e291a6","src/glean.udl":"24d9e431f95d79dc4254feff68f19a4ea4e6e76c33b110e10c5e5dbd5bc64ff2","src/glean_metrics.rs":"9414fb1453d19f6832df33e4c6ef7383d62203e47026bf5bc9552b083101ddd1","src/histogram/exponential.rs":"58bb1770bae45770d92995515d328eb50a7e78726224f779446ae7d1632a6a3e","src/histogram/functional.rs":"1a63a305b48bcef7bc38136b40d916df4bb8f098dc602514ada54a9b091f6951","src/histogram/linear.rs":"4342a1733175d7f97b2b41adb18100537c206100c9fccb5bd13bd782c9cb3c9a","src/histogram/mod.rs":"eeb7aff80806ab76cdce101dc08887b5552f8b4bdf64683f64f767e0f06a889d","src/internal_metrics.rs":"263779535963a804c8c7fa6f8e284ac8ec7f415ceeadbb6a8f913a1e7073ae18","src/internal_pings.rs":"7267166a8e357053526c545cf62bb502a7b6f07aed1de48d43041228d8835366","src/lib.rs":"367ea21f9d3f1c808b258011821d8505cd47d29eff8e8e6d938623e6e9997b73","src/lib_unit_tests.rs":"46897c6bb4003c5e00152d7b55c00d3176b5bffb28d8669a3fb0d10e5233e3a5","src/metrics/boolean.rs":"2b9ef57e3582c9bd8b2cca8ab94c962a4871ecc00e837b913c9b0349ba9dff08","src/metrics/counter.rs":"b4a52a8167fb0edd6354f952525e59f3eadb4261de3483374f03c94449d30b92","src/metrics/custom_distribution.rs":"e1f2edfefb67da4bf369bab3d3047f4ff6539a1fea0eee81c78d96626e5b4bb0","src/metrics/datetime.rs":"e4405762fc71718299fa1b208e3d5fda654bd1b82fe908c884c284e3530de2ec","src/metrics/denominator.rs":"95e8442f90bad97f80fc74b146782f215344b52c5f3825ae0a8baffdc001a714","src/metrics/event.rs":"7281d8b63f34758a47abd7ae3956f44701d1fd48433ccba7a4302526a9912255","src/metrics/experiment.rs":"5f9278cca4e133eb8df33bbfe36d1fe0ef3eade8c09f1b46db3c4d0790515412","src/metrics/labeled.rs":"8d6e76a07064d132cd617c7901f2bc11ff6ba31e3483ba3b96354a4a3736b58d","src/metrics/memory_distribution.rs":"7f6ca51acb470df277ff14427c0e7bb07d921c0a0087d0cc56aebe038d198ccc","src/metrics/memory_unit.rs":"d7a678e5242febd021283b30c0099a9e62729944816a3f17d2d91e2808bc0570","src/metrics/metrics_enabled_config.rs":"87fed12219c756ecf1e5c8cd6a21f26999b6bbcf3ffc1b5467b0a58ca5ad35d8","src/metrics/mod.rs":"8f8958b8cedfe01df6c97ec26b63f14fd7516f9de7ba62984062db96b5708720","src/metrics/numerator.rs":"937dfd583b797ac798a525cedca95c5a36262356760a89670d8113983c263154","src/metrics/object.rs":"89ce5190ed681b26b74a06a4ecaf9f96c36f96be1276f1fdb40f4406648e08c1","src/metrics/ping.rs":"4ccdf0ae2ac6f3e5a352334797d2805f1a3d932e92f08447285dd9bec4e7d724","src/metrics/quantity.rs":"aa13a8f8cf8e5e0281668fbbafc2998411df2a499479423558fd91b9bd7f8702","src/metrics/rate.rs":"603cc45c149c7a27c93b6a80146bf43f8ce70d9655f905bb5be6bc2c15bcb22b","src/metrics/recorded_experiment.rs":"33958abee79d8b55dec4cb5d20742640423713010f76314075cefde18b5c118a","src/metrics/string.rs":"2418632c492463970c3eca533d5318f519698bb361d73dd8781db108d7d1fbd8","src/metrics/string_list.rs":"ed53a095184c3e8224d0511809b5d7601ba3166505a39b0570f24ebeb0a5b97c","src/metrics/text.rs":"5c994a282b16b9dde6d6dc4922475457a72c82f64248778811b84db70ed4c116","src/metrics/time_unit.rs":"b7578010c6270a45b30342b59189a862b2ede9dd24e9afae3e90fa6b970b3d24","src/metrics/timespan.rs":"b0fda3a45597c8306a0d1928dcf0837538859e66ebd9db113ebb6efbea721d4c","src/metrics/timing_distribution.rs":"5da04272dd8b44502ffd0b60b12c84239a7fe359a51754b6c0cd96388a4e8a3c","src/metrics/url.rs":"f6b27a60d13a1268f0115c5d292c9b16b6bc370055961368cb2648283b7140a0","src/metrics/uuid.rs":"cacffd95ab30ed327ec2fa5feaf1359e667706746401f1e2c1195ad9553c4b54","src/ping/mod.rs":"fcadd52d2d536c9ace01f8a3812c3fb3c39b8094915db1b3656839fb87f771b5","src/scheduler.rs":"129863e31205404a3d1708627a62583324c347d143f976216f769893ec541ea0","src/storage/mod.rs":"04dc1a94be1d59097cd87b14386952a6ec8b9115bc06397ae389a323f6f55dcc","src/system.rs":"e3d1b54e1d39cafe6f4dc7ff5021b08c879733f909951b0e1332b3efa9ed97bd","src/traits/boolean.rs":"be0e130f8043215705becc956d45b126c340568f1b24a396c0af9b4334a41ced","src/traits/counter.rs":"c686d26e131d854cd7a7df83c900ca7c17a03c663a30cf58ab48c7259476ce85","src/traits/custom_distribution.rs":"0bd1d425e4c059cca6af2dfb13c78e5e4c6c07fb46c7e31489ad0c5959854833","src/traits/datetime.rs":"636ac1456b1b042e38cf5ae6193c5b232ea0b80df62f583a2097891baef9641b","src/traits/event.rs":"3f48aa336854141784d121f7fa9e283f6ff708a9214f9c0aade3a68cc38dda99","src/traits/labeled.rs":"c633c68e70a44e73f8aff88aaab1029c0faded3cad08d822590ed8838f24b4fd","src/traits/memory_distribution.rs":"55bb8f45e948319fbba9d28a50d8742da134b066a42e480887db7c7e435f4096","src/traits/mod.rs":"d14b69d0946848c1f92cc8977cbc3fc9338ff1b53b7acc31ea0fe2f1122beecb","src/traits/numerator.rs":"6e4f236bdc448f1bde7a8c249dcd086204c2c69990d3f444e746290929226ed3","src/traits/object.rs":"c03bad670ec7affbc578247f9e1904e898c1870b9bf25750c5094113f995623f","src/traits/ping.rs":"8831c106c03afeb458b0b028fa1ce61f056ebf8e82bc0a171a1bff255d920748","src/traits/quantity.rs":"6ffe25c913bef4315573d747308c182de740b2a4e02ba22cd21d0c33ba521f31","src/traits/rate.rs":"f000790440e0f389f0b160526a9a9a266e58d1405915ae56ac550f482858222c","src/traits/string.rs":"0c3c88382ff2e8eba89c7cfe129c4b84e31140af717819533c14919541ad790c","src/traits/string_list.rs":"14e56b62c2c2be1dd8013f12001f235b084abd2a0d5aa2f7932843877af49ac0","src/traits/text.rs":"8af7d3a0c87cfd8c6d33d6ad47532b431055bbdd395f9110da5630222c23cf93","src/traits/timespan.rs":"52be325a9c061916f34c5b638a07a93b4a14aa89fe365783103d2e06b998f547","src/traits/timing_distribution.rs":"00ebdef647a7a208c01d13ba7b3996750e36de98d1f63859b609c80c8df25b6f","src/traits/url.rs":"c27f7add23214ff051078b65b88120b620560d2841a1056c7214d5237e86b9e4","src/traits/uuid.rs":"81322e71c7e847bacaf827a2cd58f6193bdc208355524207f7f38db039da6aa8","src/upload/directory.rs":"6359220db9d85ee0f3931ca518f95ffb2020c1c03bd632f17ed5c16ddd00343b","src/upload/mod.rs":"a388563d5e2940c5c28b48fc7b67ca507512efccae95fd1c2f04b15ec21aa08c","src/upload/policy.rs":"c250957a37783e74af8002cd80ba06ef9780a389fb0f61b8b665b79688f0a360","src/upload/request.rs":"0b7e215f61499a681d1cebc9cf4a0efbaae2f543a5d44e5db40cbe61ed90549e","src/upload/result.rs":"7efbbe50e8d36beb3f23e7bfd172d22e1c003472d2dd8055b06f6050c36437c5","src/util.rs":"ee7500434d9758a320dd410f18d7e18da956591e19d2555db87eef9623e4b916","tests/boolean.rs":"76d6014ff108cb6514d9bceb1b2b14749a55b09921f4595a5e30f1bd3546e9f0","tests/common/mod.rs":"c1d980a9cff0b64f452ebbe43f24d70aa685b80b48db08fc4338a60466b07a5e","tests/counter.rs":"3663a3f5ec5c0bd2b758a9920cd20cc619a12566b445e4421ec7c98232bf5a32","tests/custom_distribution.rs":"41c593a0b4561e21f29d1a5b948de964a866253c58ca76ffefebe370fca150e0","tests/datetime.rs":"ec3c9760e70bb2cbc61ab23281c891bc1ec493c5c545466c29fd13e4f05c2c96","tests/event.rs":"67291cbcc4d1cba56ada6ba733fb1dc4c6327680059e8d7637add2ae45cd344b","tests/labeled.rs":"e9ea6dba17059d68114efce0c23373be9ceed922bf5e638a2158a6422c75a1c1","tests/memory_distribution.rs":"a5a7aa955e60823ea29a6f4bc96c61e41f1e41f08958aa4854668cf8fe04cde6","tests/object.rs":"8c35676e04f6ccf54a28764700915e753fc0355bfa5d7804d72caba66fd564cd","tests/ping.rs":"eb9f6be1aba21acc5dc670622bf622976718a706df1cc2095efa56a8e8b3fe1a","tests/ping_maker.rs":"b267ecf7c714ff27512424b743da0ea4f05a87755c1b96355bfca3e173e3f62e","tests/quantity.rs":"55e7dca346fd1d27f0974b78ca3fb12427cb5da2ee637afc08a54f360f947361","tests/rate.rs":"1de571b9f0ee9a9006cbc8a31f91352d3ff1190b50840f0f668b470a7cd2a3a5","tests/storage.rs":"f0c8312bd789d7bda502cd45f35fef6b8591652bd194d07da4d81935ebe69b48","tests/string.rs":"7ece988a4b8efe6932ccb90bfe2f3c8aaea983777e99d7de6028bf6a29459ee6","tests/string_list.rs":"77188a2b90663c3f8dac5da89a6cb6b1d16a9f8c66ccd032d02966dfd14a3486","tests/text.rs":"1d43f6b90a43124311cacf0a6ee16f9e1e9263bcd11fee8b996d6efd81633638","tests/timespan.rs":"d50d75c7d75da3a878d67331cb0df8ae5e6a099ffab474361f71a408e02528d7","tests/timing_distribution.rs":"20860a7baccdcee6aed40c9cc8202b94f3b2e61164fbaf8f2af96b0f404a895a","tests/uuid.rs":"052ad26a6927c56272219340211cf4a059d200f14287b482fe8621d7bce3cc54","uniffi.toml":"6ddc98b686b0925a81abd9d1c769e5c98ac29771b210a1c535931a46dec9a8e3"},"package":"ed9acc46fd38c5c995a0537e76364496addace660839dc279079e5957e3c1093"} \ No newline at end of file
diff --git a/third_party/rust/glean-core/Cargo.toml b/third_party/rust/glean-core/Cargo.toml
index 44c159051d..9d33444fbd 100644
--- a/third_party/rust/glean-core/Cargo.toml
+++ b/third_party/rust/glean-core/Cargo.toml
@@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.66"
name = "glean-core"
-version = "57.0.0"
+version = "58.1.0"
authors = [
"Jan-Erik Rediger <jrediger@mozilla.com>",
"The Glean Team <glean-team@mozilla.com>",
@@ -35,7 +35,7 @@ license = "MPL-2.0"
repository = "https://github.com/mozilla/glean"
[package.metadata.glean]
-glean-parser = "11.0.1"
+glean-parser = "13.0.0"
[dependencies.bincode]
version = "1.2.1"
diff --git a/third_party/rust/glean-core/src/core/mod.rs b/third_party/rust/glean-core/src/core/mod.rs
index 5a8dd56cde..30f9a34f11 100644
--- a/third_party/rust/glean-core/src/core/mod.rs
+++ b/third_party/rust/glean-core/src/core/mod.rs
@@ -118,11 +118,11 @@ where
/// trim_data_to_registered_pings: false,
/// log_level: None,
/// rate_limit: None,
-/// enable_event_timestamps: false,
+/// enable_event_timestamps: true,
/// experimentation_id: None,
/// };
/// let mut glean = Glean::new(cfg).unwrap();
-/// let ping = PingType::new("sample", true, false, true, vec![]);
+/// let ping = PingType::new("sample", true, false, true, true, vec![]);
/// glean.register_ping_type(&ping);
///
/// let call_counter: CounterMetric = CounterMetric::new(CommonMetricData {
@@ -318,7 +318,7 @@ impl Glean {
trim_data_to_registered_pings: false,
log_level: None,
rate_limit: None,
- enable_event_timestamps: false,
+ enable_event_timestamps: true,
experimentation_id: None,
};
diff --git a/third_party/rust/glean-core/src/glean.udl b/third_party/rust/glean-core/src/glean.udl
index e531f64a26..e68a57ea4c 100644
--- a/third_party/rust/glean-core/src/glean.udl
+++ b/third_party/rust/glean-core/src/glean.udl
@@ -201,6 +201,10 @@ dictionary PingRequest {
sequence<u8> body;
// A map with all the headers to be sent with the request.
record<DOMString, string> headers;
+ // Whether the body has {client|ping}_info sections.
+ boolean body_has_info_sections;
+ // The ping's name. Likely also somewhere in `path`.
+ string ping_name;
};
// An enum representing the possible upload tasks to be performed by an uploader.
@@ -287,7 +291,7 @@ enum ErrorType {
};
interface PingType {
- constructor(string name, boolean include_client_id, boolean send_if_empty, boolean precise_timestamps, sequence<string> reason_codes);
+ constructor(string name, boolean include_client_id, boolean send_if_empty, boolean precise_timestamps, boolean include_info_sections, sequence<string> reason_codes);
void submit(optional string? reason = null);
};
@@ -480,6 +484,8 @@ interface TimingDistributionMetric {
void accumulate_samples(sequence<i64> samples);
+ void accumulate_single_sample(i64 sample);
+
DistributionData? test_get_value(optional string? ping_name = null);
i32 test_get_num_recorded_errors(ErrorType error);
@@ -523,6 +529,8 @@ interface CustomDistributionMetric {
void accumulate_samples(sequence<i64> samples);
+ void accumulate_single_sample(i64 sample);
+
DistributionData? test_get_value(optional string? ping_name = null);
i32 test_get_num_recorded_errors(ErrorType error);
diff --git a/third_party/rust/glean-core/src/internal_pings.rs b/third_party/rust/glean-core/src/internal_pings.rs
index 076a1f7485..07c3849006 100644
--- a/third_party/rust/glean-core/src/internal_pings.rs
+++ b/third_party/rust/glean-core/src/internal_pings.rs
@@ -26,6 +26,7 @@ impl InternalPings {
true,
true,
true,
+ true,
vec![
"active".to_string(),
"dirty_startup".to_string(),
@@ -37,6 +38,7 @@ impl InternalPings {
true,
false,
true,
+ true,
vec![
"overdue".to_string(),
"reschedule".to_string(),
@@ -50,6 +52,7 @@ impl InternalPings {
true,
false,
true,
+ true,
vec![
"startup".to_string(),
"inactive".to_string(),
@@ -61,6 +64,7 @@ impl InternalPings {
true,
true,
true,
+ true,
vec!["at_init".to_string(), "set_upload_enabled".to_string()],
),
}
diff --git a/third_party/rust/glean-core/src/lib.rs b/third_party/rust/glean-core/src/lib.rs
index a54e57a95b..b7f9d73beb 100644
--- a/third_party/rust/glean-core/src/lib.rs
+++ b/third_party/rust/glean-core/src/lib.rs
@@ -91,12 +91,12 @@ pub(crate) const DELETION_REQUEST_PINGS_DIRECTORY: &str = "deletion_request";
static INITIALIZE_CALLED: AtomicBool = AtomicBool::new(false);
/// Keep track of the debug features before Glean is initialized.
-static PRE_INIT_DEBUG_VIEW_TAG: OnceCell<Mutex<String>> = OnceCell::new();
+static PRE_INIT_DEBUG_VIEW_TAG: Mutex<String> = Mutex::new(String::new());
static PRE_INIT_LOG_PINGS: AtomicBool = AtomicBool::new(false);
-static PRE_INIT_SOURCE_TAGS: OnceCell<Mutex<Vec<String>>> = OnceCell::new();
+static PRE_INIT_SOURCE_TAGS: Mutex<Vec<String>> = Mutex::new(Vec::new());
/// Keep track of pings registered before Glean is initialized.
-static PRE_INIT_PING_REGISTRATION: OnceCell<Mutex<Vec<metrics::PingType>>> = OnceCell::new();
+static PRE_INIT_PING_REGISTRATION: Mutex<Vec<metrics::PingType>> = Mutex::new(Vec::new());
/// Global singleton of the handles of the glean.init threads.
/// For joining. For tests.
@@ -396,11 +396,9 @@ fn initialize_inner(
core::with_glean_mut(|glean| {
// The debug view tag might have been set before initialize,
// get the cached value and set it.
- if let Some(tag) = PRE_INIT_DEBUG_VIEW_TAG.get() {
- let lock = tag.try_lock();
- if let Ok(ref debug_tag) = lock {
- glean.set_debug_view_tag(debug_tag);
- }
+ let debug_tag = PRE_INIT_DEBUG_VIEW_TAG.lock().unwrap();
+ if debug_tag.len() > 0 {
+ glean.set_debug_view_tag(&debug_tag);
}
// The log pings debug option might have been set before initialize,
@@ -412,11 +410,9 @@ fn initialize_inner(
// The source tags might have been set before initialize,
// get the cached value and set them.
- if let Some(tags) = PRE_INIT_SOURCE_TAGS.get() {
- let lock = tags.try_lock();
- if let Ok(ref source_tags) = lock {
- glean.set_source_tags(source_tags.to_vec());
- }
+ let source_tags = PRE_INIT_SOURCE_TAGS.lock().unwrap();
+ if source_tags.len() > 0 {
+ glean.set_source_tags(source_tags.to_vec());
}
// Get the current value of the dirty flag so we know whether to
@@ -428,13 +424,9 @@ fn initialize_inner(
// Perform registration of pings that were attempted to be
// registered before init.
- if let Some(tags) = PRE_INIT_PING_REGISTRATION.get() {
- let lock = tags.try_lock();
- if let Ok(pings) = lock {
- for ping in &*pings {
- glean.register_ping_type(ping);
- }
- }
+ let pings = PRE_INIT_PING_REGISTRATION.lock().unwrap();
+ for ping in pings.iter() {
+ glean.register_ping_type(ping);
}
// If this is the first time ever the Glean SDK runs, make sure to set
@@ -861,7 +853,7 @@ pub(crate) fn register_ping_type(ping: &PingType) {
// if ping registration is attempted before Glean initializes.
// This state is kept across Glean resets, which should only ever happen in test mode.
// It's a set and keeping them around forever should not have much of an impact.
- let m = PRE_INIT_PING_REGISTRATION.get_or_init(Default::default);
+ let m = &PRE_INIT_PING_REGISTRATION;
let mut lock = m.lock().unwrap();
lock.push(ping.clone());
}
@@ -956,7 +948,7 @@ pub fn glean_set_debug_view_tag(tag: String) -> bool {
true
} else {
// Glean has not been initialized yet. Cache the provided tag value.
- let m = PRE_INIT_DEBUG_VIEW_TAG.get_or_init(Default::default);
+ let m = &PRE_INIT_DEBUG_VIEW_TAG;
let mut lock = m.lock().unwrap();
*lock = tag;
// When setting the debug view tag before initialization,
@@ -984,7 +976,7 @@ pub fn glean_set_source_tags(tags: Vec<String>) -> bool {
true
} else {
// Glean has not been initialized yet. Cache the provided source tags.
- let m = PRE_INIT_SOURCE_TAGS.get_or_init(Default::default);
+ let m = &PRE_INIT_SOURCE_TAGS;
let mut lock = m.lock().unwrap();
*lock = tags;
// When setting the source tags before initialization,
diff --git a/third_party/rust/glean-core/src/lib_unit_tests.rs b/third_party/rust/glean-core/src/lib_unit_tests.rs
index 0fc85b4602..cb1e4129d8 100644
--- a/third_party/rust/glean-core/src/lib_unit_tests.rs
+++ b/third_party/rust/glean-core/src/lib_unit_tests.rs
@@ -197,7 +197,7 @@ fn experimentation_id_is_set_correctly() {
trim_data_to_registered_pings: false,
log_level: None,
rate_limit: None,
- enable_event_timestamps: false,
+ enable_event_timestamps: true,
experimentation_id: Some(experimentation_id.to_string()),
})
.unwrap();
@@ -423,6 +423,7 @@ fn correct_order() {
Jwe("eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGeipsEdY3mx_etLbbWSrFr05kLzcSr4qKAq7YN7e9jwQRb23nfa6c9d-StnImGyFDbSv04uVuxIp5Zms1gNxKKK2Da14B8S4rzVRltdYwam_lDp5XnZAYpQdb76FdIKLaVmqgfwX7XWRxv2322i-vDxRfqNzo_tETKzpVLzfiwQyeyPGLBIO56YJ7eObdv0je81860ppamavo35UgoRdbYaBcoh9QcfylQr66oc6vFWXRcZ_ZT2LawVCWTIy3brGPi6UklfCpIMfIjf7iGdXKHzg.48V1_ALb6US04U3b.5eym8TW_c8SuK0ltJ3rpYIzOeDQz7TALvtu6UG9oMo4vpzs9tX_EFShS8iB7j6jiSdiwkIr3ajwQzaBtQD_A.XFBoMYUZodetZdvTiFvSkQ".into()),
Rate(0, 0),
Text(long_string),
+ Object("{}".into()),
];
for metric in all_metrics {
@@ -451,6 +452,7 @@ fn correct_order() {
Rate(..) => assert_eq!(14, disc),
Url(..) => assert_eq!(15, disc),
Text(..) => assert_eq!(16, disc),
+ Object(..) => assert_eq!(17, disc),
}
}
}
diff --git a/third_party/rust/glean-core/src/metrics/boolean.rs b/third_party/rust/glean-core/src/metrics/boolean.rs
index 71ed2372c2..ade4a22bfc 100644
--- a/third_party/rust/glean-core/src/metrics/boolean.rs
+++ b/third_party/rust/glean-core/src/metrics/boolean.rs
@@ -74,7 +74,6 @@ impl BooleanMetric {
///
/// # Arguments
///
- /// * `glean` - the Glean instance this metric belongs to.
/// * `value` - the value to set.
pub fn set(&self, value: bool) {
let metric = self.clone();
@@ -106,6 +105,15 @@ impl BooleanMetric {
/// Gets the currently stored value as an integer.
///
/// This doesn't clear the stored value.
+ ///
+ /// # Arguments
+ ///
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
+ ///
+ /// # Returns
+ ///
+ /// The stored value or `None` if nothing stored.
pub fn test_get_value(&self, ping_name: Option<String>) -> Option<bool> {
crate::block_on_dispatcher();
crate::core::with_glean(|glean| self.get_value(glean, ping_name.as_deref()))
@@ -118,8 +126,6 @@ impl BooleanMetric {
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - represents the optional name of the ping to retrieve the
- /// metric for. inner to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/metrics/counter.rs b/third_party/rust/glean-core/src/metrics/counter.rs
index 8f0a01cc3e..7e262c7d68 100644
--- a/third_party/rust/glean-core/src/metrics/counter.rs
+++ b/third_party/rust/glean-core/src/metrics/counter.rs
@@ -105,7 +105,6 @@ impl CounterMetric {
///
/// # Arguments
///
- /// * `glean` - The Glean instance this metric belongs to.
/// * `amount` - The amount to increase by. Should be positive.
///
/// ## Notes
@@ -143,6 +142,15 @@ impl CounterMetric {
/// Gets the currently stored value as an integer.
///
/// This doesn't clear the stored value.
+ ///
+ /// # Arguments
+ ///
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
+ ///
+ /// # Returns
+ ///
+ /// The stored value or `None` if nothing stored.
pub fn test_get_value(&self, ping_name: Option<String>) -> Option<i32> {
crate::block_on_dispatcher();
crate::core::with_glean(|glean| self.get_value(glean, ping_name.as_deref()))
@@ -155,8 +163,6 @@ impl CounterMetric {
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - represents the optional name of the ping to retrieve the
- /// metric for. inner to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/metrics/custom_distribution.rs b/third_party/rust/glean-core/src/metrics/custom_distribution.rs
index 929e4863ec..c7f3fbc56f 100644
--- a/third_party/rust/glean-core/src/metrics/custom_distribution.rs
+++ b/third_party/rust/glean-core/src/metrics/custom_distribution.rs
@@ -84,14 +84,33 @@ impl CustomDistributionMetric {
/// for each of them.
pub fn accumulate_samples(&self, samples: Vec<i64>) {
let metric = self.clone();
- crate::launch_with_glean(move |glean| metric.accumulate_samples_sync(glean, samples))
+ crate::launch_with_glean(move |glean| metric.accumulate_samples_sync(glean, &samples))
+ }
+
+ /// Accumulates precisely one signed sample and appends it to the metric.
+ ///
+ /// Signed is required so that the platform-specific code can provide us with a
+ /// 64 bit signed integer if no `u64` comparable type is available. This
+ /// will take care of filtering and reporting errors.
+ ///
+ /// # Arguments
+ ///
+ /// - `sample` - The singular sample to be recorded by the metric.
+ ///
+ /// ## Notes
+ ///
+ /// Discards any negative value of `sample` and reports an
+ /// [`ErrorType::InvalidValue`](crate::ErrorType::InvalidValue).
+ pub fn accumulate_single_sample(&self, sample: i64) {
+ let metric = self.clone();
+ crate::launch_with_glean(move |glean| metric.accumulate_samples_sync(glean, &[sample]))
}
/// Accumulates the provided sample in the metric synchronously.
///
/// See [`accumulate_samples`](Self::accumulate_samples) for details.
#[doc(hidden)]
- pub fn accumulate_samples_sync(&self, glean: &Glean, samples: Vec<i64>) {
+ pub fn accumulate_samples_sync(&self, glean: &Glean, samples: &[i64]) {
if !self.should_record(glean) {
return;
}
@@ -132,7 +151,7 @@ impl CustomDistributionMetric {
self.bucket_count as usize,
)
};
- accumulate(&samples, hist, Metric::CustomDistributionLinear)
+ accumulate(samples, hist, Metric::CustomDistributionLinear)
}
HistogramType::Exponential => {
let hist = if let Some(Metric::CustomDistributionExponential(hist)) = old_value
@@ -145,7 +164,7 @@ impl CustomDistributionMetric {
self.bucket_count as usize,
)
};
- accumulate(&samples, hist, Metric::CustomDistributionExponential)
+ accumulate(samples, hist, Metric::CustomDistributionExponential)
}
};
@@ -194,6 +213,15 @@ impl CustomDistributionMetric {
/// Gets the currently stored value as an integer.
///
/// This doesn't clear the stored value.
+ ///
+ /// # Arguments
+ ///
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
+ ///
+ /// # Returns
+ ///
+ /// The stored value or `None` if nothing stored.
pub fn test_get_value(&self, ping_name: Option<String>) -> Option<DistributionData> {
crate::block_on_dispatcher();
crate::core::with_glean(|glean| self.get_value(glean, ping_name.as_deref()))
@@ -206,8 +234,6 @@ impl CustomDistributionMetric {
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - represents the optional name of the ping to retrieve the
- /// metric for. inner to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/metrics/datetime.rs b/third_party/rust/glean-core/src/metrics/datetime.rs
index 3ef846a32c..e04f7fc051 100644
--- a/third_party/rust/glean-core/src/metrics/datetime.rs
+++ b/third_party/rust/glean-core/src/metrics/datetime.rs
@@ -262,8 +262,8 @@ impl DatetimeMetric {
///
/// # Arguments
///
- /// * `glean` - the Glean instance this metric belongs to.
- /// * `storage_name` - the storage name to look into.
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
///
/// # Returns
///
@@ -284,8 +284,8 @@ impl DatetimeMetric {
///
/// # Arguments
///
- /// * `glean` - the Glean instance this metric belongs to.
- /// * `storage_name` - the storage name to look into.
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
///
/// # Returns
///
@@ -311,8 +311,6 @@ impl DatetimeMetric {
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - represents the optional name of the ping to retrieve the
- /// metric for. inner to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/metrics/denominator.rs b/third_party/rust/glean-core/src/metrics/denominator.rs
index fb80874924..3083d6e78a 100644
--- a/third_party/rust/glean-core/src/metrics/denominator.rs
+++ b/third_party/rust/glean-core/src/metrics/denominator.rs
@@ -91,6 +91,15 @@ impl DenominatorMetric {
/// Gets the currently stored value as an integer.
///
/// This doesn't clear the stored value.
+ ///
+ /// # Arguments
+ ///
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
+ ///
+ /// # Returns
+ ///
+ /// The stored value or `None` if nothing stored.
pub fn test_get_value(&self, ping_name: Option<String>) -> Option<i32> {
crate::block_on_dispatcher();
crate::core::with_glean(|glean| self.get_value(glean, ping_name.as_deref()))
@@ -124,8 +133,6 @@ impl DenominatorMetric {
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - the optional name of the ping to retrieve the metric
- /// for. inner to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/metrics/event.rs b/third_party/rust/glean-core/src/metrics/event.rs
index 5ad6e6d50c..c7aefd9cd6 100644
--- a/third_party/rust/glean-core/src/metrics/event.rs
+++ b/third_party/rust/glean-core/src/metrics/event.rs
@@ -185,6 +185,11 @@ impl EventMetric {
/// Get the vector of currently stored events for this event metric.
///
/// This doesn't clear the stored value.
+ ///
+ /// # Arguments
+ ///
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
pub fn test_get_value(&self, ping_name: Option<String>) -> Option<Vec<RecordedEvent>> {
crate::block_on_dispatcher();
crate::core::with_glean(|glean| self.get_value(glean, ping_name.as_deref()))
@@ -197,8 +202,6 @@ impl EventMetric {
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - represents the optional name of the ping to retrieve the
- /// metric for. inner to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/metrics/experiment.rs b/third_party/rust/glean-core/src/metrics/experiment.rs
index 23e6c41ce2..5695bf942e 100644
--- a/third_party/rust/glean-core/src/metrics/experiment.rs
+++ b/third_party/rust/glean-core/src/metrics/experiment.rs
@@ -195,6 +195,15 @@ impl ExperimentMetric {
/// the RecordedExperiment.
///
/// This doesn't clear the stored value.
+ ///
+ /// # Arguments
+ ///
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
+ ///
+ /// # Returns
+ ///
+ /// The stored value or `None` if nothing stored.
pub fn test_get_value(&self, glean: &Glean) -> Option<RecordedExperiment> {
match StorageManager.snapshot_metric_for_test(
glean.storage(),
diff --git a/third_party/rust/glean-core/src/metrics/labeled.rs b/third_party/rust/glean-core/src/metrics/labeled.rs
index fa3e6a6a75..f9f6a28880 100644
--- a/third_party/rust/glean-core/src/metrics/labeled.rs
+++ b/third_party/rust/glean-core/src/metrics/labeled.rs
@@ -205,8 +205,6 @@ where
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - represents the optional name of the ping to retrieve the
- /// metric for. Defaults to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/metrics/memory_distribution.rs b/third_party/rust/glean-core/src/metrics/memory_distribution.rs
index ac9eda1a90..7b5e5ee192 100644
--- a/third_party/rust/glean-core/src/metrics/memory_distribution.rs
+++ b/third_party/rust/glean-core/src/metrics/memory_distribution.rs
@@ -254,6 +254,15 @@ impl MemoryDistributionMetric {
/// Gets the currently stored value.
///
/// This doesn't clear the stored value.
+ ///
+ /// # Arguments
+ ///
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
+ ///
+ /// # Returns
+ ///
+ /// The stored value or `None` if nothing stored.
pub fn test_get_value(&self, ping_name: Option<String>) -> Option<DistributionData> {
crate::block_on_dispatcher();
crate::core::with_glean(|glean| self.get_value(glean, ping_name.as_deref()))
@@ -266,8 +275,6 @@ impl MemoryDistributionMetric {
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - represents the optional name of the ping to retrieve the
- /// metric for. Defaults to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/metrics/mod.rs b/third_party/rust/glean-core/src/metrics/mod.rs
index 43253b9aa7..92001efd2a 100644
--- a/third_party/rust/glean-core/src/metrics/mod.rs
+++ b/third_party/rust/glean-core/src/metrics/mod.rs
@@ -9,7 +9,8 @@ use std::sync::atomic::Ordering;
use chrono::{DateTime, FixedOffset};
use serde::{Deserialize, Serialize};
-use serde_json::{json, Value as JsonValue};
+use serde_json::json;
+pub use serde_json::Value as JsonValue;
mod boolean;
mod counter;
@@ -23,6 +24,7 @@ mod memory_distribution;
mod memory_unit;
mod metrics_enabled_config;
mod numerator;
+mod object;
mod ping;
mod quantity;
mod rate;
@@ -54,6 +56,7 @@ pub use self::labeled::{LabeledBoolean, LabeledCounter, LabeledMetric, LabeledSt
pub use self::memory_distribution::MemoryDistributionMetric;
pub use self::memory_unit::MemoryUnit;
pub use self::numerator::NumeratorMetric;
+pub use self::object::ObjectMetric;
pub use self::ping::PingType;
pub use self::quantity::QuantityMetric;
pub use self::rate::{Rate, RateMetric};
@@ -141,6 +144,8 @@ pub enum Metric {
Url(String),
/// A Text metric. See [`TextMetric`] for more information.
Text(String),
+ /// An Object metric. See [`ObjectMetric`] for more information.
+ Object(String),
}
/// A [`MetricType`] describes common behavior across all metrics.
@@ -251,6 +256,7 @@ impl Metric {
Metric::MemoryDistribution(_) => "memory_distribution",
Metric::Jwe(_) => "jwe",
Metric::Text(_) => "text",
+ Metric::Object(_) => "object",
}
}
@@ -280,6 +286,9 @@ impl Metric {
Metric::MemoryDistribution(hist) => json!(memory_distribution::snapshot(hist)),
Metric::Jwe(s) => json!(s),
Metric::Text(s) => json!(s),
+ Metric::Object(s) => {
+ serde_json::from_str(s).expect("object storage should have been json")
+ }
}
}
}
diff --git a/third_party/rust/glean-core/src/metrics/numerator.rs b/third_party/rust/glean-core/src/metrics/numerator.rs
index 3c340cab1d..de29338a5c 100644
--- a/third_party/rust/glean-core/src/metrics/numerator.rs
+++ b/third_party/rust/glean-core/src/metrics/numerator.rs
@@ -55,12 +55,16 @@ impl NumeratorMetric {
///
/// Gets the currently stored value as a pair of integers.
///
+ /// This doesn't clear the stored value.
+ ///
/// # Arguments
///
/// * `ping_name` - the optional name of the ping to retrieve the metric
/// for. Defaults to the first value in `send_in_pings`.
///
- /// This doesn't clear the stored value.
+ /// # Returns
+ ///
+ /// The stored value or `None` if nothing stored.
pub fn test_get_value(&self, ping_name: Option<String>) -> Option<Rate> {
crate::block_on_dispatcher();
crate::core::with_glean(|glean| self.get_value(glean, ping_name.as_deref()))
@@ -82,8 +86,6 @@ impl NumeratorMetric {
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - the optional name of the ping to retrieve the metric
- /// for. Defaults to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/metrics/object.rs b/third_party/rust/glean-core/src/metrics/object.rs
new file mode 100644
index 0000000000..6071e2b33a
--- /dev/null
+++ b/third_party/rust/glean-core/src/metrics/object.rs
@@ -0,0 +1,135 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+use std::sync::Arc;
+
+use crate::common_metric_data::CommonMetricDataInternal;
+use crate::error_recording::{record_error, test_get_num_recorded_errors, ErrorType};
+use crate::metrics::JsonValue;
+use crate::metrics::Metric;
+use crate::metrics::MetricType;
+use crate::storage::StorageManager;
+use crate::CommonMetricData;
+use crate::Glean;
+
+/// An object metric.
+///
+/// Record structured data.
+/// The value must adhere to a predefined structure and is serialized into JSON.
+#[derive(Clone, Debug)]
+pub struct ObjectMetric {
+ meta: Arc<CommonMetricDataInternal>,
+}
+
+impl MetricType for ObjectMetric {
+ fn meta(&self) -> &CommonMetricDataInternal {
+ &self.meta
+ }
+}
+
+// IMPORTANT:
+//
+// When changing this implementation, make sure all the operations are
+// also declared in the related trait in `../traits/`.
+impl ObjectMetric {
+ /// Creates a new object metric.
+ pub fn new(meta: CommonMetricData) -> Self {
+ Self {
+ meta: Arc::new(meta.into()),
+ }
+ }
+
+ /// Sets to the specified structure.
+ ///
+ /// # Arguments
+ ///
+ /// * `glean` - the Glean instance this metric belongs to.
+ /// * `value` - the value to set.
+ #[doc(hidden)]
+ pub fn set_sync(&self, glean: &Glean, value: JsonValue) {
+ let value = Metric::Object(serde_json::to_string(&value).unwrap());
+ glean.storage().record(glean, &self.meta, &value)
+ }
+
+ /// Sets to the specified structure.
+ ///
+ /// No additional verification is done.
+ /// The shape needs to be externally verified.
+ ///
+ /// # Arguments
+ ///
+ /// * `value` - the value to set.
+ pub fn set(&self, value: JsonValue) {
+ let metric = self.clone();
+ crate::launch_with_glean(move |glean| metric.set_sync(glean, value))
+ }
+
+ /// Record an `InvalidValue` error for this metric.
+ ///
+ /// Only to be used by the RLB.
+ // TODO(bug 1691073): This can probably go once we have a more generic mechanism to record
+ // errors
+ pub fn record_schema_error(&self) {
+ let metric = self.clone();
+ crate::launch_with_glean(move |glean| {
+ let msg = "Value did not match predefined schema";
+ record_error(glean, &metric.meta, ErrorType::InvalidValue, msg, None);
+ });
+ }
+
+ /// Get current value
+ #[doc(hidden)]
+ pub fn get_value<'a, S: Into<Option<&'a str>>>(
+ &self,
+ glean: &Glean,
+ ping_name: S,
+ ) -> Option<String> {
+ let queried_ping_name = ping_name
+ .into()
+ .unwrap_or_else(|| &self.meta().inner.send_in_pings[0]);
+
+ match StorageManager.snapshot_metric_for_test(
+ glean.storage(),
+ queried_ping_name,
+ &self.meta.identifier(glean),
+ self.meta.inner.lifetime,
+ ) {
+ Some(Metric::Object(o)) => Some(o),
+ _ => None,
+ }
+ }
+
+ /// **Test-only API (exported for FFI purposes).**
+ ///
+ /// Gets the currently stored value as JSON.
+ ///
+ /// This doesn't clear the stored value.
+ pub fn test_get_value(&self, ping_name: Option<String>) -> Option<JsonValue> {
+ crate::block_on_dispatcher();
+ let value = crate::core::with_glean(|glean| self.get_value(glean, ping_name.as_deref()));
+ // We only store valid JSON
+ value.map(|val| serde_json::from_str(&val).unwrap())
+ }
+
+ /// **Exported for test purposes.**
+ ///
+ /// Gets the number of recorded errors for the given metric and error type.
+ ///
+ /// # Arguments
+ ///
+ /// * `error` - The type of error
+ /// * `ping_name` - represents the optional name of the ping to retrieve the
+ /// metric for. inner to the first value in `send_in_pings`.
+ ///
+ /// # Returns
+ ///
+ /// The number of errors reported.
+ pub fn test_get_num_recorded_errors(&self, error: ErrorType) -> i32 {
+ crate::block_on_dispatcher();
+
+ crate::core::with_glean(|glean| {
+ test_get_num_recorded_errors(glean, self.meta(), error).unwrap_or(0)
+ })
+ }
+}
diff --git a/third_party/rust/glean-core/src/metrics/ping.rs b/third_party/rust/glean-core/src/metrics/ping.rs
index dc37d76a45..e60284b1e2 100644
--- a/third_party/rust/glean-core/src/metrics/ping.rs
+++ b/third_party/rust/glean-core/src/metrics/ping.rs
@@ -6,6 +6,7 @@ use std::fmt;
use std::sync::Arc;
use crate::ping::PingMaker;
+use crate::upload::PingPayload;
use crate::Glean;
use uuid::Uuid;
@@ -26,6 +27,8 @@ struct InnerPing {
pub send_if_empty: bool,
/// Whether to use millisecond-precise start/end times.
pub precise_timestamps: bool,
+ /// Whether to include the {client|ping}_info sections on assembly.
+ pub include_info_sections: bool,
/// The "reason" codes that this ping can send
pub reason_codes: Vec<String>,
}
@@ -37,6 +40,7 @@ impl fmt::Debug for PingType {
.field("include_client_id", &self.0.include_client_id)
.field("send_if_empty", &self.0.send_if_empty)
.field("precise_timestamps", &self.0.precise_timestamps)
+ .field("include_info_sections", &self.0.include_info_sections)
.field("reason_codes", &self.0.reason_codes)
.finish()
}
@@ -61,6 +65,7 @@ impl PingType {
include_client_id: bool,
send_if_empty: bool,
precise_timestamps: bool,
+ include_info_sections: bool,
reason_codes: Vec<String>,
) -> Self {
let this = Self(Arc::new(InnerPing {
@@ -68,6 +73,7 @@ impl PingType {
include_client_id,
send_if_empty,
precise_timestamps,
+ include_info_sections,
reason_codes,
}));
@@ -94,6 +100,10 @@ impl PingType {
self.0.precise_timestamps
}
+ pub(crate) fn include_info_sections(&self) -> bool {
+ self.0.include_info_sections
+ }
+
/// Submits the ping for eventual uploading.
///
/// The ping content is assembled as soon as possible, but upload is not
@@ -186,13 +196,17 @@ impl PingType {
// so both scenarios should be impossible.
let content =
::serde_json::to_string(&ping.content).expect("ping serialization failed");
- glean.upload_manager.enqueue_ping(
- glean,
- ping.doc_id,
- ping.url_path,
- &content,
- Some(ping.headers),
- );
+ // TODO: Shouldn't we consolidate on a single collected Ping representation?
+ let ping = PingPayload {
+ document_id: ping.doc_id.to_string(),
+ upload_path: ping.url_path.to_string(),
+ json_body: content,
+ headers: Some(ping.headers),
+ body_has_info_sections: self.0.include_info_sections,
+ ping_name: self.0.name.to_string(),
+ };
+
+ glean.upload_manager.enqueue_ping(glean, ping);
return true;
}
diff --git a/third_party/rust/glean-core/src/metrics/quantity.rs b/third_party/rust/glean-core/src/metrics/quantity.rs
index c59d3a4a21..92216625d6 100644
--- a/third_party/rust/glean-core/src/metrics/quantity.rs
+++ b/third_party/rust/glean-core/src/metrics/quantity.rs
@@ -98,6 +98,15 @@ impl QuantityMetric {
/// Gets the currently stored value as an integer.
///
/// This doesn't clear the stored value.
+ ///
+ /// # Arguments
+ ///
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
+ ///
+ /// # Returns
+ ///
+ /// The stored value or `None` if nothing stored.
pub fn test_get_value(&self, ping_name: Option<String>) -> Option<i64> {
crate::block_on_dispatcher();
crate::core::with_glean(|glean| self.get_value(glean, ping_name.as_deref()))
@@ -110,8 +119,6 @@ impl QuantityMetric {
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - represents the optional name of the ping to retrieve the
- /// metric for. Defaults to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/metrics/rate.rs b/third_party/rust/glean-core/src/metrics/rate.rs
index ba7f085b55..843d35002e 100644
--- a/third_party/rust/glean-core/src/metrics/rate.rs
+++ b/third_party/rust/glean-core/src/metrics/rate.rs
@@ -141,6 +141,15 @@ impl RateMetric {
/// Gets the currently stored value as a pair of integers.
///
/// This doesn't clear the stored value.
+ ///
+ /// # Arguments
+ ///
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
+ ///
+ /// # Returns
+ ///
+ /// The stored value or `None` if nothing stored.
pub fn test_get_value(&self, ping_name: Option<String>) -> Option<Rate> {
crate::block_on_dispatcher();
crate::core::with_glean(|glean| self.get_value(glean, ping_name.as_deref()))
@@ -175,8 +184,6 @@ impl RateMetric {
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - represents the optional name of the ping to retrieve the
- /// metric for. Defaults to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/metrics/string.rs b/third_party/rust/glean-core/src/metrics/string.rs
index 5ed7b2c7f1..4aa30a8d7e 100644
--- a/third_party/rust/glean-core/src/metrics/string.rs
+++ b/third_party/rust/glean-core/src/metrics/string.rs
@@ -112,6 +112,15 @@ impl StringMetric {
/// Gets the currently stored value as a string.
///
/// This doesn't clear the stored value.
+ ///
+ /// # Arguments
+ ///
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
+ ///
+ /// # Returns
+ ///
+ /// The stored value or `None` if nothing stored.
pub fn test_get_value(&self, ping_name: Option<String>) -> Option<String> {
crate::block_on_dispatcher();
crate::core::with_glean(|glean| self.get_value(glean, ping_name.as_deref()))
@@ -124,8 +133,6 @@ impl StringMetric {
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - represents the optional name of the ping to retrieve the
- /// metric for. Defaults to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/metrics/string_list.rs b/third_party/rust/glean-core/src/metrics/string_list.rs
index 75b2df7f80..cd4e71b885 100644
--- a/third_party/rust/glean-core/src/metrics/string_list.rs
+++ b/third_party/rust/glean-core/src/metrics/string_list.rs
@@ -171,6 +171,15 @@ impl StringListMetric {
/// Gets the currently-stored values.
///
/// This doesn't clear the stored value.
+ ///
+ /// # Arguments
+ ///
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
+ ///
+ /// # Returns
+ ///
+ /// The stored value or `None` if nothing stored.
pub fn test_get_value(&self, ping_name: Option<String>) -> Option<Vec<String>> {
crate::block_on_dispatcher();
crate::core::with_glean(|glean| self.get_value(glean, ping_name.as_deref()))
@@ -183,8 +192,6 @@ impl StringListMetric {
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - represents the optional name of the ping to retrieve the
- /// metric for. Defaults to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/metrics/text.rs b/third_party/rust/glean-core/src/metrics/text.rs
index 06ad5c0d78..baa8e88d75 100644
--- a/third_party/rust/glean-core/src/metrics/text.rs
+++ b/third_party/rust/glean-core/src/metrics/text.rs
@@ -116,6 +116,15 @@ impl TextMetric {
/// Gets the currently stored value as a string.
///
/// This doesn't clear the stored value.
+ ///
+ /// # Arguments
+ ///
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
+ ///
+ /// # Returns
+ ///
+ /// The stored value or `None` if nothing stored.
pub fn test_get_value(&self, ping_name: Option<String>) -> Option<String> {
crate::block_on_dispatcher();
crate::core::with_glean(|glean| self.get_value(glean, ping_name.as_deref()))
@@ -128,8 +137,6 @@ impl TextMetric {
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - represents the optional name of the ping to retrieve the
- /// metric for. Defaults to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/metrics/timespan.rs b/third_party/rust/glean-core/src/metrics/timespan.rs
index b4d3bd5902..ee63fb52f8 100644
--- a/third_party/rust/glean-core/src/metrics/timespan.rs
+++ b/third_party/rust/glean-core/src/metrics/timespan.rs
@@ -253,6 +253,15 @@ impl TimespanMetric {
/// Gets the currently stored value as an integer.
///
/// This doesn't clear the stored value.
+ ///
+ /// # Arguments
+ ///
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
+ ///
+ /// # Returns
+ ///
+ /// The stored value or `None` if nothing stored.
pub fn test_get_value(&self, ping_name: Option<String>) -> Option<i64> {
crate::block_on_dispatcher();
crate::core::with_glean(|glean| {
@@ -292,8 +301,6 @@ impl TimespanMetric {
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - represents the optional name of the ping to retrieve the
- /// metric for. Defaults to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/metrics/timing_distribution.rs b/third_party/rust/glean-core/src/metrics/timing_distribution.rs
index e339ef8882..3293be9518 100644
--- a/third_party/rust/glean-core/src/metrics/timing_distribution.rs
+++ b/third_party/rust/glean-core/src/metrics/timing_distribution.rs
@@ -293,7 +293,35 @@ impl TimingDistributionMetric {
/// are longer than `MAX_SAMPLE_TIME`.
pub fn accumulate_samples(&self, samples: Vec<i64>) {
let metric = self.clone();
- crate::launch_with_glean(move |glean| metric.accumulate_samples_sync(glean, samples))
+ crate::launch_with_glean(move |glean| metric.accumulate_samples_sync(glean, &samples))
+ }
+
+ /// Accumulates precisely one signed sample and appends it to the metric.
+ ///
+ /// Precludes the need for a collection in the most common use case.
+ ///
+ /// Sign is required so that the platform-specific code can provide us with
+ /// a 64 bit signed integer if no `u64` comparable type is available. This
+ /// will take care of filtering and reporting errors for any provided negative
+ /// sample.
+ ///
+ /// Please note that this assumes that the provided sample is already in
+ /// the "unit" declared by the instance of the metric type (e.g. if the
+ /// instance this method was called on is using [`crate::TimeUnit::Second`], then
+ /// `sample` is assumed to be in that unit).
+ ///
+ /// # Arguments
+ ///
+ /// * `sample` - The singular sample to be recorded by the metric.
+ ///
+ /// ## Notes
+ ///
+ /// Discards any negative value and reports an [`ErrorType::InvalidValue`].
+ /// Reports an [`ErrorType::InvalidOverflow`] error if the sample is longer than
+ /// `MAX_SAMPLE_TIME`.
+ pub fn accumulate_single_sample(&self, sample: i64) {
+ let metric = self.clone();
+ crate::launch_with_glean(move |glean| metric.accumulate_samples_sync(glean, &[sample]))
}
/// **Test-only API (exported for testing purposes).**
@@ -301,7 +329,7 @@ impl TimingDistributionMetric {
///
/// Use [`accumulate_samples`](Self::accumulate_samples)
#[doc(hidden)]
- pub fn accumulate_samples_sync(&self, glean: &Glean, samples: Vec<i64>) {
+ pub fn accumulate_samples_sync(&self, glean: &Glean, samples: &[i64]) {
if !self.should_record(glean) {
return;
}
@@ -464,6 +492,15 @@ impl TimingDistributionMetric {
/// Gets the currently stored value as an integer.
///
/// This doesn't clear the stored value.
+ ///
+ /// # Arguments
+ ///
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
+ ///
+ /// # Returns
+ ///
+ /// The stored value or `None` if nothing stored.
pub fn test_get_value(&self, ping_name: Option<String>) -> Option<DistributionData> {
crate::block_on_dispatcher();
crate::core::with_glean(|glean| self.get_value(glean, ping_name.as_deref()))
@@ -476,8 +513,6 @@ impl TimingDistributionMetric {
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - represents the optional name of the ping to retrieve the
- /// metric for. Defaults to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/metrics/url.rs b/third_party/rust/glean-core/src/metrics/url.rs
index c9eb824a3e..48b3f9e7ae 100644
--- a/third_party/rust/glean-core/src/metrics/url.rs
+++ b/third_party/rust/glean-core/src/metrics/url.rs
@@ -131,6 +131,15 @@ impl UrlMetric {
/// Gets the currently stored value as a string.
///
/// This doesn't clear the stored value.
+ ///
+ /// # Arguments
+ ///
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
+ ///
+ /// # Returns
+ ///
+ /// The stored value or `None` if nothing stored.
pub fn test_get_value(&self, ping_name: Option<String>) -> Option<String> {
crate::block_on_dispatcher();
crate::core::with_glean(|glean| self.get_value(glean, ping_name.as_deref()))
@@ -143,8 +152,6 @@ impl UrlMetric {
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - represents the optional name of the ping to retrieve the
- /// metric for. Defaults to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/metrics/uuid.rs b/third_party/rust/glean-core/src/metrics/uuid.rs
index e78d15ad3b..77d0f82320 100644
--- a/third_party/rust/glean-core/src/metrics/uuid.rs
+++ b/third_party/rust/glean-core/src/metrics/uuid.rs
@@ -128,6 +128,15 @@ impl UuidMetric {
/// Gets the currently stored value as a string.
///
/// This doesn't clear the stored value.
+ ///
+ /// # Arguments
+ ///
+ /// * `ping_name` - the optional name of the ping to retrieve the metric
+ /// for. Defaults to the first value in `send_in_pings`.
+ ///
+ /// # Returns
+ ///
+ /// The stored value or `None` if nothing stored.
pub fn test_get_value(&self, ping_name: Option<String>) -> Option<String> {
crate::block_on_dispatcher();
crate::core::with_glean(|glean| {
@@ -143,8 +152,6 @@ impl UuidMetric {
/// # Arguments
///
/// * `error` - The type of error
- /// * `ping_name` - represents the optional name of the ping to retrieve the
- /// metric for. Defaults to the first value in `send_in_pings`.
///
/// # Returns
///
diff --git a/third_party/rust/glean-core/src/ping/mod.rs b/third_party/rust/glean-core/src/ping/mod.rs
index c22a890aa2..d1a67ae360 100644
--- a/third_party/rust/glean-core/src/ping/mod.rs
+++ b/third_party/rust/glean-core/src/ping/mod.rs
@@ -14,7 +14,7 @@ use serde_json::{json, Value as JsonValue};
use crate::common_metric_data::{CommonMetricData, Lifetime};
use crate::metrics::{CounterMetric, DatetimeMetric, Metric, MetricType, PingType, TimeUnit};
use crate::storage::{StorageManager, INTERNAL_STORAGE};
-use crate::upload::HeaderMap;
+use crate::upload::{HeaderMap, PingMetadata};
use crate::util::{get_iso_time_string, local_now_with_offset};
use crate::{Glean, Result, DELETION_REQUEST_PINGS_DIRECTORY, PENDING_PINGS_DIRECTORY};
@@ -30,6 +30,8 @@ pub struct Ping<'a> {
pub content: JsonValue,
/// The headers to upload with the payload.
pub headers: HeaderMap,
+ /// Whether the content contains {client|ping}_info sections.
+ pub includes_info_sections: bool,
}
/// Collect a ping's data, assemble it into its full payload and store it on disk.
@@ -237,9 +239,9 @@ impl PingMaker {
.snapshot_as_json(glean, ping.name(), true);
// Due to the way the experimentation identifier could link datasets that are intentionally unlinked,
- // it will not be included in pings that specifically exclude the Glean client-id and those pings that
- // should not be sent if empty.
- if (!ping.include_client_id() || !ping.send_if_empty())
+ // it will not be included in pings that specifically exclude the Glean client-id, those pings that
+ // should not be sent if empty, or pings that exclude the {client|ping}_info sections wholesale.
+ if (!ping.include_client_id() || !ping.send_if_empty() || !ping.include_info_sections())
&& glean.test_get_experimentation_id().is_some()
&& metrics_data.is_some()
{
@@ -285,13 +287,18 @@ impl PingMaker {
TimeUnit::Minute
};
- let ping_info = self.get_ping_info(glean, ping.name(), reason, precision);
- let client_info = self.get_client_info(glean, ping.include_client_id());
+ let mut json = if ping.include_info_sections() {
+ let ping_info = self.get_ping_info(glean, ping.name(), reason, precision);
+ let client_info = self.get_client_info(glean, ping.include_client_id());
+
+ json!({
+ "ping_info": ping_info,
+ "client_info": client_info
+ })
+ } else {
+ json!({})
+ };
- let mut json = json!({
- "ping_info": ping_info,
- "client_info": client_info
- });
let json_obj = json.as_object_mut()?;
if let Some(metrics_data) = metrics_data {
json_obj.insert("metrics".to_string(), metrics_data);
@@ -306,6 +313,7 @@ impl PingMaker {
doc_id,
url_path,
headers: self.get_headers(glean),
+ includes_info_sections: ping.include_info_sections(),
})
}
@@ -355,11 +363,17 @@ impl PingMaker {
file.write_all(ping.url_path.as_bytes())?;
file.write_all(b"\n")?;
file.write_all(::serde_json::to_string(&ping.content)?.as_bytes())?;
- if !ping.headers.is_empty() {
- file.write_all(b"\n{\"headers\":")?;
- file.write_all(::serde_json::to_string(&ping.headers)?.as_bytes())?;
- file.write_all(b"}")?;
- }
+ file.write_all(b"\n")?;
+ let metadata = PingMetadata {
+ // We don't actually need to clone the headers except to match PingMetadata's ownership.
+ // But since we're going to write a file to disk in a sec,
+ // and HeaderMaps tend to have only like two things in them, tops,
+ // the cost is bearable.
+ headers: Some(ping.headers.clone()),
+ body_has_info_sections: Some(ping.includes_info_sections),
+ ping_name: Some(ping.name.to_string()),
+ };
+ file.write_all(::serde_json::to_string(&metadata)?.as_bytes())?;
}
if let Err(e) = std::fs::rename(&temp_ping_path, &ping_path) {
diff --git a/third_party/rust/glean-core/src/traits/custom_distribution.rs b/third_party/rust/glean-core/src/traits/custom_distribution.rs
index c0c80c028b..43dfdb7da8 100644
--- a/third_party/rust/glean-core/src/traits/custom_distribution.rs
+++ b/third_party/rust/glean-core/src/traits/custom_distribution.rs
@@ -28,6 +28,22 @@ pub trait CustomDistribution {
/// them.
fn accumulate_samples_signed(&self, samples: Vec<i64>);
+ /// Accumulates precisely one signed sample in the metric.
+ ///
+ /// This is required so that the platform-specific code can provide us with a
+ /// 64 bit signed integer if no `u64` comparable type is available. This
+ /// will take care of filtering and reporting errors.
+ ///
+ /// # Arguments
+ ///
+ /// - `sample` - The singular sample to be recorded by the metric.
+ ///
+ /// ## Notes
+ ///
+ /// Discards any negative value of `sample` and reports an
+ /// [`ErrorType::InvalidValue`](crate::ErrorType::InvalidValue).
+ fn accumulate_single_sample_signed(&self, sample: i64);
+
/// **Exported for test purposes.**
///
/// Gets the currently stored histogram.
diff --git a/third_party/rust/glean-core/src/traits/mod.rs b/third_party/rust/glean-core/src/traits/mod.rs
index c4bcf7cdd6..4115609fdd 100644
--- a/third_party/rust/glean-core/src/traits/mod.rs
+++ b/third_party/rust/glean-core/src/traits/mod.rs
@@ -7,6 +7,10 @@
//! Individual metric types implement this trait to expose the specific metrics API.
//! It can be used by wrapping implementations to guarantee API conformance.
+/// Re-export for use in generated code.
+#[doc(hidden)]
+pub extern crate serde as __serde;
+
mod boolean;
mod counter;
mod custom_distribution;
@@ -15,6 +19,7 @@ mod event;
mod labeled;
mod memory_distribution;
mod numerator;
+mod object;
mod ping;
mod quantity;
mod rate;
@@ -37,6 +42,7 @@ pub use self::event::NoExtraKeys;
pub use self::labeled::Labeled;
pub use self::memory_distribution::MemoryDistribution;
pub use self::numerator::Numerator;
+pub use self::object::{ObjectError, ObjectSerialize};
pub use self::ping::Ping;
pub use self::quantity::Quantity;
pub use self::rate::Rate;
diff --git a/third_party/rust/glean-core/src/traits/object.rs b/third_party/rust/glean-core/src/traits/object.rs
new file mode 100644
index 0000000000..c579efeac7
--- /dev/null
+++ b/third_party/rust/glean-core/src/traits/object.rs
@@ -0,0 +1,53 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+use std::fmt::Display;
+
+use serde::{Deserialize, Serialize};
+use serde_json::Value as JsonValue;
+
+/// This type represents all possible errors that can occur when serializing or deserializing an object from/to JSON.
+#[derive(Debug)]
+pub struct ObjectError(serde_json::Error);
+
+impl Display for ObjectError {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ Display::fmt(&self.0, f)
+ }
+}
+
+impl std::error::Error for ObjectError {}
+
+/// An object that can be serialized into JSON.
+///
+/// Objects are defined by their structure in the metrics definition.
+///
+/// This is essentially a wrapper around serde's `Serialize`/`Deserialize`,
+/// but in a way we can name it for our JSON (de)serialization.
+pub trait ObjectSerialize {
+ /// Deserialize the object from its JSON representation.
+ ///
+ /// Returns an error if deserialization fails.
+ /// This should not happen for glean_parser-generated and later serialized objects.
+ fn from_str(obj: &str) -> Result<Self, ObjectError>
+ where
+ Self: Sized;
+
+ /// Serialize this object into a JSON string.
+ fn into_serialized_object(self) -> Result<JsonValue, ObjectError>;
+}
+
+impl<V> ObjectSerialize for V
+where
+ V: Serialize,
+ V: for<'de> Deserialize<'de>,
+{
+ fn from_str(obj: &str) -> Result<Self, ObjectError> {
+ serde_json::from_str(obj).map_err(ObjectError)
+ }
+
+ fn into_serialized_object(self) -> Result<JsonValue, ObjectError> {
+ serde_json::to_value(self).map_err(ObjectError)
+ }
+}
diff --git a/third_party/rust/glean-core/src/traits/timing_distribution.rs b/third_party/rust/glean-core/src/traits/timing_distribution.rs
index 03083753c6..ba618d2b4b 100644
--- a/third_party/rust/glean-core/src/traits/timing_distribution.rs
+++ b/third_party/rust/glean-core/src/traits/timing_distribution.rs
@@ -66,6 +66,31 @@ pub trait TimingDistribution {
/// are longer than `MAX_SAMPLE_TIME`.
fn accumulate_samples(&self, samples: Vec<i64>);
+ /// Accumulates precisely one signed sample in the metric.
+ ///
+ /// Precludes the need for a collection in the most common use case.
+ ///
+ /// Sign is required so that the platform-specific code can provide us with
+ /// a 64 bit signed integer if no `u64` comparable type is available. This
+ /// will take care of filtering and reporting errors for any provided negative
+ /// sample.
+ ///
+ /// Please note that this assumes that the provided sample is already in
+ /// the "unit" declared by the instance of the metric type (e.g. if the
+ /// instance this method was called on is using [`crate::TimeUnit::Second`], then
+ /// `sample` is assumed to be in that unit).
+ ///
+ /// # Arguments
+ ///
+ /// * `sample` - The singular sample to be recorded by the metric.
+ ///
+ /// ## Notes
+ ///
+ /// Discards any negative value and reports an [`ErrorType::InvalidValue`].
+ /// Reports an [`ErrorType::InvalidOverflow`] error if the sample is longer than
+ /// `MAX_SAMPLE_TIME`.
+ fn accumulate_single_sample(&self, sample: i64);
+
/// Accumulates the provided samples in the metric.
///
/// # Arguments
diff --git a/third_party/rust/glean-core/src/upload/directory.rs b/third_party/rust/glean-core/src/upload/directory.rs
index a78bbf0bdb..706550fe6c 100644
--- a/third_party/rust/glean-core/src/upload/directory.rs
+++ b/third_party/rust/glean-core/src/upload/directory.rs
@@ -9,15 +9,28 @@ use std::fs::{self, File};
use std::io::{BufRead, BufReader};
use std::path::{Path, PathBuf};
-use serde::Deserialize;
+use serde::{Deserialize, Serialize};
use uuid::Uuid;
use super::request::HeaderMap;
use crate::{DELETION_REQUEST_PINGS_DIRECTORY, PENDING_PINGS_DIRECTORY};
/// A representation of the data extracted from a ping file,
-/// this will contain the document_id, path, JSON encoded body of a ping and the persisted headers.
-pub type PingPayload = (String, String, String, Option<HeaderMap>);
+#[derive(Clone, Debug, Default)]
+pub struct PingPayload {
+ /// The ping's doc_id.
+ pub document_id: String,
+ /// The path to upload the ping to.
+ pub upload_path: String,
+ /// The ping body as JSON-encoded string.
+ pub json_body: String,
+ /// HTTP headers to include in the upload request.
+ pub headers: Option<HeaderMap>,
+ /// Whether the ping body contains {client|ping}_info
+ pub body_has_info_sections: bool,
+ /// The ping's name. (Also likely in the upload_path.)
+ pub ping_name: String,
+}
/// A struct to hold the result of scanning all pings directories.
#[derive(Clone, Debug, Default)]
@@ -62,20 +75,28 @@ fn get_file_name_as_str(path: &Path) -> Option<&str> {
}
}
+/// A ping's metadata, as (optionally) represented on disk.
+///
+/// Anything that isn't the upload path or the ping body.
+#[derive(Default, Deserialize, Serialize)]
+pub struct PingMetadata {
+ /// HTTP headers to include when uploading the ping.
+ pub headers: Option<HeaderMap>,
+ /// Whether the body has {client|ping}_info sections.
+ pub body_has_info_sections: Option<bool>,
+ /// The name of the ping.
+ pub ping_name: Option<String>,
+}
+
/// Processes a ping's metadata.
///
/// The metadata is an optional third line in the ping file,
/// currently it contains only additonal headers to be added to each ping request.
/// Therefore, we will process the contents of this line
/// and return a HeaderMap of the persisted headers.
-fn process_metadata(path: &str, metadata: &str) -> Option<HeaderMap> {
- #[derive(Deserialize)]
- struct PingMetadata {
- pub headers: HeaderMap,
- }
-
+fn process_metadata(path: &str, metadata: &str) -> Option<PingMetadata> {
if let Ok(metadata) = serde_json::from_str::<PingMetadata>(metadata) {
- return Some(metadata.headers);
+ return Some(metadata);
} else {
log::warn!("Error while parsing ping metadata: {}", path);
}
@@ -171,8 +192,23 @@ impl PingDirectoryManager {
if let (Some(Ok(path)), Some(Ok(body)), Ok(metadata)) =
(lines.next(), lines.next(), lines.next().transpose())
{
- let headers = metadata.and_then(|m| process_metadata(&path, &m));
- return Some((document_id.into(), path, body, headers));
+ let PingMetadata {
+ headers,
+ body_has_info_sections,
+ ping_name,
+ } = metadata
+ .and_then(|m| process_metadata(&path, &m))
+ .unwrap_or_default();
+ let ping_name =
+ ping_name.unwrap_or_else(|| path.split('/').nth(3).unwrap_or("").into());
+ return Some(PingPayload {
+ document_id: document_id.into(),
+ upload_path: path,
+ json_body: body,
+ headers,
+ body_has_info_sections: body_has_info_sections.unwrap_or(true),
+ ping_name,
+ });
} else {
log::warn!(
"Error processing ping file: {}. Ping file is not formatted as expected.",
@@ -303,7 +339,7 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
- let ping_type = PingType::new("test", true, true, true, vec![]);
+ let ping_type = PingType::new("test", true, true, true, true, vec![]);
glean.register_ping_type(&ping_type);
// Submit the ping to populate the pending_pings directory
@@ -320,7 +356,8 @@ mod test {
// Verify request was returned for the "test" ping
let ping = &data.pending_pings[0].1;
- let request_ping_type = ping.1.split('/').nth(3).unwrap();
+ let request_ping_type = ping.upload_path.split('/').nth(3).unwrap();
+ assert_eq!(request_ping_type, ping.ping_name);
assert_eq!(request_ping_type, "test");
}
@@ -329,7 +366,7 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
- let ping_type = PingType::new("test", true, true, true, vec![]);
+ let ping_type = PingType::new("test", true, true, true, true, vec![]);
glean.register_ping_type(&ping_type);
// Submit the ping to populate the pending_pings directory
@@ -352,7 +389,8 @@ mod test {
// Verify request was returned for the "test" ping
let ping = &data.pending_pings[0].1;
- let request_ping_type = ping.1.split('/').nth(3).unwrap();
+ let request_ping_type = ping.upload_path.split('/').nth(3).unwrap();
+ assert_eq!(request_ping_type, ping.ping_name);
assert_eq!(request_ping_type, "test");
// Verify that file was indeed deleted
@@ -364,7 +402,7 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
- let ping_type = PingType::new("test", true, true, true, vec![]);
+ let ping_type = PingType::new("test", true, true, true, true, vec![]);
glean.register_ping_type(&ping_type);
// Submit the ping to populate the pending_pings directory
@@ -387,7 +425,8 @@ mod test {
// Verify request was returned for the "test" ping
let ping = &data.pending_pings[0].1;
- let request_ping_type = ping.1.split('/').nth(3).unwrap();
+ let request_ping_type = ping.upload_path.split('/').nth(3).unwrap();
+ assert_eq!(request_ping_type, ping.ping_name);
assert_eq!(request_ping_type, "test");
// Verify that file was indeed deleted
@@ -414,7 +453,8 @@ mod test {
// Verify request was returned for the "deletion-request" ping
let ping = &data.deletion_request_pings[0].1;
- let request_ping_type = ping.1.split('/').nth(3).unwrap();
+ let request_ping_type = ping.upload_path.split('/').nth(3).unwrap();
+ assert_eq!(request_ping_type, ping.ping_name);
assert_eq!(request_ping_type, "deletion-request");
}
}
diff --git a/third_party/rust/glean-core/src/upload/mod.rs b/third_party/rust/glean-core/src/upload/mod.rs
index d764dcd29e..e51a9d9508 100644
--- a/third_party/rust/glean-core/src/upload/mod.rs
+++ b/third_party/rust/glean-core/src/upload/mod.rs
@@ -30,6 +30,7 @@ use directory::{PingDirectoryManager, PingPayloadsByDirectory};
use policy::Policy;
use request::create_date_header_value;
+pub use directory::{PingMetadata, PingPayload};
pub use request::{HeaderMap, PingRequest};
pub use result::{UploadResult, UploadTaskAction};
@@ -322,21 +323,24 @@ impl PingUploadManager {
///
/// Returns the `PingRequest` or `None` if unable to build,
/// in which case it will delete the ping file and record an error.
- fn build_ping_request(
- &self,
- glean: &Glean,
- document_id: &str,
- path: &str,
- body: &str,
- headers: Option<HeaderMap>,
- ) -> Option<PingRequest> {
+ fn build_ping_request(&self, glean: &Glean, ping: PingPayload) -> Option<PingRequest> {
+ let PingPayload {
+ document_id,
+ upload_path: path,
+ json_body: body,
+ headers,
+ body_has_info_sections,
+ ping_name,
+ } = ping;
let mut request = PingRequest::builder(
&self.language_binding_name,
self.policy.max_ping_body_size(),
)
- .document_id(document_id)
+ .document_id(&document_id)
.path(path)
- .body(body);
+ .body(body)
+ .body_has_info_sections(body_has_info_sections)
+ .ping_name(ping_name);
if let Some(headers) = headers {
request = request.headers(headers);
@@ -346,7 +350,7 @@ impl PingUploadManager {
Ok(request) => Some(request),
Err(e) => {
log::warn!("Error trying to build ping request: {}", e);
- self.directory_manager.delete_file(document_id);
+ self.directory_manager.delete_file(&document_id);
// Record the error.
// Currently the only possible error is PingBodyOverflow.
@@ -362,23 +366,21 @@ impl PingUploadManager {
}
/// Enqueue a ping for upload.
- pub fn enqueue_ping(
- &self,
- glean: &Glean,
- document_id: &str,
- path: &str,
- body: &str,
- headers: Option<HeaderMap>,
- ) {
+ pub fn enqueue_ping(&self, glean: &Glean, ping: PingPayload) {
let mut queue = self
.queue
.write()
.expect("Can't write to pending pings queue.");
+ let PingPayload {
+ ref document_id,
+ upload_path: ref path,
+ ..
+ } = ping;
// Checks if a ping with this `document_id` is already enqueued.
if queue
.iter()
- .any(|request| request.document_id == document_id)
+ .any(|request| request.document_id.as_str() == document_id)
{
log::warn!(
"Attempted to enqueue a duplicate ping {} at {}.",
@@ -404,7 +406,7 @@ impl PingUploadManager {
}
log::trace!("Enqueuing ping {} at {}", document_id, path);
- if let Some(request) = self.build_ping_request(glean, document_id, path, body, headers) {
+ if let Some(request) = self.build_ping_request(glean, ping) {
queue.push_back(request)
}
}
@@ -455,7 +457,7 @@ impl PingUploadManager {
// Thus, we reverse the order of the pending pings vector,
// so that we iterate in descending order (newest -> oldest).
cached_pings.pending_pings.reverse();
- cached_pings.pending_pings.retain(|(file_size, (document_id, _, _, _))| {
+ cached_pings.pending_pings.retain(|(file_size, PingPayload {document_id, ..})| {
pending_pings_count += 1;
pending_pings_directory_size += file_size;
@@ -493,14 +495,14 @@ impl PingUploadManager {
// Enqueue the remaining pending pings and
// enqueue all deletion-request pings.
- let deletion_request_pings = cached_pings.deletion_request_pings.drain(..);
- for (_, (document_id, path, body, headers)) in deletion_request_pings {
- self.enqueue_ping(glean, &document_id, &path, &body, headers);
- }
- let pending_pings = cached_pings.pending_pings.drain(..);
- for (_, (document_id, path, body, headers)) in pending_pings {
- self.enqueue_ping(glean, &document_id, &path, &body, headers);
- }
+ cached_pings
+ .deletion_request_pings
+ .drain(..)
+ .for_each(|(_, ping)| self.enqueue_ping(glean, ping));
+ cached_pings
+ .pending_pings
+ .drain(..)
+ .for_each(|(_, ping)| self.enqueue_ping(glean, ping));
}
}
@@ -532,10 +534,8 @@ impl PingUploadManager {
/// * `glean` - The Glean object holding the database.
/// * `document_id` - The UUID of the ping in question.
pub fn enqueue_ping_from_file(&self, glean: &Glean, document_id: &str) {
- if let Some((doc_id, path, body, headers)) =
- self.directory_manager.process_file(document_id)
- {
- self.enqueue_ping(glean, &doc_id, &path, &body, headers)
+ if let Some(ping) = self.directory_manager.process_file(document_id) {
+ self.enqueue_ping(glean, ping);
}
}
@@ -883,7 +883,17 @@ mod test {
let upload_manager = PingUploadManager::no_policy(dir.path());
// Enqueue a ping
- upload_manager.enqueue_ping(&glean, &Uuid::new_v4().to_string(), PATH, "", None);
+ upload_manager.enqueue_ping(
+ &glean,
+ PingPayload {
+ document_id: Uuid::new_v4().to_string(),
+ upload_path: PATH.into(),
+ json_body: "".into(),
+ headers: None,
+ body_has_info_sections: true,
+ ping_name: "ping-name".into(),
+ },
+ );
// Try and get the next request.
// Verify request was returned
@@ -900,7 +910,17 @@ mod test {
// Enqueue a ping multiple times
let n = 10;
for _ in 0..n {
- upload_manager.enqueue_ping(&glean, &Uuid::new_v4().to_string(), PATH, "", None);
+ upload_manager.enqueue_ping(
+ &glean,
+ PingPayload {
+ document_id: Uuid::new_v4().to_string(),
+ upload_path: PATH.into(),
+ json_body: "".into(),
+ headers: None,
+ body_has_info_sections: true,
+ ping_name: "ping-name".into(),
+ },
+ );
}
// Verify a request is returned for each submitted ping
@@ -928,7 +948,17 @@ mod test {
// Enqueue the max number of pings allowed per uploading window
for _ in 0..max_pings_per_interval {
- upload_manager.enqueue_ping(&glean, &Uuid::new_v4().to_string(), PATH, "", None);
+ upload_manager.enqueue_ping(
+ &glean,
+ PingPayload {
+ document_id: Uuid::new_v4().to_string(),
+ upload_path: PATH.into(),
+ json_body: "".into(),
+ headers: None,
+ body_has_info_sections: true,
+ ping_name: "ping-name".into(),
+ },
+ );
}
// Verify a request is returned for each submitted ping
@@ -938,7 +968,17 @@ mod test {
}
// Enqueue just one more ping
- upload_manager.enqueue_ping(&glean, &Uuid::new_v4().to_string(), PATH, "", None);
+ upload_manager.enqueue_ping(
+ &glean,
+ PingPayload {
+ document_id: Uuid::new_v4().to_string(),
+ upload_path: PATH.into(),
+ json_body: "".into(),
+ headers: None,
+ body_has_info_sections: true,
+ ping_name: "ping-name".into(),
+ },
+ );
// Verify that we are indeed told to wait because we are at capacity
match upload_manager.get_upload_task(&glean, false) {
@@ -961,7 +1001,17 @@ mod test {
// Enqueue a ping multiple times
for _ in 0..10 {
- upload_manager.enqueue_ping(&glean, &Uuid::new_v4().to_string(), PATH, "", None);
+ upload_manager.enqueue_ping(
+ &glean,
+ PingPayload {
+ document_id: Uuid::new_v4().to_string(),
+ upload_path: PATH.into(),
+ json_body: "".into(),
+ headers: None,
+ body_has_info_sections: true,
+ ping_name: "ping-name".into(),
+ },
+ );
}
// Clear the queue
@@ -979,7 +1029,14 @@ mod test {
let (mut glean, _t) = new_glean(None);
// Register a ping for testing
- let ping_type = PingType::new("test", true, /* send_if_empty */ true, true, vec![]);
+ let ping_type = PingType::new(
+ "test",
+ true,
+ /* send_if_empty */ true,
+ true,
+ true,
+ vec![],
+ );
glean.register_ping_type(&ping_type);
// Submit the ping multiple times
@@ -1011,7 +1068,14 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
- let ping_type = PingType::new("test", true, /* send_if_empty */ true, true, vec![]);
+ let ping_type = PingType::new(
+ "test",
+ true,
+ /* send_if_empty */ true,
+ true,
+ true,
+ vec![],
+ );
glean.register_ping_type(&ping_type);
// Submit the ping multiple times
@@ -1041,7 +1105,14 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
- let ping_type = PingType::new("test", true, /* send_if_empty */ true, true, vec![]);
+ let ping_type = PingType::new(
+ "test",
+ true,
+ /* send_if_empty */ true,
+ true,
+ true,
+ vec![],
+ );
glean.register_ping_type(&ping_type);
// Submit a ping
@@ -1071,7 +1142,14 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
- let ping_type = PingType::new("test", true, /* send_if_empty */ true, true, vec![]);
+ let ping_type = PingType::new(
+ "test",
+ true,
+ /* send_if_empty */ true,
+ true,
+ true,
+ vec![],
+ );
glean.register_ping_type(&ping_type);
// Submit a ping
@@ -1101,7 +1179,14 @@ mod test {
let (mut glean, _t) = new_glean(None);
// Register a ping for testing
- let ping_type = PingType::new("test", true, /* send_if_empty */ true, true, vec![]);
+ let ping_type = PingType::new(
+ "test",
+ true,
+ /* send_if_empty */ true,
+ true,
+ true,
+ vec![],
+ );
glean.register_ping_type(&ping_type);
// Submit a ping
@@ -1133,7 +1218,14 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
- let ping_type = PingType::new("test", true, /* send_if_empty */ true, true, vec![]);
+ let ping_type = PingType::new(
+ "test",
+ true,
+ /* send_if_empty */ true,
+ true,
+ true,
+ vec![],
+ );
glean.register_ping_type(&ping_type);
// Submit a ping
@@ -1174,7 +1266,17 @@ mod test {
let path2 = format!("/submit/app_id/test-ping/1/{}", doc2);
// Enqueue a ping
- upload_manager.enqueue_ping(&glean, &doc1, &path1, "", None);
+ upload_manager.enqueue_ping(
+ &glean,
+ PingPayload {
+ document_id: doc1.clone(),
+ upload_path: path1,
+ json_body: "".into(),
+ headers: None,
+ body_has_info_sections: true,
+ ping_name: "test-ping".into(),
+ },
+ );
// Try and get the first request.
let req = match upload_manager.get_upload_task(&glean, false) {
@@ -1184,7 +1286,17 @@ mod test {
assert_eq!(doc1, req.document_id);
// Schedule the next one while the first one is "in progress"
- upload_manager.enqueue_ping(&glean, &doc2, &path2, "", None);
+ upload_manager.enqueue_ping(
+ &glean,
+ PingPayload {
+ document_id: doc2.clone(),
+ upload_path: path2,
+ json_body: "".into(),
+ headers: None,
+ body_has_info_sections: true,
+ ping_name: "test-ping".into(),
+ },
+ );
// Mark as processed
upload_manager.process_ping_upload_response(
@@ -1221,7 +1333,14 @@ mod test {
glean.set_debug_view_tag("valid-tag");
// Register a ping for testing
- let ping_type = PingType::new("test", true, /* send_if_empty */ true, true, vec![]);
+ let ping_type = PingType::new(
+ "test",
+ true,
+ /* send_if_empty */ true,
+ true,
+ true,
+ vec![],
+ );
glean.register_ping_type(&ping_type);
// Submit a ping
@@ -1248,8 +1367,28 @@ mod test {
let path = format!("/submit/app_id/test-ping/1/{}", doc_id);
// Try to enqueue a ping with the same doc_id twice
- upload_manager.enqueue_ping(&glean, &doc_id, &path, "", None);
- upload_manager.enqueue_ping(&glean, &doc_id, &path, "", None);
+ upload_manager.enqueue_ping(
+ &glean,
+ PingPayload {
+ document_id: doc_id.clone(),
+ upload_path: path.clone(),
+ json_body: "".into(),
+ headers: None,
+ body_has_info_sections: true,
+ ping_name: "test-ping".into(),
+ },
+ );
+ upload_manager.enqueue_ping(
+ &glean,
+ PingPayload {
+ document_id: doc_id,
+ upload_path: path,
+ json_body: "".into(),
+ headers: None,
+ body_has_info_sections: true,
+ ping_name: "test-ping".into(),
+ },
+ );
// Get a task once
let task = upload_manager.get_upload_task(&glean, false);
@@ -1267,7 +1406,14 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
- let ping_type = PingType::new("test", true, /* send_if_empty */ true, true, vec![]);
+ let ping_type = PingType::new(
+ "test",
+ true,
+ /* send_if_empty */ true,
+ true,
+ true,
+ vec![],
+ );
glean.register_ping_type(&ping_type);
// Submit the ping multiple times
@@ -1317,7 +1463,14 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
- let ping_type = PingType::new("test", true, /* send_if_empty */ true, true, vec![]);
+ let ping_type = PingType::new(
+ "test",
+ true,
+ /* send_if_empty */ true,
+ true,
+ true,
+ vec![],
+ );
glean.register_ping_type(&ping_type);
// Submit the ping multiple times
@@ -1331,7 +1484,10 @@ mod test {
// The pending pings array is sorted by date in ascending order,
// the newest element is the last one.
let (_, newest_ping) = &pending_pings.last().unwrap();
- let (newest_ping_id, _, _, _) = &newest_ping;
+ let PingPayload {
+ document_id: newest_ping_id,
+ ..
+ } = &newest_ping;
// Create a new upload manager pointing to the same data_path as the glean instance.
let mut upload_manager = PingUploadManager::no_policy(dir.path());
@@ -1385,7 +1541,14 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
- let ping_type = PingType::new("test", true, /* send_if_empty */ true, true, vec![]);
+ let ping_type = PingType::new(
+ "test",
+ true,
+ /* send_if_empty */ true,
+ true,
+ true,
+ vec![],
+ );
glean.register_ping_type(&ping_type);
// How many pings we allow at maximum
@@ -1406,7 +1569,7 @@ mod test {
.iter()
.rev()
.take(count_quota)
- .map(|(_, ping)| ping.0.clone())
+ .map(|(_, ping)| ping.document_id.clone())
.collect::<Vec<_>>();
// Create a new upload manager pointing to the same data_path as the glean instance.
@@ -1457,7 +1620,14 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
- let ping_type = PingType::new("test", true, /* send_if_empty */ true, true, vec![]);
+ let ping_type = PingType::new(
+ "test",
+ true,
+ /* send_if_empty */ true,
+ true,
+ true,
+ vec![],
+ );
glean.register_ping_type(&ping_type);
let expected_number_of_pings = 3;
@@ -1477,7 +1647,7 @@ mod test {
.iter()
.rev()
.take(expected_number_of_pings)
- .map(|(_, ping)| ping.0.clone())
+ .map(|(_, ping)| ping.document_id.clone())
.collect::<Vec<_>>();
// Create a new upload manager pointing to the same data_path as the glean instance.
@@ -1531,7 +1701,14 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
- let ping_type = PingType::new("test", true, /* send_if_empty */ true, true, vec![]);
+ let ping_type = PingType::new(
+ "test",
+ true,
+ /* send_if_empty */ true,
+ true,
+ true,
+ vec![],
+ );
glean.register_ping_type(&ping_type);
let expected_number_of_pings = 2;
@@ -1551,7 +1728,7 @@ mod test {
.iter()
.rev()
.take(expected_number_of_pings)
- .map(|(_, ping)| ping.0.clone())
+ .map(|(_, ping)| ping.document_id.clone())
.collect::<Vec<_>>();
// Create a new upload manager pointing to the same data_path as the glean instance.
@@ -1622,8 +1799,28 @@ mod test {
upload_manager.set_rate_limiter(secs_per_interval, max_pings_per_interval);
// Enqueue two pings
- upload_manager.enqueue_ping(&glean, &Uuid::new_v4().to_string(), PATH, "", None);
- upload_manager.enqueue_ping(&glean, &Uuid::new_v4().to_string(), PATH, "", None);
+ upload_manager.enqueue_ping(
+ &glean,
+ PingPayload {
+ document_id: Uuid::new_v4().to_string(),
+ upload_path: PATH.into(),
+ json_body: "".into(),
+ headers: None,
+ body_has_info_sections: true,
+ ping_name: "ping-name".into(),
+ },
+ );
+ upload_manager.enqueue_ping(
+ &glean,
+ PingPayload {
+ document_id: Uuid::new_v4().to_string(),
+ upload_path: PATH.into(),
+ json_body: "".into(),
+ headers: None,
+ body_has_info_sections: true,
+ ping_name: "ping-name".into(),
+ },
+ );
// Get the first ping, it should be returned normally.
match upload_manager.get_upload_task(&glean, false) {
@@ -1679,12 +1876,28 @@ mod test {
let upload_manager = PingUploadManager::no_policy(dir.path());
// Enqueue a ping and start processing it
- let identifier = &Uuid::new_v4().to_string();
- upload_manager.enqueue_ping(&glean, identifier, PATH, "", None);
+ let identifier = &Uuid::new_v4();
+ let ping = PingPayload {
+ document_id: identifier.to_string(),
+ upload_path: PATH.into(),
+ json_body: "".into(),
+ headers: None,
+ body_has_info_sections: true,
+ ping_name: "ping-name".into(),
+ };
+ upload_manager.enqueue_ping(&glean, ping);
assert!(upload_manager.get_upload_task(&glean, false).is_upload());
// Attempt to re-enqueue the same ping
- upload_manager.enqueue_ping(&glean, identifier, PATH, "", None);
+ let ping = PingPayload {
+ document_id: identifier.to_string(),
+ upload_path: PATH.into(),
+ json_body: "".into(),
+ headers: None,
+ body_has_info_sections: true,
+ ping_name: "ping-name".into(),
+ };
+ upload_manager.enqueue_ping(&glean, ping);
// No new pings should have been enqueued so the upload task is Done.
assert_eq!(
@@ -1695,7 +1908,7 @@ mod test {
// Process the upload response
upload_manager.process_ping_upload_response(
&glean,
- identifier,
+ &identifier.to_string(),
UploadResult::http_status(200),
);
}
diff --git a/third_party/rust/glean-core/src/upload/request.rs b/third_party/rust/glean-core/src/upload/request.rs
index 0fd5ec5713..b4ac6eba97 100644
--- a/third_party/rust/glean-core/src/upload/request.rs
+++ b/third_party/rust/glean-core/src/upload/request.rs
@@ -62,6 +62,8 @@ pub struct Builder {
body: Option<Vec<u8>>,
headers: HeaderMap,
body_max_size: usize,
+ body_has_info_sections: Option<bool>,
+ ping_name: Option<String>,
}
impl Builder {
@@ -87,6 +89,8 @@ impl Builder {
body: None,
headers,
body_max_size,
+ body_has_info_sections: None,
+ ping_name: None,
}
}
@@ -138,6 +142,18 @@ impl Builder {
self
}
+ /// Sets whether the request body has {client|ping}_info sections.
+ pub fn body_has_info_sections(mut self, body_has_info_sections: bool) -> Self {
+ self.body_has_info_sections = Some(body_has_info_sections);
+ self
+ }
+
+ /// Sets the ping's name aka doctype.
+ pub fn ping_name<S: Into<String>>(mut self, ping_name: S) -> Self {
+ self.ping_name = Some(ping_name.into());
+ self
+ }
+
/// Sets a header for this request.
pub fn header<S: Into<String>>(mut self, key: S, value: S) -> Self {
self.headers.insert(key.into(), value.into());
@@ -174,6 +190,12 @@ impl Builder {
.expect("path must be set before attempting to build PingRequest"),
body,
headers: self.headers,
+ body_has_info_sections: self.body_has_info_sections.expect(
+ "body_has_info_sections must be set before attempting to build PingRequest",
+ ),
+ ping_name: self
+ .ping_name
+ .expect("ping_name must be set before attempting to build PingRequest"),
})
}
}
@@ -192,6 +214,10 @@ pub struct PingRequest {
pub body: Vec<u8>,
/// A map with all the headers to be sent with the request.
pub headers: HeaderMap,
+ /// Whether the body has {client|ping}_info sections.
+ pub body_has_info_sections: bool,
+ /// The ping's name. Likely also somewhere in `path`.
+ pub ping_name: String,
}
impl PingRequest {
@@ -208,12 +234,7 @@ impl PingRequest {
/// Verifies if current request is for a deletion-request ping.
pub fn is_deletion_request(&self) -> bool {
- // The path format should be `/submit/<app_id>/<ping_name>/<schema_version/<doc_id>`
- self.path
- .split('/')
- .nth(3)
- .map(|url| url == "deletion-request")
- .unwrap_or(false)
+ self.ping_name == "deletion-request"
}
/// Decompresses and pretty-format the ping payload
@@ -257,11 +278,15 @@ mod test {
.document_id("woop")
.path("/random/path/doesnt/matter")
.body("{}")
+ .body_has_info_sections(false)
+ .ping_name("whatevs")
.build()
.unwrap();
assert_eq!(request.document_id, "woop");
assert_eq!(request.path, "/random/path/doesnt/matter");
+ assert!(!request.body_has_info_sections);
+ assert_eq!(request.ping_name, "whatevs");
// Make sure all the expected headers were added.
assert!(request.headers.contains_key("X-Telemetry-Agent"));
diff --git a/third_party/rust/glean-core/tests/custom_distribution.rs b/third_party/rust/glean-core/tests/custom_distribution.rs
index 43c69fb26d..4cdfa5e99b 100644
--- a/third_party/rust/glean-core/tests/custom_distribution.rs
+++ b/third_party/rust/glean-core/tests/custom_distribution.rs
@@ -40,7 +40,7 @@ mod linear {
HistogramType::Linear,
);
- metric.accumulate_samples_sync(&glean, vec![50]);
+ metric.accumulate_samples_sync(&glean, &[50]);
let snapshot = metric
.get_value(&glean, "store1")
@@ -84,7 +84,7 @@ mod linear {
HistogramType::Linear,
);
- metric.accumulate_samples_sync(&glean, vec![50]);
+ metric.accumulate_samples_sync(&glean, &[50]);
for store_name in store_names {
let snapshot = StorageManager
@@ -126,7 +126,7 @@ mod linear {
// Accumulate the samples. We intentionally do not report
// negative values to not trigger error reporting.
- metric.accumulate_samples_sync(&glean, [1, 2, 3].to_vec());
+ metric.accumulate_samples_sync(&glean, &[1, 2, 3]);
let snapshot = metric
.get_value(&glean, "store1")
@@ -168,7 +168,7 @@ mod linear {
);
// Accumulate the samples.
- metric.accumulate_samples_sync(&glean, [-1, 1, 2, 3].to_vec());
+ metric.accumulate_samples_sync(&glean, &[-1, 1, 2, 3]);
let snapshot = metric
.get_value(&glean, "store1")
@@ -209,7 +209,7 @@ mod linear {
HistogramType::Linear,
);
- metric.accumulate_samples_sync(&glean, vec![50]);
+ metric.accumulate_samples_sync(&glean, &[50]);
let snapshot = metric.get_value(&glean, "store1");
assert!(snapshot.is_some());
@@ -242,7 +242,7 @@ mod exponential {
HistogramType::Exponential,
);
- metric.accumulate_samples_sync(&glean, vec![50]);
+ metric.accumulate_samples_sync(&glean, &[50]);
let snapshot = metric
.get_value(&glean, "store1")
@@ -286,7 +286,7 @@ mod exponential {
HistogramType::Exponential,
);
- metric.accumulate_samples_sync(&glean, vec![50]);
+ metric.accumulate_samples_sync(&glean, &[50]);
for store_name in store_names {
let snapshot = StorageManager
@@ -328,7 +328,7 @@ mod exponential {
// Accumulate the samples. We intentionally do not report
// negative values to not trigger error reporting.
- metric.accumulate_samples_sync(&glean, [1, 2, 3].to_vec());
+ metric.accumulate_samples_sync(&glean, &[1, 2, 3]);
let snapshot = metric
.get_value(&glean, "store1")
@@ -370,7 +370,7 @@ mod exponential {
);
// Accumulate the samples.
- metric.accumulate_samples_sync(&glean, [-1, 1, 2, 3].to_vec());
+ metric.accumulate_samples_sync(&glean, &[-1, 1, 2, 3]);
let snapshot = metric
.get_value(&glean, "store1")
@@ -411,7 +411,7 @@ mod exponential {
HistogramType::Exponential,
);
- metric.accumulate_samples_sync(&glean, vec![50]);
+ metric.accumulate_samples_sync(&glean, &[50]);
let snapshot = metric.get_value(&glean, "store1");
assert!(snapshot.is_some());
diff --git a/third_party/rust/glean-core/tests/event.rs b/third_party/rust/glean-core/tests/event.rs
index ed8f7d807f..c83e225ca2 100644
--- a/third_party/rust/glean-core/tests/event.rs
+++ b/third_party/rust/glean-core/tests/event.rs
@@ -166,6 +166,7 @@ fn test_sending_of_event_ping_when_it_fills_up() {
true,
false,
true,
+ true,
vec!["max_capacity".to_string()],
));
}
@@ -450,6 +451,7 @@ fn event_storage_trimming() {
true,
false,
true,
+ true,
vec![],
));
diff --git a/third_party/rust/glean-core/tests/object.rs b/third_party/rust/glean-core/tests/object.rs
new file mode 100644
index 0000000000..1e734e99d2
--- /dev/null
+++ b/third_party/rust/glean-core/tests/object.rs
@@ -0,0 +1,104 @@
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+mod common;
+use crate::common::*;
+
+use serde_json::json;
+
+use glean_core::metrics::*;
+use glean_core::storage::StorageManager;
+use glean_core::{CommonMetricData, Lifetime};
+
+#[test]
+fn object_serializer_should_correctly_serialize_objects() {
+ let (mut tempdir, _) = tempdir();
+
+ {
+ // We give tempdir to the `new_glean` function...
+ let (glean, dir) = new_glean(Some(tempdir));
+ // And then we get it back once that function returns.
+ tempdir = dir;
+
+ let metric = ObjectMetric::new(CommonMetricData {
+ name: "object_metric".into(),
+ category: "telemetry".into(),
+ send_in_pings: vec!["store1".into()],
+ disabled: false,
+ lifetime: Lifetime::User,
+ ..Default::default()
+ });
+
+ let obj = serde_json::from_str("{ \"value\": 1 }").unwrap();
+ metric.set_sync(&glean, obj);
+
+ let snapshot = StorageManager
+ .snapshot_as_json(glean.storage(), "store1", true)
+ .unwrap();
+ assert_eq!(
+ json!({"object": {"telemetry.object_metric": { "value": 1 }}}),
+ snapshot
+ );
+ }
+
+ // Make a new Glean instance here, which should force reloading of the data from disk
+ // so we can ensure it persisted, because it has User lifetime
+ {
+ let (glean, _t) = new_glean(Some(tempdir));
+ let snapshot = StorageManager
+ .snapshot_as_json(glean.storage(), "store1", true)
+ .unwrap();
+ assert_eq!(
+ json!({"object": {"telemetry.object_metric": { "value": 1 }}}),
+ snapshot
+ );
+ }
+}
+
+#[test]
+fn set_value_properly_sets_the_value_in_all_stores() {
+ let (glean, _t) = new_glean(None);
+ let store_names: Vec<String> = vec!["store1".into(), "store2".into()];
+
+ let metric = ObjectMetric::new(CommonMetricData {
+ name: "object_metric".into(),
+ category: "telemetry".into(),
+ send_in_pings: store_names.clone(),
+ disabled: false,
+ lifetime: Lifetime::Ping,
+ ..Default::default()
+ });
+
+ let obj = serde_json::from_str("{ \"value\": 1 }").unwrap();
+ metric.set_sync(&glean, obj);
+
+ for store_name in store_names {
+ let snapshot = StorageManager
+ .snapshot_as_json(glean.storage(), &store_name, true)
+ .unwrap();
+
+ assert_eq!(
+ json!({"object": {"telemetry.object_metric": { "value": 1 }}}),
+ snapshot
+ );
+ }
+}
+
+#[test]
+fn getting_data_json_encoded() {
+ let (glean, _t) = new_glean(None);
+
+ let object: ObjectMetric = ObjectMetric::new(CommonMetricData {
+ name: "transformation".into(),
+ category: "local".into(),
+ send_in_pings: vec!["store1".into()],
+ ..Default::default()
+ });
+
+ let obj_str = "{\"value\":1}";
+ let obj = serde_json::from_str(obj_str).unwrap();
+ object.set_sync(&glean, obj);
+
+ assert_eq!(obj_str, object.get_value(&glean, Some("store1")).unwrap());
+}
diff --git a/third_party/rust/glean-core/tests/ping.rs b/third_party/rust/glean-core/tests/ping.rs
index 0ee3736168..17944b4c24 100644
--- a/third_party/rust/glean-core/tests/ping.rs
+++ b/third_party/rust/glean-core/tests/ping.rs
@@ -15,7 +15,7 @@ use glean_core::Lifetime;
fn write_ping_to_disk() {
let (mut glean, _temp) = new_glean(None);
- let ping = PingType::new("metrics", true, false, true, vec![]);
+ let ping = PingType::new("metrics", true, false, true, true, vec![]);
glean.register_ping_type(&ping);
// We need to store a metric as an empty ping is not stored.
@@ -36,7 +36,7 @@ fn write_ping_to_disk() {
fn disabling_upload_clears_pending_pings() {
let (mut glean, _t) = new_glean(None);
- let ping = PingType::new("metrics", true, false, true, vec![]);
+ let ping = PingType::new("metrics", true, false, true, true, vec![]);
glean.register_ping_type(&ping);
// We need to store a metric as an empty ping is not stored.
@@ -105,9 +105,9 @@ fn deletion_request_only_when_toggled_from_on_to_off() {
fn empty_pings_with_flag_are_sent() {
let (mut glean, _t) = new_glean(None);
- let ping1 = PingType::new("custom-ping1", true, true, true, vec![]);
+ let ping1 = PingType::new("custom-ping1", true, true, true, true, vec![]);
glean.register_ping_type(&ping1);
- let ping2 = PingType::new("custom-ping2", true, false, true, vec![]);
+ let ping2 = PingType::new("custom-ping2", true, false, true, true, vec![]);
glean.register_ping_type(&ping2);
// No data is stored in either of the custom pings
@@ -139,10 +139,10 @@ fn test_pings_submitted_metric() {
None,
);
- let metrics_ping = PingType::new("metrics", true, false, true, vec![]);
+ let metrics_ping = PingType::new("metrics", true, false, true, true, vec![]);
glean.register_ping_type(&metrics_ping);
- let baseline_ping = PingType::new("baseline", true, false, true, vec![]);
+ let baseline_ping = PingType::new("baseline", true, false, true, true, vec![]);
glean.register_ping_type(&baseline_ping);
// We need to store a metric as an empty ping is not stored.
@@ -218,7 +218,7 @@ fn test_pings_submitted_metric() {
fn events_ping_with_metric_but_no_events_is_not_sent() {
let (mut glean, _t) = new_glean(None);
- let events_ping = PingType::new("events", true, true, true, vec![]);
+ let events_ping = PingType::new("events", true, true, true, true, vec![]);
glean.register_ping_type(&events_ping);
let counter = CounterMetric::new(CommonMetricData {
name: "counter".into(),
diff --git a/third_party/rust/glean-core/tests/ping_maker.rs b/third_party/rust/glean-core/tests/ping_maker.rs
index 29b6bccaca..bc3aac6311 100644
--- a/third_party/rust/glean-core/tests/ping_maker.rs
+++ b/third_party/rust/glean-core/tests/ping_maker.rs
@@ -13,7 +13,7 @@ fn set_up_basic_ping() -> (Glean, PingMaker, PingType, tempfile::TempDir) {
let (tempdir, _) = tempdir();
let (mut glean, t) = new_glean(Some(tempdir));
let ping_maker = PingMaker::new();
- let ping_type = PingType::new("store1", true, false, true, vec![]);
+ let ping_type = PingType::new("store1", true, false, true, true, vec![]);
glean.register_ping_type(&ping_type);
// Record something, so the ping will have data
@@ -89,12 +89,12 @@ fn test_metrics_must_report_experimentation_id() {
trim_data_to_registered_pings: false,
log_level: None,
rate_limit: None,
- enable_event_timestamps: false,
+ enable_event_timestamps: true,
experimentation_id: Some("test-experimentation-id".to_string()),
})
.unwrap();
let ping_maker = PingMaker::new();
- let ping_type = PingType::new("store1", true, false, true, vec![]);
+ let ping_type = PingType::new("store1", true, false, true, true, vec![]);
glean.register_ping_type(&ping_type);
// Record something, so the ping will have data
@@ -141,13 +141,13 @@ fn experimentation_id_is_removed_if_send_if_empty_is_false() {
trim_data_to_registered_pings: false,
log_level: None,
rate_limit: None,
- enable_event_timestamps: false,
+ enable_event_timestamps: true,
experimentation_id: Some("test-experimentation-id".to_string()),
})
.unwrap();
let ping_maker = PingMaker::new();
- let unknown_ping_type = PingType::new("unknown", true, false, true, vec![]);
+ let unknown_ping_type = PingType::new("unknown", true, false, true, true, vec![]);
glean.register_ping_type(&unknown_ping_type);
assert!(ping_maker
@@ -163,7 +163,7 @@ fn collect_must_report_none_when_no_data_is_stored() {
let (mut glean, ping_maker, ping_type, _t) = set_up_basic_ping();
- let unknown_ping_type = PingType::new("unknown", true, false, true, vec![]);
+ let unknown_ping_type = PingType::new("unknown", true, false, true, true, vec![]);
glean.register_ping_type(&ping_type);
assert!(ping_maker
@@ -187,7 +187,7 @@ fn seq_number_must_be_sequential() {
for i in 0..=1 {
for ping_name in ["store1", "store2"].iter() {
- let ping_type = PingType::new(*ping_name, true, false, true, vec![]);
+ let ping_type = PingType::new(*ping_name, true, false, true, true, vec![]);
let ping = ping_maker
.collect(&glean, &ping_type, None, "", "")
.unwrap();
@@ -200,7 +200,7 @@ fn seq_number_must_be_sequential() {
// Test that ping sequence numbers increase independently.
{
- let ping_type = PingType::new("store1", true, false, true, vec![]);
+ let ping_type = PingType::new("store1", true, false, true, true, vec![]);
// 3rd ping of store1
let ping = ping_maker
@@ -218,7 +218,7 @@ fn seq_number_must_be_sequential() {
}
{
- let ping_type = PingType::new("store2", true, false, true, vec![]);
+ let ping_type = PingType::new("store2", true, false, true, true, vec![]);
// 3rd ping of store2
let ping = ping_maker
@@ -229,7 +229,7 @@ fn seq_number_must_be_sequential() {
}
{
- let ping_type = PingType::new("store1", true, false, true, vec![]);
+ let ping_type = PingType::new("store1", true, false, true, true, vec![]);
// 5th ping of store1
let ping = ping_maker
@@ -244,7 +244,7 @@ fn seq_number_must_be_sequential() {
fn clear_pending_pings() {
let (mut glean, _t) = new_glean(None);
let ping_maker = PingMaker::new();
- let ping_type = PingType::new("store1", true, false, true, vec![]);
+ let ping_type = PingType::new("store1", true, false, true, true, vec![]);
glean.register_ping_type(&ping_type);
// Record something, so the ping will have data
@@ -272,7 +272,7 @@ fn no_pings_submitted_if_upload_disabled() {
// Regression test, bug 1603571
let (mut glean, _t) = new_glean(None);
- let ping_type = PingType::new("store1", true, true, true, vec![]);
+ let ping_type = PingType::new("store1", true, true, true, true, vec![]);
glean.register_ping_type(&ping_type);
assert!(ping_type.submit_sync(&glean, None));
@@ -290,7 +290,7 @@ fn no_pings_submitted_if_upload_disabled() {
fn metadata_is_correctly_added_when_necessary() {
let (mut glean, _t) = new_glean(None);
glean.set_debug_view_tag("valid-tag");
- let ping_type = PingType::new("store1", true, true, true, vec![]);
+ let ping_type = PingType::new("store1", true, true, true, true, vec![]);
glean.register_ping_type(&ping_type);
assert!(ping_type.submit_sync(&glean, None));
diff --git a/third_party/rust/glean-core/tests/timing_distribution.rs b/third_party/rust/glean-core/tests/timing_distribution.rs
index 96f7fae5af..59ce5fbadb 100644
--- a/third_party/rust/glean-core/tests/timing_distribution.rs
+++ b/third_party/rust/glean-core/tests/timing_distribution.rs
@@ -169,7 +169,7 @@ fn the_accumulate_samples_api_correctly_stores_timing_values() {
// Accumulate the samples. We intentionally do not report
// negative values to not trigger error reporting.
- metric.accumulate_samples_sync(&glean, [1, 2, 3].to_vec());
+ metric.accumulate_samples_sync(&glean, &[1, 2, 3]);
let snapshot = metric
.get_value(&glean, "store1")
@@ -211,7 +211,7 @@ fn the_accumulate_samples_api_correctly_handles_negative_values() {
);
// Accumulate the samples.
- metric.accumulate_samples_sync(&glean, [-1, 1, 2, 3].to_vec());
+ metric.accumulate_samples_sync(&glean, &[-1, 1, 2, 3]);
let snapshot = metric
.get_value(&glean, "store1")
@@ -255,7 +255,7 @@ fn the_accumulate_samples_api_correctly_handles_overflowing_values() {
const MAX_SAMPLE_TIME: u64 = 1000 * 1000 * 1000 * 60 * 10;
let overflowing_val = MAX_SAMPLE_TIME as i64 + 1;
// Accumulate the samples.
- metric.accumulate_samples_sync(&glean, [overflowing_val, 1, 2, 3].to_vec());
+ metric.accumulate_samples_sync(&glean, &[overflowing_val, 1, 2, 3]);
let snapshot = metric
.get_value(&glean, "store1")