Bug 1891745 - Update to Glean v60 and glean_parser v14 r=TravisLong,supply-chain-reviewers,mach-reviewers,android-reviewers,firefox-desktop-core-reviewers ,mconley,ahal,kaya

Differential Revision: https://phabricator.services.mozilla.com/D207869
This commit is contained in:
Jan-Erik Rediger 2024-04-24 19:14:16 +00:00
Родитель 8dd11ba3ee
Коммит d23d51f602
80 изменённых файлов: 905 добавлений и 310 удалений

8
Cargo.lock сгенерированный
Просмотреть файл

@ -2371,9 +2371,9 @@ dependencies = [
[[package]]
name = "glean"
version = "59.0.0"
version = "60.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ceede8fb9c90ba1b77fb8290d3ae7b62bfcb422ad1d6e46bae1c8af3f22f12d"
checksum = "782325c56864d3ce57e46840b8eb9318e8d85f5b80ba88fb85bb05d47e2e119b"
dependencies = [
"glean-core",
"inherent",
@ -2384,9 +2384,9 @@ dependencies = [
[[package]]
name = "glean-core"
version = "59.0.0"
version = "60.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea06a592b1395e0a16a5f4d6872f009ca7c98acc5127a8119088f1b435b5aaae"
checksum = "f1d6ca4a985a5d5a947334338381da0b8a24cf23e8da574c1d40e74067c91b81"
dependencies = [
"android_logger",
"bincode",

Просмотреть файл

@ -2937,7 +2937,7 @@ BrowserGlue.prototype = {
let cfg = lazy.NimbusFeatures.gleanInternalSdk.getVariable(
"gleanMetricConfiguration"
);
Services.fog.setMetricsFeatureConfig(JSON.stringify(cfg));
Services.fog.applyServerKnobsConfig(JSON.stringify(cfg));
});
// Register Glean to listen for experiment updates releated to the
@ -2946,7 +2946,7 @@ BrowserGlue.prototype = {
let cfg = lazy.NimbusFeatures.glean.getVariable(
"gleanMetricConfiguration"
);
Services.fog.setMetricsFeatureConfig(JSON.stringify(cfg));
Services.fog.applyServerKnobsConfig(JSON.stringify(cfg));
});
},
},

8
gfx/wr/Cargo.lock сгенерированный
Просмотреть файл

@ -996,9 +996,9 @@ dependencies = [
[[package]]
name = "glean"
version = "59.0.0"
version = "60.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ceede8fb9c90ba1b77fb8290d3ae7b62bfcb422ad1d6e46bae1c8af3f22f12d"
checksum = "782325c56864d3ce57e46840b8eb9318e8d85f5b80ba88fb85bb05d47e2e119b"
dependencies = [
"glean-core",
"inherent",
@ -1009,9 +1009,9 @@ dependencies = [
[[package]]
name = "glean-core"
version = "59.0.0"
version = "60.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea06a592b1395e0a16a5f4d6872f009ca7c98acc5127a8119088f1b435b5aaae"
checksum = "f1d6ca4a985a5d5a947334338381da0b8a24cf23e8da574c1d40e74067c91b81"
dependencies = [
"android_logger",
"bincode",

Просмотреть файл

@ -52,7 +52,7 @@ svg_fmt = "0.4"
tracy-rs = "0.1.2"
derive_more = { version = "0.99", default-features = false, features = ["add_assign"] }
etagere = "0.2.6"
glean = { version = "59.0.0", optional = true }
glean = { version = "60.0.0", optional = true }
firefox-on-glean = { version = "0.1.0", optional = true }
swgl = { path = "../swgl", optional = true }
topological-sort = "0.1"

Просмотреть файл

@ -25,7 +25,7 @@ tracy-rs = "0.1.2"
log = "0.4"
lazy_static = "1"
fxhash = "0.2.1"
glean = { version = "59.0.0", optional = true }
glean = { version = "60.0.0", optional = true }
firefox-on-glean = { version = "0.1.0", optional = true }
serde = { optional = true, version = "1.0", features = ["serde_derive"] }

Просмотреть файл

@ -116,8 +116,8 @@ object Glean {
*
* @param enabled Map of metrics' enabled state.
*/
fun setMetricsEnabledConfig(enabled: Map<String, Boolean>) {
GleanCore.setMetricsEnabledConfig(JSONObject(enabled).toString())
fun applyServerKnobsConfig(enabled: Map<String, Boolean>) {
GleanCore.applyServerKnobsConfig(JSONObject(enabled).toString())
}
/**

Просмотреть файл

@ -23,6 +23,7 @@ typealias LabeledMetricType<T> = mozilla.telemetry.glean.private.LabeledMetricTy
typealias MemoryDistributionMetricType = mozilla.telemetry.glean.private.MemoryDistributionMetricType
typealias MemoryUnit = mozilla.telemetry.glean.private.MemoryUnit
typealias NumeratorMetricType = mozilla.telemetry.glean.private.NumeratorMetricType
typealias ObjectSerialize = mozilla.telemetry.glean.private.ObjectSerialize
typealias PingType<T> = mozilla.telemetry.glean.private.PingType<T>
typealias QuantityMetricType = mozilla.telemetry.glean.private.QuantityMetricType
typealias RateMetricType = mozilla.telemetry.glean.private.RateMetricType
@ -30,8 +31,8 @@ typealias RecordedExperiment = mozilla.telemetry.glean.private.RecordedExperimen
typealias StringListMetricType = mozilla.telemetry.glean.private.StringListMetricType
typealias StringMetricType = mozilla.telemetry.glean.private.StringMetricType
typealias TextMetricType = mozilla.telemetry.glean.private.TextMetricType
typealias TimeUnit = mozilla.telemetry.glean.private.TimeUnit
typealias TimespanMetricType = mozilla.telemetry.glean.private.TimespanMetricType
typealias TimeUnit = mozilla.telemetry.glean.private.TimeUnit
typealias TimingDistributionMetricType = mozilla.telemetry.glean.private.TimingDistributionMetricType
typealias UrlMetricType = mozilla.telemetry.glean.private.UrlMetricType
typealias UuidMetricType = mozilla.telemetry.glean.private.UuidMetricType

Просмотреть файл

@ -19,7 +19,7 @@ object Versions {
const val serialization = "1.6.3"
const val python_envs_plugin = "0.0.31"
const val mozilla_glean = "59.0.0"
const val mozilla_glean = "60.0.0"
const val junit = "4.13.2"
const val robolectric = "4.12.1"

Просмотреть файл

@ -209,7 +209,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
)
// Set the metric configuration from Nimbus.
Glean.setMetricsEnabledConfig(FxNimbus.features.glean.value().metricsEnabled)
Glean.applyServerKnobsConfig(FxNimbus.features.glean.value().metricsEnabled)
Glean.initialize(
applicationContext = this,

Просмотреть файл

@ -93,7 +93,7 @@ vendored:third_party/python/wheel
vendored:third_party/python/zipp
# glean-sdk may not be installable if a wheel isn't available
# and it has to be built from source.
pypi-optional:glean-sdk==59.0.0:telemetry will not be collected
pypi-optional:glean-sdk==60.0.0:telemetry will not be collected
# Mach gracefully handles the case where `psutil` is unavailable.
# We aren't (yet) able to pin packages in automation, so we have to
# support down to the oldest locally-installed version (5.4.2).

Просмотреть файл

@ -240,15 +240,15 @@ user-login = "jrmuizel"
user-name = "Jeff Muizelaar"
[[publisher.glean]]
version = "59.0.0"
when = "2024-03-28"
version = "60.0.0"
when = "2024-04-22"
user-id = 48
user-login = "badboy"
user-name = "Jan-Erik Rediger"
[[publisher.glean-core]]
version = "59.0.0"
when = "2024-03-28"
version = "60.0.0"
when = "2024-04-22"
user-id = 48
user-login = "badboy"
user-name = "Jan-Erik Rediger"

Просмотреть файл

@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: glean-parser
Version: 13.0.1
Name: glean_parser
Version: 14.0.1
Summary: Parser tools for Mozilla's Glean telemetry
Home-page: https://github.com/mozilla/glean_parser
Author: The Glean Team
@ -77,7 +77,16 @@ $ glean_parser check < ping.json
# Changelog
## Unreleased
## 14.0.1
- BUGFIX: Fix missing `ping_arg` in util.py ([#687](https://github.com/mozilla/glean_parser/pull/687))
## 14.0.0
- BREAKING CHANGE: Expose the optional `enabled` property on pings, defaulting to `enabled: true` ([#681](https://github.com/mozilla/glean_parser/pull/681))
- BREAKING CHANGE: Support metadata field `ping_schedule` for pings ([bug 1804711](https://bugzilla.mozilla.org/show_bug.cgi?id=1804711))
- Add support for event metric type in server JavaScript outputter ([DENG-2407](https://mozilla-hub.atlassian.net/browse/DENG-2407))
- Add Swift and Kotlin codegen support for the object metric type object ([#685](https://github.com/mozilla/glean_parser/pull/685))
## 13.0.1

Просмотреть файл

@ -4,45 +4,45 @@ glean_parser/coverage.py,sha256=2IwC4XMDtDamMkBFoYilmqJzW4gyypq65YVCur8SNas,4405
glean_parser/data_review.py,sha256=BweeeTkNNS6HrIDkztawhbDByrk_-Avxpg7YeST3VAs,2152
glean_parser/go_server.py,sha256=s6lxK9IAFY55pNl3Rv4MHlV-nQwSoyhO9ppTQE9VCik,5346
glean_parser/javascript.py,sha256=w4ZhNBHBKWYk0h3t7G0Ud2tR__hRqzn9dlEXNKLdQrA,11230
glean_parser/javascript_server.py,sha256=x75JfOaveEkPQe3ozYXdtDb1Zks-PxzncDOizsJbYos,7972
glean_parser/kotlin.py,sha256=5z8_74xlqvHDsedwZhGf1_qb7swPEgIZumkJIuj3ef8,12598
glean_parser/javascript_server.py,sha256=PZSTl63TR3cY8Y99jXMOLu-8rzgQarymzjnHJm9aYK0,8389
glean_parser/kotlin.py,sha256=5nXnen4s2YOj503Z77HVTUgDHWdulB8BMl8vOie38o4,13365
glean_parser/lint.py,sha256=STqdgyOhR4Q3fHivSizgn9bOOyqrNHhzjaqyJxz6qzI,19948
glean_parser/markdown.py,sha256=GkCr1CrV6mnRQseT6FO1-JJ7Eup8X3lxUfRMBTxXpe4,9066
glean_parser/metrics.py,sha256=YAO8wPuRHTLkdT9M4zh9ZwoFI1_VS8O9oQqwZNYyDp0,14612
glean_parser/parser.py,sha256=cUOnvSXKfEBg8YTpRcWiPcMwpFpK1TTqsVO_zjUtpR4,15309
glean_parser/pings.py,sha256=AQ-fBmIx2GKQv6J2NyTFfHHZzSnApZZoC770LlstkoI,3180
glean_parser/parser.py,sha256=3-uF-Hi5LlvdFc1NxZOKX0EoEyekZGnZV094eTIJut0,16361
glean_parser/pings.py,sha256=-CIiMBVOTFULmNybV8YTFI7vmfOYOGQ5TD9hEfYPUII,3435
glean_parser/python_server.py,sha256=ERpYcbSwF19xKFagxX0mZAvlR1y6D7Ah5DSvW8LipCY,4791
glean_parser/ruby_server.py,sha256=e5lkfcLQAUMUBQDCjqNU82LkdUzT5x-G6HOnsUInbsU,5190
glean_parser/rust.py,sha256=UEHeIZlToxCBelfec5sl_l_uLZfk8f_OUXqa_ZoEvnk,7330
glean_parser/swift.py,sha256=T1BSGahd9wUd6VDeNC89SdN6M34jKXDlydMpSI0QLOs,8379
glean_parser/swift.py,sha256=paUzF6tItdktFwIQYCKsYpqXfn8zxR2coU_jMYrmwlc,8957
glean_parser/tags.py,sha256=bemKYvcbMO4JrghiNSe-A4BNNDtx_FlUPkgrPPJy84Y,1391
glean_parser/translate.py,sha256=luKQoraARZ2tjenHs0SVtCxflnYaMkzPYFfKEdKdSqQ,8403
glean_parser/translation_options.py,sha256=Lxzr6G7MP0tC_ZYlZXftS4j0SLiqO-5mGVTEc7ggXis,2037
glean_parser/util.py,sha256=v81watw5nSPGRlFNNpTb7iUv9NZObiFIbyyg2oZ6EnY,16149
glean_parser/util.py,sha256=wftmoWBUQM_o7pUwdhBp3HuDCVHIBw1PXtrfxwPLD0Q,16187
glean_parser/validate_ping.py,sha256=0TNvILH6dtzJDys3W8Kqorw6kk03me73OCUDtpoHcXU,2118
glean_parser/schemas/metrics.1-0-0.schema.yaml,sha256=cND3cvi6iBfPUVmtfIBQfGJV9AALpbvN7nu8E33_J-o,19566
glean_parser/schemas/metrics.2-0-0.schema.yaml,sha256=wx1q0L4C0-Vcwk1SPU6t8OfjDEQvgrwwEG6xfSHO1MI,26365
glean_parser/schemas/pings.1-0-0.schema.yaml,sha256=hwCnsKpEysmrmVp-QHGBArEkVY3vaU1rVsxlTwhAzws,4315
glean_parser/schemas/pings.2-0-0.schema.yaml,sha256=vDyvFT8KwAwaqyWHG4y6pFNrsc3NO7OyDDagA2eTeqM,5415
glean_parser/schemas/pings.2-0-0.schema.yaml,sha256=f8PClAlMoLTmX6ANq8Ai0CpiE74i3LOgU5SoTJpoh0M,6149
glean_parser/schemas/tags.1-0-0.schema.yaml,sha256=OGXIJlvvVW1vaqB_NVZnwKeZ-sLlfH57vjBSHbj6DNI,1231
glean_parser/templates/data_review.jinja2,sha256=jeYU29T1zLSyu9fKBBFu5BFPfIw8_hmOUXw8RXhRXK8,3287
glean_parser/templates/go_server.jinja2,sha256=Jy1e0uQqr_WZNoj-AWnygRmygX2jyj_GQMMV8mSah2k,6825
glean_parser/templates/javascript.buildinfo.jinja2,sha256=4mXiZCQIk9if4lxlA05kpSIL4a95IdwGwqle2OqqNAs,474
glean_parser/templates/javascript.jinja2,sha256=cT_bG-jC6m4afECXmcsqHwiiHjRuVtJnfv90OD2Mwxw,2669
glean_parser/templates/javascript_server.jinja2,sha256=H991yQOKJMwSgM0bLEA-Q5Z15LWsfEPh6bTYz_owSCU,9423
glean_parser/templates/javascript_server.jinja2,sha256=k-XI3QIhHQ1vbIPqSMTmCu93b1oZhm7KLmx9LfO3IJ0,9472
glean_parser/templates/kotlin.buildinfo.jinja2,sha256=X0lk2SNu5OIIj2i6mUyF9CWFQIonLgfqkgT5fA-5G6c,920
glean_parser/templates/kotlin.geckoview.jinja2,sha256=MJOgtoDXmBjE9pwk-G6T89y36RZuMbDWM_-DBN_gFJo,5099
glean_parser/templates/kotlin.jinja2,sha256=3DqUMXJRkmTvSp_5IRyvGmw5iXYWdox7coMFe3YDxcc,5247
glean_parser/templates/kotlin.jinja2,sha256=npMgDdWD9OItOZQ-dyLQZn_IKgnzee2EdJynhUa1ig8,7690
glean_parser/templates/markdown.jinja2,sha256=vAHHGGm28HRDPd3zO_wQMAUZIuxE9uQ7hl3NpXxcKV4,3425
glean_parser/templates/python_server.jinja2,sha256=gu2C1rkn760IqBCG2SWaK7o32T1ify94wDEsudLPUg8,7260
glean_parser/templates/qmldir.jinja2,sha256=m6IGsp-tgTiOfQ7VN8XW6GqX0gJqJkt3B6Pkaul6FVo,156
glean_parser/templates/ruby_server.jinja2,sha256=vm4BEenOqzomQNTLFfMOzlWHARnsWUjTBbnR-v2cadI,6247
glean_parser/templates/rust.jinja2,sha256=wlV0OZvV3Mk2ulrqFkN1vGjdsahsupEy2TQvWxQKzww,5439
glean_parser/templates/swift.jinja2,sha256=xkvVsTpfK0QK3tI32wGqzxm2hqFNaBQ6Y71rKIsCmAI,4944
glean_parser-13.0.1.dist-info/AUTHORS.md,sha256=yxgj8MioO4wUnrh0gmfb8l3DJJrf-l4HmmEDbQsbbNI,455
glean_parser-13.0.1.dist-info/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
glean_parser-13.0.1.dist-info/METADATA,sha256=UYz6ZRXyv3ODi3yl2vRQHZVdm0XGerFp8pIOGWGwOKw,31604
glean_parser-13.0.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
glean_parser-13.0.1.dist-info/entry_points.txt,sha256=mf9d3sv8BwSjjR58x9KDnpVkONCnv3fPQC2NjJl15Xg,68
glean_parser-13.0.1.dist-info/top_level.txt,sha256=q7T3duD-9tYZFyDry6Wv2LcdMsK2jGnzdDFhxWcT2Z8,13
glean_parser-13.0.1.dist-info/RECORD,,
glean_parser/templates/rust.jinja2,sha256=Ir_JqWRIUs1KLoYNDolgTRjWfWdzzBfouCP-YeTJa-c,5495
glean_parser/templates/swift.jinja2,sha256=4f993l_zZk_Tz1efiz3nbvDK1H3Uq3dWQ2T6glT9XQ4,6695
glean_parser-14.0.1.dist-info/AUTHORS.md,sha256=yxgj8MioO4wUnrh0gmfb8l3DJJrf-l4HmmEDbQsbbNI,455
glean_parser-14.0.1.dist-info/LICENSE,sha256=HyVuytGSiAUQ6ErWBHTqt1iSGHhLmlC8fO7jTCuR8dU,16725
glean_parser-14.0.1.dist-info/METADATA,sha256=Ghvw-Y7woQUJ38P8TYT5TFt8sL61GJoZPBajaB0WLeQ,32276
glean_parser-14.0.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
glean_parser-14.0.1.dist-info/entry_points.txt,sha256=mf9d3sv8BwSjjR58x9KDnpVkONCnv3fPQC2NjJl15Xg,68
glean_parser-14.0.1.dist-info/top_level.txt,sha256=q7T3duD-9tYZFyDry6Wv2LcdMsK2jGnzdDFhxWcT2Z8,13
glean_parser-14.0.1.dist-info/RECORD,,

Просмотреть файл

@ -42,9 +42,12 @@ from . import util
SUPPORTED_METRIC_TYPES = ["string", "event"]
def event_class_name(ping_name: str, event_metric_exists: bool) -> str:
def event_class_name(
ping_name: str, metrics_by_type: Dict[str, List[metrics.Metric]]
) -> str:
# For compatibility with FxA codebase we don't want to add "Logger" suffix
# when custom pings without event metrics are used.
event_metric_exists = "event" in metrics_by_type
suffix = "Logger" if event_metric_exists else ""
return util.Camelize(ping_name) + "ServerEvent" + suffix
@ -61,10 +64,13 @@ def generate_js_metric_type(metric: metrics.Metric) -> str:
return metric.type
def generate_ping_factory_method(ping: str, event_metric_exists: bool) -> str:
def generate_ping_factory_method(
ping: str, metrics_by_type: Dict[str, List[metrics.Metric]]
) -> str:
# `ServerEventLogger` better describes role of the class that this factory
# method generates, but for compatibility with existing FxA codebase
# we use `Event` suffix if no event metrics are defined.
event_metric_exists = "event" in metrics_by_type
suffix = "ServerEventLogger" if event_metric_exists else "Event"
return f"create{util.Camelize(ping)}{suffix}"
@ -136,6 +142,12 @@ def output(
metrics_list = metrics_by_type.setdefault(metric.type, [])
metrics_list.append(metric)
# Order pings_to_metrics for backwards compatibility with the existing FxA codebase.
# Put pings without `event` type metrics first.
ping_to_metrics = dict(
sorted(ping_to_metrics.items(), key=lambda item: "event" in item[1])
)
PING_METRIC_ERROR_MSG = (
" Server-side environment is simplified and this"
+ " parser doesn't generate individual metric files. Make sure to pass all"

Просмотреть файл

@ -107,6 +107,11 @@ def type_name(obj: Union[metrics.Metric, pings.Ping]) -> str:
return "{}<{}>".format(class_name(obj.type), generic)
generate_structure = getattr(obj, "_generate_structure", [])
if len(generate_structure):
generic = util.Camelize(obj.name) + "Object"
return "{}<{}>".format(class_name(obj.type), generic)
return class_name(obj.type)
@ -125,6 +130,21 @@ def extra_type_name(typ: str) -> str:
return "UNSUPPORTED"
def structure_type_name(typ: str) -> str:
"""
Returns the corresponding Kotlin type for structure items.
"""
if typ == "boolean":
return "Boolean"
elif typ == "string":
return "String"
elif typ == "number":
return "Int"
else:
return "UNSUPPORTED"
def class_name(obj_type: str) -> str:
"""
Returns the Kotlin class name for a given metric or ping type.
@ -320,6 +340,7 @@ def output_kotlin(
("type_name", type_name),
("extra_type_name", extra_type_name),
("class_name", class_name),
("structure_type_name", structure_type_name),
),
)
@ -333,6 +354,9 @@ def output_kotlin(
has_labeled_metrics = any(
getattr(metric, "labeled", False) for metric in category_val.values()
)
has_object_metrics = any(
isinstance(metric, metrics.Object) for metric in category_val.values()
)
with filepath.open("w", encoding="utf-8") as fd:
fd.write(
@ -346,6 +370,7 @@ def output_kotlin(
ping_args=util.ping_args,
namespace=namespace,
has_labeled_metrics=has_labeled_metrics,
has_object_metrics=has_object_metrics,
glean_namespace=glean_namespace,
)
)

Просмотреть файл

@ -11,7 +11,7 @@ Code for parsing metrics.yaml files.
import functools
from pathlib import Path
import textwrap
from typing import Any, Dict, Generator, Iterable, Optional, Tuple, Union
from typing import Any, cast, Dict, Generator, Iterable, Optional, Set, Tuple, Union
import jsonschema # type: ignore
from jsonschema.exceptions import ValidationError # type: ignore
@ -267,6 +267,7 @@ def _instantiate_pings(
"""
global_no_lint = content.get("no_lint", [])
assert isinstance(global_no_lint, list)
ping_schedule_reverse_map: Dict[str, Set[str]] = dict()
for ping_key, ping_val in sorted(content.items()):
if ping_key.startswith("$"):
@ -284,6 +285,22 @@ def _instantiate_pings(
if not isinstance(ping_val, dict):
raise TypeError(f"Invalid content for ping {ping_key}")
ping_val["name"] = ping_key
if "metadata" in ping_val and "ping_schedule" in ping_val["metadata"]:
if ping_key in ping_val["metadata"]["ping_schedule"]:
yield util.format_error(
filepath,
f"For ping '{ping_key}'",
"ping_schedule contains its own ping name",
)
continue
for ping_schedule in ping_val["metadata"]["ping_schedule"]:
if ping_schedule not in ping_schedule_reverse_map:
ping_schedule_reverse_map[ping_schedule] = set()
ping_schedule_reverse_map[ping_schedule].add(ping_key)
del ping_val["metadata"]["ping_schedule"]
try:
ping_obj = Ping(
defined_in=getattr(ping_val, "defined_in", None),
@ -313,6 +330,11 @@ def _instantiate_pings(
all_objects.setdefault("pings", {})[ping_key] = ping_obj
sources[ping_key] = filepath
for scheduler, scheduled in ping_schedule_reverse_map.items():
if isinstance(all_objects["pings"][scheduler], Ping):
scheduler_obj: Ping = cast(Ping, all_objects["pings"][scheduler])
scheduler_obj.schedules_pings = sorted(list(scheduled))
def _instantiate_tags(
all_objects: ObjectTree,

Просмотреть файл

@ -31,6 +31,7 @@ class Ping:
reasons: Optional[Dict[str, str]] = None,
defined_in: Optional[Dict] = None,
no_lint: Optional[List[str]] = None,
enabled: Optional[bool] = None,
_validated: bool = False,
):
# Avoid cyclical import
@ -46,6 +47,10 @@ class Ping:
self.metadata = metadata
self.precise_timestamps = self.metadata.get("precise_timestamps", True)
self.include_info_sections = self.metadata.get("include_info_sections", True)
if enabled is None:
enabled = True
self.enabled = enabled
self.schedules_pings: List[str] = []
if data_reviews is None:
data_reviews = []
self.data_reviews = data_reviews
@ -94,6 +99,7 @@ class Ping:
modified_dict = util.remove_output_params(
modified_dict, "include_info_sections"
)
modified_dict = util.remove_output_params(modified_dict, "schedules_pings")
return modified_dict
def identifier(self) -> str:

Просмотреть файл

@ -96,6 +96,16 @@ additionalProperties:
Interaction with `include_client_id`: `include_client_id` only takes
effect when `metadata.include_info_sections` is `true`.
type: boolean
ping_schedule:
title: Ping Schedule
description: |
An optional array of ping names. When one of the listed pings is
sent, then this ping will also be sent. A ping cannot list its own
name in `ping_schedule`.
type: array
items:
type: string
maxLength: 30
default: {}
@ -175,6 +185,18 @@ additionalProperties:
additionalProperties:
type: string
enabled:
title: Whether or not this ping is enabled
description: |
**Optional.**
When `true`, the ping will be sent as usual.
When `false`, the ping will not be sent, but the data will continue to
be collected but will not be cleared when the ping is submitted.
Defaults to `true` if omitted.
type: boolean
no_lint:
title: Lint checks to skip
description: |

Просмотреть файл

@ -106,12 +106,17 @@ def type_name(obj: Union[metrics.Metric, pings.Ping]) -> str:
return "{}<{}>".format(class_name(obj.type), generic)
generate_structure = getattr(obj, "_generate_structure", [])
if len(generate_structure):
generic = util.Camelize(obj.name) + "Object"
return "{}<{}>".format(class_name(obj.type), generic)
return class_name(obj.type)
def extra_type_name(typ: str) -> str:
"""
Returns the corresponding Kotlin type for event's extra key types.
Returns the corresponding Swift type for event's extra key types.
"""
if typ == "boolean":
@ -124,6 +129,21 @@ def extra_type_name(typ: str) -> str:
return "UNSUPPORTED"
def structure_type_name(typ: str) -> str:
"""
Returns the corresponding Swift type for structure items.
"""
if typ == "boolean":
return "Bool"
elif typ == "string":
return "String"
elif typ == "number":
return "Int64"
else:
return "UNSUPPORTED"
def class_name(obj_type: str) -> str:
"""
Returns the Swift class name for a given metric or ping type.
@ -215,6 +235,7 @@ def output_swift(
("class_name", class_name),
("variable_name", variable_name),
("extra_type_name", extra_type_name),
("structure_type_name", structure_type_name),
),
)

Просмотреть файл

@ -21,7 +21,7 @@ type LoggerOptions = { app: string; fmt?: 'heka' };
type Event = {
category: string;
name: string;
extra: Record<string, any>;
extra?: Record<string, any>;
timestamp?: number;
};
{% endif %}
@ -30,14 +30,14 @@ type Event = {
let _logger{% if lang == "typescript" %}: Logger{% endif %};
{% for ping, metrics_by_type in pings.items() %}
class {{ ping|event_class_name(event_metric_exists) }} {
class {{ ping|event_class_name(metrics_by_type) }} {
{% if lang == "typescript" %}
_applicationId: string;
_appDisplayVersion: string;
_channel: string;
{% endif %}
/**
* Create {{ ping|event_class_name(event_metric_exists) }} instance.
* Create {{ ping|event_class_name(metrics_by_type) }} instance.
*
* @param {string} applicationId - The application ID.
* @param {string} appDisplayVersion - The application display version.
@ -72,7 +72,7 @@ class {{ ping|event_class_name(event_metric_exists) }} {
{% endif %}
}
}
{% if event_metric_exists %}
{% if 'event' in metrics_by_type %}
#record({
{% else %}
/**
@ -99,28 +99,28 @@ class {{ ping|event_class_name(event_metric_exists) }} {
{% endfor %}
{% endif %}
{% endfor %}
{% if event_metric_exists %}
{% if 'event' in metrics_by_type %}
event,
{% endif %}
{% if lang == "typescript" %}
}: {
user_agent: string,
ip_address: string,
user_agent: string;
ip_address: string;
{% for metric_type, metrics in metrics_by_type.items() %}
{% if metric_type != 'event' %}
{% for metric in metrics %}
{{ metric|metric_argument_name }}: {{ metric|js_metric_type }},
{{ metric|metric_argument_name }}: {{ metric|js_metric_type }};
{% endfor %}
{% endif %}
{% endfor %}
{% if event_metric_exists %}
event: Event
{% if 'event' in metrics_by_type %}
event: Event;
{% endif %}
{% endif %}
}) {
const now = new Date();
const timestamp = now.toISOString();
{% if event_metric_exists %}
{% if 'event' in metrics_by_type %}
event.timestamp = now.getTime();
{% endif %}
const eventPayload = {
@ -135,7 +135,7 @@ class {{ ping|event_class_name(event_metric_exists) }} {
{% endif %}
{% endfor %}
},
{% if event_metric_exists %}
{% if 'event' in metrics_by_type %}
events: [event],
{% endif %}
ping_info: {
@ -171,7 +171,7 @@ class {{ ping|event_class_name(event_metric_exists) }} {
// this is similar to how FxA currently logs with mozlog: https://github.com/mozilla/fxa/blob/4c5c702a7fcbf6f8c6b1f175e9172cdd21471eac/packages/fxa-auth-server/lib/log.js#L289
_logger.info(GLEAN_EVENT_MOZLOG_TYPE, ping);
}
{% if event_metric_exists %}
{% if 'event' in metrics_by_type %}
{% for event in metrics_by_type["event"] %}
/**
* Record and submit a {{ event.category }}_{{ event.name }} event:
@ -209,27 +209,27 @@ class {{ ping|event_class_name(event_metric_exists) }} {
{% endfor %}
{% if lang == "typescript" %}
}: {
user_agent: string,
ip_address: string,
user_agent: string;
ip_address: string;
{% for metric_type, metrics in metrics_by_type.items() %}
{% if metric_type != 'event' %}
{% for metric in metrics %}
{{ metric|metric_argument_name }}: {{ metric|js_metric_type }},
{{ metric|metric_argument_name }}: {{ metric|js_metric_type }};
{% endfor %}
{% endif %}
{% endfor %}
{% for extra, metadata in event.extra_keys.items() %}
{{ extra }}: {{metadata.type}},
{{ extra }}: {{metadata.type}};
{% endfor %}
{% endif %}
}) {
let event = {
'category': '{{ event.category }}',
'name': '{{ event.name }}',
const event = {
category: '{{ event.category }}',
name: '{{ event.name }}',
{% if event.extra_keys %}
'extra': {
extra: {
{% for extra, metadata in event.extra_keys.items() %}
'{{ extra }}': {{ extra }},
{{ extra }}: {{ extra }},
{% endfor %}
},
{% endif %}
@ -244,14 +244,14 @@ class {{ ping|event_class_name(event_metric_exists) }} {
{% endfor %}
{% endif %}
{% endfor %}
event
event,
});
}
{% endfor %}
{% endif %}
}
{% endfor %}
{% for ping in pings %}
{% for ping, metrics_by_type in pings.items() %}
/**
* Factory function that creates an instance of Glean Server Event Logger to
@ -262,11 +262,11 @@ class {{ ping|event_class_name(event_metric_exists) }} {
* @param {Object} logger_options - The logger options.
* @returns {EventsServerEventLogger} An instance of EventsServerEventLogger.
*/
export const {{ ping|factory_method(event_metric_exists) }} = function ({
export const {{ ping|factory_method(metrics_by_type) }} = function ({
applicationId,
appDisplayVersion,
channel,
logger_options
logger_options,
{% if lang == "typescript" %}
}: {
applicationId: string;
@ -275,7 +275,7 @@ export const {{ ping|factory_method(event_metric_exists) }} = function ({
logger_options: LoggerOptions;
{% endif %}
}) {
return new {{ ping|event_class_name(event_metric_exists) }}(
return new {{ ping|event_class_name(metrics_by_type) }}(
applicationId,
appDisplayVersion,
channel,

Просмотреть файл

@ -66,6 +66,61 @@ data class {{ obj.name|Camelize }}{{ suffix }}(
}
{%- endmacro -%}
{%- macro generate_structure(name, struct) %}
{%- if struct.type == "array" -%}
@Serializable
data class {{ name }}(var items: MutableList<{{ name }}Item> = mutableListOf()) : ObjectSerialize {
fun add(elem: {{ name }}Item) = items.add(elem)
fun addAll(elements: Collection<{{ name }}Item>) = items.addAll(elements)
fun clear() = items.clear()
fun remove(element: {{ name }}Item) = items.remove(element)
fun removeAll(elements: Collection<{{ name }}Item>) = items.removeAll(elements)
fun removeAt(index: Int) = items.removeAt(index)
fun set(index: Int, element: {{ name }}Item) = items.set(index, element)
override fun intoSerializedObject(): String {
return Json.encodeToString(items)
}
}
{{ generate_structure(name ~ "Item", struct["items"]) }}
{%- elif struct.type == "object" -%}
@Serializable
data class {{ name }}(
{% for itemname, val in struct.properties.items() %}
{% if val.type == "object" %}
var {{itemname|camelize}}: {{ name ~ "Item" ~ itemname|Camelize ~ "Object" }}? = null,
{% elif val.type == "array" %}
var {{itemname|camelize}}: {{ name ~ "Item" ~ itemname|Camelize }} = {{ name ~ "Item" ~ itemname|Camelize }}(),
{% else %}
var {{itemname|camelize}}: {{val.type|structure_type_name}}? = null,
{% endif %}
{% endfor %}
): ObjectSerialize {
override fun intoSerializedObject(): String {
return Json.encodeToString(this)
}
}
{% for itemname, val in struct.properties.items() %}
{% if val.type == "array" %}
{% set nested_name = name ~ "Item" ~ itemname|Camelize %}
{{ generate_structure(nested_name, val) }}
{% elif val.type == "object" %}
{% set nested_name = name ~ "Item" ~ itemname|Camelize ~ "Object" %}
{{ generate_structure(nested_name, val) }}
{% endif %}
{% endfor %}
{% endif %}
{% endmacro %}
/* ktlint-disable no-blank-line-before-rbrace */
@file:Suppress("PackageNaming", "MaxLineLength")
package {{ namespace }}
@ -76,8 +131,9 @@ import {{ glean_namespace }}.private.HistogramType // ktlint-disable import-orde
import {{ glean_namespace }}.private.Lifetime // ktlint-disable import-ordering no-unused-imports
import {{ glean_namespace }}.private.MemoryUnit // ktlint-disable import-ordering no-unused-imports
import {{ glean_namespace }}.private.NoExtras // ktlint-disable import-ordering no-unused-imports
import {{ glean_namespace }}.private.ReasonCode // ktlint-disable import-ordering no-unused-imports
import {{ glean_namespace }}.private.NoReasonCodes // ktlint-disable import-ordering no-unused-imports
import {{ glean_namespace }}.private.ObjectSerialize // ktlint-disable import-ordering no-unused-imports
import {{ glean_namespace }}.private.ReasonCode // ktlint-disable import-ordering no-unused-imports
import {{ glean_namespace }}.private.TimeUnit // ktlint-disable import-ordering no-unused-imports
{% for obj_type in obj_types %}
import {{ glean_namespace }}.private.{{ obj_type }} // ktlint-disable import-ordering
@ -85,6 +141,11 @@ import {{ glean_namespace }}.private.{{ obj_type }} // ktlint-disable import-ord
{% if has_labeled_metrics %}
import {{ glean_namespace }}.private.LabeledMetricType // ktlint-disable import-ordering
{% endif %}
{% if has_object_metrics %}
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
{% endif %}
internal object {{ category_name|Camelize }} {
{% for obj in objs.values() %}
@ -97,6 +158,9 @@ internal object {{ category_name|Camelize }} {
{% endfor %}
{% endif %}
{% else %}
{% if obj|attr("_generate_structure") %}
{{ generate_structure(obj.name|Camelize ~ "Object", obj._generate_structure) }}
{%- endif %}
{% if obj|attr("_generate_enums") %}
{% for name, suffix in obj["_generate_enums"] %}
{% if obj|attr(name)|length %}

Просмотреть файл

@ -87,7 +87,7 @@ impl ExtraKeys for {{ obj.name|Camelize }}{{ suffix }} {
/// {{ obj.description|wordwrap() | replace('\n', '\n/// ') }}
#[rustfmt::skip]
pub static {{ obj.name|snake_case }}: ::glean::private::__export::Lazy<::glean::private::PingType> =
::glean::private::__export::Lazy::new(|| ::glean::private::PingType::new("{{ obj.name }}", {{ obj.include_client_id|rust }}, {{ obj.send_if_empty|rust }}, {{ obj.precise_timestamps|rust }}, {{ obj.include_info_sections|rust }}, {{ obj.reason_codes|rust }}));
::glean::private::__export::Lazy::new(|| ::glean::private::PingType::new("{{ obj.name }}", {{ obj.include_client_id|rust }}, {{ obj.send_if_empty|rust }}, {{ obj.precise_timestamps|rust }}, {{ obj.include_info_sections|rust }}, {{ obj.enabled|rust }}, {{ obj.schedules_pings|rust }}, {{ obj.reason_codes|rust }}));
{% endfor %}
{% else %}
pub mod {{ category.name|snake_case }} {

Просмотреть файл

@ -11,7 +11,7 @@ Jinja2 template is not. Please file bugs! #}
/* 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 http://mozilla.org/MPL/2.0/. */
{% macro obj_declaration(obj, suffix='', access='') %}
{%- macro obj_declaration(obj, suffix='', access='') %}
{{ access }}static let {{ obj.name|camelize|variable_name }}{{ suffix }} = {{ obj|type_name }}( // generated from {{ obj.identifier() }}
CommonMetricData(
{% for arg_name in common_metric_args if obj[arg_name] is defined %}
@ -24,7 +24,7 @@ Jinja2 template is not. Please file bugs! #}
)
{% endmacro %}
{% macro struct_decl(obj, name, suffix) %}
{%- macro struct_decl(obj, name, suffix) %}
struct {{ obj.name|Camelize }}{{ suffix }}: EventExtras {
{% for item, typ in obj|attr(name) %}
var {{ item|camelize|variable_name }}: {{typ|extra_type_name}}?
@ -44,6 +44,46 @@ struct {{ obj.name|Camelize }}{{ suffix }}: EventExtras {
}
{% endmacro %}
{%- macro generate_structure(name, struct) %}
{%- if struct.type == "array" -%}
typealias {{ name }} = [{{ name }}Item]
{{ generate_structure(name ~ "Item", struct["items"]) }}
{%- elif struct.type == "object" -%}
struct {{ name }}: Codable, Equatable, ObjectSerialize {
{% for itemname, val in struct.properties.items() %}
{% if val.type == "object" %}
var {{itemname|camelize|variable_name}}: {{ name ~ "Item" ~ itemname|Camelize ~ "Object" }}?
{% elif val.type == "array" %}
var {{itemname|camelize|variable_name}}: {{ name ~ "Item" ~ itemname|Camelize }}
{% else %}
var {{itemname|camelize|variable_name}}: {{val.type|structure_type_name}}?
{% endif %}
{% endfor %}
func intoSerializedObject() -> String {
let jsonEncoder = JSONEncoder()
let jsonData = try! jsonEncoder.encode(self)
let json = String(data: jsonData, encoding: String.Encoding.utf8)!
return json
}
}
{% for itemname, val in struct.properties.items() %}
{% if val.type == "array" %}
{% set nested_name = name ~ "Item" ~ itemname|Camelize %}
{{ generate_structure(nested_name, val) }}
{% elif val.type == "object" %}
{% set nested_name = name ~ "Item" ~ itemname|Camelize ~ "Object" %}
{{ generate_structure(nested_name, val) }}
{% endif %}
{% endfor %}
{%- endif -%}
{% endmacro %}
{% if not allow_reserved %}
import {{ glean_namespace }}
@ -97,6 +137,8 @@ extension {{ namespace }} {
sendIfEmpty: {{obj.send_if_empty|swift}},
preciseTimestamps: {{obj.precise_timestamps|swift}},
includeInfoSections: {{obj.include_info_sections|swift}},
enabled: {{obj.enabled|swift}},
schedulesPings: {{obj.schedules_pings|swift}},
reasonCodes: {{obj.reason_codes|swift}}
)
@ -106,6 +148,9 @@ extension {{ namespace }} {
{% else %}
enum {{ category.name|Camelize }} {
{% for obj in category.objs.values() %}
{% if obj|attr("_generate_structure") %}
{{ generate_structure(obj.name|Camelize ~ "Object", obj._generate_structure) }}
{%- endif %}
{% if obj|attr("_generate_enums") %}
{% for name, suffix in obj["_generate_enums"] %}
{% if obj|attr(name)|length %}

Просмотреть файл

@ -531,6 +531,8 @@ ping_args = [
"send_if_empty",
"precise_timestamps",
"include_info_sections",
"enabled",
"schedules_pings",
"reason_codes",
]

Просмотреть файл

@ -138,24 +138,24 @@ import mozilla_repo_urls
},
"user": "",
"valid": True,
},
),
(
"https://hg.mozilla.org/mozilla-central/raw-file/tip/taskcluster/config.yml", # noqa: E501
does_not_raise(),
{
"github": False,
},
),
(
"https://hg.mozilla.org/mozilla-central/raw-file/tip/taskcluster/ci/config.yml", # noqa: E501
does_not_raise(),
{
"github": False,
"git_cinnabar": False,
"groups": [],
"hgmo": True,
"host": "hg.mozilla.org",
"name": "mozilla-central",
"normalized": "https://hg.mozilla.org/mozilla-central/raw-file/tip/taskcluster/config.yml", # noqa: E501
"path_raw": "/raw-file/tip/taskcluster/config.yml",
"path": "tip/taskcluster/config.yml",
"pathname": "/mozilla-central",
"platform": "hgmo",
"port": "",
"hgmo": True,
"host": "hg.mozilla.org",
"name": "mozilla-central",
"normalized": "https://hg.mozilla.org/mozilla-central/raw-file/tip/taskcluster/ci/config.yml", # noqa: E501
"path_raw": "/raw-file/tip/taskcluster/ci/config.yml",
"path": "tip/taskcluster/ci/config.yml",
"pathname": "/mozilla-central",
"platform": "hgmo",
"port": "",
"protocol": "https",
"protocols": ["https"],
"repo": "mozilla-central",
@ -163,32 +163,32 @@ import mozilla_repo_urls
"repo_path": "mozilla-central",
"repo_type": "hg",
"resource": "hg.mozilla.org",
"taskcluster_role_prefix": "repo:hg.mozilla.org/mozilla-central",
"urls": {
"hg": "hg://hg.mozilla.org:https/mozilla-central",
"https": "https://hg.mozilla.org/mozilla-central/raw-file/tip/taskcluster/config.yml", # noqa: E501
"ssh": "ssh://hg.mozilla.org/mozilla-central",
},
"user": "",
"taskcluster_role_prefix": "repo:hg.mozilla.org/mozilla-central",
"urls": {
"hg": "hg://hg.mozilla.org:https/mozilla-central",
"https": "https://hg.mozilla.org/mozilla-central/raw-file/tip/taskcluster/ci/config.yml", # noqa: E501
"ssh": "ssh://hg.mozilla.org/mozilla-central",
},
"user": "",
"valid": True,
},
),
(
"https://hg.mozilla.org/mozilla-central/file/tip/taskcluster/config.yml", # noqa: E501
does_not_raise(),
{
"github": False,
},
),
(
"https://hg.mozilla.org/mozilla-central/file/tip/taskcluster/ci/config.yml", # noqa: E501
does_not_raise(),
{
"github": False,
"git_cinnabar": False,
"groups": [],
"hgmo": True,
"host": "hg.mozilla.org",
"name": "mozilla-central",
"normalized": "https://hg.mozilla.org/mozilla-central/file/tip/taskcluster/config.yml", # noqa: E501
"path_raw": "/file/tip/taskcluster/config.yml",
"path": "tip/taskcluster/config.yml",
"pathname": "/mozilla-central",
"platform": "hgmo",
"port": "",
"hgmo": True,
"host": "hg.mozilla.org",
"name": "mozilla-central",
"normalized": "https://hg.mozilla.org/mozilla-central/file/tip/taskcluster/ci/config.yml", # noqa: E501
"path_raw": "/file/tip/taskcluster/ci/config.yml",
"path": "tip/taskcluster/ci/config.yml",
"pathname": "/mozilla-central",
"platform": "hgmo",
"port": "",
"protocol": "https",
"protocols": ["https"],
"repo": "mozilla-central",
@ -196,13 +196,13 @@ import mozilla_repo_urls
"repo_path": "mozilla-central",
"repo_type": "hg",
"resource": "hg.mozilla.org",
"taskcluster_role_prefix": "repo:hg.mozilla.org/mozilla-central",
"urls": {
"hg": "hg://hg.mozilla.org:https/mozilla-central",
"https": "https://hg.mozilla.org/mozilla-central/file/tip/taskcluster/config.yml", # noqa: E501
"ssh": "ssh://hg.mozilla.org/mozilla-central",
},
"user": "",
"taskcluster_role_prefix": "repo:hg.mozilla.org/mozilla-central",
"urls": {
"hg": "hg://hg.mozilla.org:https/mozilla-central",
"https": "https://hg.mozilla.org/mozilla-central/file/tip/taskcluster/ci/config.yml", # noqa: E501
"ssh": "ssh://hg.mozilla.org/mozilla-central",
},
"user": "",
"valid": True,
},
),

8
third_party/python/poetry.lock сгенерированный поставляемый
Просмотреть файл

@ -592,14 +592,14 @@ files = [
[[package]]
name = "glean-parser"
version = "13.0.1"
version = "14.0.1"
description = "Parser tools for Mozilla's Glean telemetry"
category = "main"
optional = false
python-versions = "*"
files = [
{file = "glean_parser-13.0.1-py3-none-any.whl", hash = "sha256:8421c88f3673dd195d0cde635f4f09c9bfd0c9709ad3d28c8b201b3b7145e257"},
{file = "glean_parser-13.0.1.tar.gz", hash = "sha256:feead4cbec6930ed38a48df5bae9eb4ee486bb4026ddf2f3206b85f80279d1e7"},
{file = "glean_parser-14.0.1-py3-none-any.whl", hash = "sha256:3275ca235885c99da659fa7d9bf929b8fb020df79d26fcbec317328c369cd039"},
{file = "glean_parser-14.0.1.tar.gz", hash = "sha256:3e9e5f99ad8592300e364b70d6247b21c445774a73a2ad274677fb58a0065809"},
]
[package.dependencies]
@ -1624,4 +1624,4 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=4.6)", "pytest-black (
[metadata]
lock-version = "2.0"
python-versions = "^3.8"
content-hash = "8dc66a54aad7ab1d775e5a94fb1d24c517a0970f0dab2fa12d0002e84641d5e4"
content-hash = "8ccca3a41d674b8232b9784d558be138ff3feb306796e898f80e383f47f2e26c"

2
third_party/python/requirements.in поставляемый
Просмотреть файл

@ -22,7 +22,7 @@ fluent.migrate==0.13.0
fluent.syntax==0.19.0
# Pin `frozenlist` as it is required for `aiohttp`. Use minimum required version.
frozenlist==1.1.1
glean_parser==13.0.1
glean_parser==14.0.1
importlib-metadata==6.0.0
# required for compatibility with Flask >= 2 in tools/tryselect/selectors/chooser
jinja2==3.1.2

6
third_party/python/requirements.txt поставляемый
Просмотреть файл

@ -275,9 +275,9 @@ frozenlist==1.1.1 ; python_version >= "3.8" and python_version < "4.0" \
giturlparse==0.10.0 ; python_version >= "3.8" and python_version < "4.0" \
--hash=sha256:04ba1a3a099c3093fa8d24a422913c6a9b2c2cd22bcffc939cf72e3e98f672d7 \
--hash=sha256:2595ab291d30717cda8474b874c9fd509f1b9802ad7f6968c36a45e4b13eb337
glean-parser==13.0.1 ; python_version >= "3.8" and python_version < "4.0" \
--hash=sha256:8421c88f3673dd195d0cde635f4f09c9bfd0c9709ad3d28c8b201b3b7145e257 \
--hash=sha256:feead4cbec6930ed38a48df5bae9eb4ee486bb4026ddf2f3206b85f80279d1e7
glean-parser==14.0.1 ; python_version >= "3.8" and python_version < "4.0" \
--hash=sha256:3275ca235885c99da659fa7d9bf929b8fb020df79d26fcbec317328c369cd039 \
--hash=sha256:3e9e5f99ad8592300e364b70d6247b21c445774a73a2ad274677fb58a0065809
idna==2.10 ; python_version >= "3.8" and python_version < "4.0" \
--hash=sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6 \
--hash=sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

4
third_party/rust/glean-core/Cargo.toml поставляемый
Просмотреть файл

@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.66"
name = "glean-core"
version = "59.0.0"
version = "60.0.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 = "13.0.0"
glean-parser = "14.0.1"
[dependencies.bincode]
version = "1.2.1"

Просмотреть файл

@ -90,9 +90,10 @@ impl Clone for CommonMetricDataInternal {
impl From<CommonMetricData> for CommonMetricDataInternal {
fn from(input_data: CommonMetricData) -> Self {
let disabled = input_data.disabled;
Self {
inner: input_data.clone(),
disabled: AtomicU8::new(u8::from(input_data.disabled)),
inner: input_data,
disabled: AtomicU8::new(u8::from(disabled)),
}
}
}

29
third_party/rust/glean-core/src/core/mod.rs поставляемый
Просмотреть файл

@ -16,7 +16,7 @@ use crate::event_database::EventDatabase;
use crate::internal_metrics::{AdditionalMetrics, CoreMetrics, DatabaseMetrics};
use crate::internal_pings::InternalPings;
use crate::metrics::{
self, ExperimentMetric, Metric, MetricType, MetricsEnabledConfig, PingType, RecordedExperiment,
self, ExperimentMetric, Metric, MetricType, PingType, RecordedExperiment, RemoteSettingsConfig,
};
use crate::ping::PingMaker;
use crate::storage::{StorageManager, INTERNAL_STORAGE};
@ -123,7 +123,7 @@ where
/// enable_internal_pings: true,
/// };
/// let mut glean = Glean::new(cfg).unwrap();
/// let ping = PingType::new("sample", true, false, true, true, vec![]);
/// let ping = PingType::new("sample", true, false, true, true, true, vec![], vec![]);
/// glean.register_ping_type(&ping);
///
/// let call_counter: CounterMetric = CounterMetric::new(CommonMetricData {
@ -162,7 +162,7 @@ pub struct Glean {
pub(crate) app_build: String,
pub(crate) schedule_metrics_pings: bool,
pub(crate) remote_settings_epoch: AtomicU8,
pub(crate) remote_settings_metrics_config: Arc<Mutex<MetricsEnabledConfig>>,
pub(crate) remote_settings_config: Arc<Mutex<RemoteSettingsConfig>>,
pub(crate) with_timestamps: bool,
}
@ -222,7 +222,7 @@ impl Glean {
// Subprocess doesn't use "metrics" pings so has no need for a scheduler.
schedule_metrics_pings: false,
remote_settings_epoch: AtomicU8::new(0),
remote_settings_metrics_config: Arc::new(Mutex::new(MetricsEnabledConfig::new())),
remote_settings_config: Arc::new(Mutex::new(RemoteSettingsConfig::new())),
with_timestamps: cfg.enable_event_timestamps,
};
@ -758,19 +758,26 @@ impl Glean {
.get_value(self, None)
}
/// Set configuration to override the default metric enabled/disabled state, typically from a
/// Set configuration to override the default state, typically initiated from a
/// remote_settings experiment or rollout
///
/// # Arguments
///
/// * `json` - The stringified JSON representation of a `MetricsEnabledConfig` object
pub fn set_metrics_enabled_config(&self, cfg: MetricsEnabledConfig) {
// Set the current MetricsEnabledConfig, keeping the lock until the epoch is
/// * `cfg` - The stringified JSON representation of a `RemoteSettingsConfig` object
pub fn apply_server_knobs_config(&self, cfg: RemoteSettingsConfig) {
// Set the current RemoteSettingsConfig, keeping the lock until the epoch is
// updated to prevent against reading a "new" config but an "old" epoch
let mut metric_config = self.remote_settings_metrics_config.lock().unwrap();
let mut remote_settings_config = self.remote_settings_config.lock().unwrap();
// Merge the exising configuration with the supplied one
metric_config.metrics_enabled.extend(cfg.metrics_enabled);
// Merge the exising metrics configuration with the supplied one
remote_settings_config
.metrics_enabled
.extend(cfg.metrics_enabled);
// Merge the exising ping configuration with the supplied one
remote_settings_config
.pings_enabled
.extend(cfg.pings_enabled);
// Update remote_settings epoch
self.remote_settings_epoch.fetch_add(1, Ordering::SeqCst);

20
third_party/rust/glean-core/src/glean.udl поставляемый
Просмотреть файл

@ -47,7 +47,7 @@ namespace glean {
void glean_unregister_event_listener(string tag);
// Server Knobs API
void glean_set_metrics_enabled_config(string json);
void glean_apply_server_knobs_config(string json);
boolean glean_set_debug_view_tag(string tag);
boolean glean_set_source_tags(sequence<string> tags);
@ -292,7 +292,7 @@ enum ErrorType {
};
interface PingType {
constructor(string name, boolean include_client_id, boolean send_if_empty, boolean precise_timestamps, boolean include_info_sections, sequence<string> reason_codes);
constructor(string name, boolean include_client_id, boolean send_if_empty, boolean precise_timestamps, boolean include_info_sections, boolean enabled, sequence<string> schedules_pings, sequence<string> reason_codes);
void submit(optional string? reason = null);
};
@ -640,3 +640,19 @@ interface TextMetric {
i32 test_get_num_recorded_errors(ErrorType error);
};
// JSON data encoded into a string
[Custom]
typedef string JsonValue;
interface ObjectMetric {
constructor(CommonMetricData meta);
void set_string(string object);
JsonValue? test_get_value(optional string? ping_name = null);
i32 test_get_num_recorded_errors(ErrorType error);
void record_schema_error();
};

Просмотреть файл

@ -21,25 +21,28 @@ pub struct InternalPings {
impl InternalPings {
pub fn new(enabled: bool) -> InternalPings {
InternalPings {
baseline: PingType::new_internal(
baseline: PingType::new(
"baseline",
true,
true,
true,
true,
enabled,
vec![],
vec![
"active".to_string(),
"dirty_startup".to_string(),
"inactive".to_string(),
],
enabled,
),
metrics: PingType::new_internal(
metrics: PingType::new(
"metrics",
true,
false,
true,
true,
enabled,
vec![],
vec![
"overdue".to_string(),
"reschedule".to_string(),
@ -47,20 +50,20 @@ impl InternalPings {
"tomorrow".to_string(),
"upgrade".to_string(),
],
enabled,
),
events: PingType::new_internal(
events: PingType::new(
"events",
true,
false,
true,
true,
enabled,
vec![],
vec![
"startup".to_string(),
"inactive".to_string(),
"max_capacity".to_string(),
],
enabled,
),
deletion_request: PingType::new(
"deletion-request",
@ -68,6 +71,8 @@ impl InternalPings {
true,
true,
true,
true, // The deletion-request should not be disabled
vec![],
vec!["at_init".to_string(), "set_upload_enabled".to_string()],
),
}

30
third_party/rust/glean-core/src/lib.rs поставляемый
Просмотреть файл

@ -28,7 +28,7 @@ use log::LevelFilter;
use once_cell::sync::{Lazy, OnceCell};
use uuid::Uuid;
use metrics::MetricsEnabledConfig;
use metrics::RemoteSettingsConfig;
mod common_metric_data;
mod core;
@ -68,9 +68,9 @@ pub use crate::metrics::labeled::{
pub use crate::metrics::{
BooleanMetric, CounterMetric, CustomDistributionMetric, Datetime, DatetimeMetric,
DenominatorMetric, DistributionData, EventMetric, MemoryDistributionMetric, MemoryUnit,
NumeratorMetric, PingType, QuantityMetric, Rate, RateMetric, RecordedEvent, RecordedExperiment,
StringListMetric, StringMetric, TextMetric, TimeUnit, TimerId, TimespanMetric,
TimingDistributionMetric, UrlMetric, UuidMetric,
NumeratorMetric, ObjectMetric, PingType, QuantityMetric, Rate, RateMetric, RecordedEvent,
RecordedExperiment, StringListMetric, StringMetric, TextMetric, TimeUnit, TimerId,
TimespanMetric, TimingDistributionMetric, UrlMetric, UuidMetric,
};
pub use crate::upload::{PingRequest, PingUploadTask, UploadResult, UploadTaskAction};
@ -910,17 +910,17 @@ pub fn glean_test_get_experimentation_id() -> Option<String> {
/// Sets a remote configuration to override metrics' default enabled/disabled
/// state
///
/// See [`core::Glean::set_metrics_enabled_config`].
pub fn glean_set_metrics_enabled_config(json: String) {
/// See [`core::Glean::apply_server_knobs_config`].
pub fn glean_apply_server_knobs_config(json: String) {
// An empty config means it is not set,
// so we avoid logging an error about it.
if json.is_empty() {
return;
}
match MetricsEnabledConfig::try_from(json) {
match RemoteSettingsConfig::try_from(json) {
Ok(cfg) => launch_with_glean(|glean| {
glean.set_metrics_enabled_config(cfg);
glean.apply_server_knobs_config(cfg);
}),
Err(e) => {
log::error!("Error setting metrics feature config: {:?}", e);
@ -1229,6 +1229,20 @@ mod ffi {
obj.into_owned()
}
}
type JsonValue = serde_json::Value;
impl UniffiCustomTypeConverter for JsonValue {
type Builtin = String;
fn into_custom(val: Self::Builtin) -> uniffi::Result<Self> {
Ok(serde_json::from_str(&val)?)
}
fn from_custom(obj: Self) -> Self::Builtin {
serde_json::to_string(&obj).unwrap()
}
}
}
pub use ffi::*;

Просмотреть файл

@ -890,16 +890,17 @@ fn test_set_remote_metric_configuration() {
);
// 2. Set a configuration to disable the metrics
let mut metrics_enabled_config = json!(
let mut remote_settings_config = json!(
{
"category.string_metric": false,
"category.labeled_string_metric": false,
"metrics_enabled": {
"category.string_metric": false,
"category.labeled_string_metric": false,
}
}
)
.to_string();
glean.set_metrics_enabled_config(
MetricsEnabledConfig::try_from(metrics_enabled_config).unwrap(),
);
glean
.apply_server_knobs_config(RemoteSettingsConfig::try_from(remote_settings_config).unwrap());
// 3. Since the metrics were disabled, setting a new value will be ignored
metric.set_sync(&glean, "VALUE_AFTER_DISABLED");
@ -921,15 +922,16 @@ fn test_set_remote_metric_configuration() {
);
// 4. Set a new configuration where one metric is enabled
metrics_enabled_config = json!(
remote_settings_config = json!(
{
"category.string_metric": true,
"metrics_enabled": {
"category.string_metric": true,
}
}
)
.to_string();
glean.set_metrics_enabled_config(
MetricsEnabledConfig::try_from(metrics_enabled_config).unwrap(),
);
glean
.apply_server_knobs_config(RemoteSettingsConfig::try_from(remote_settings_config).unwrap());
// 5. Since the first metric is enabled, setting a new value should work
// on it but not the second metric
@ -954,15 +956,16 @@ fn test_set_remote_metric_configuration() {
// 6. Set a new configuration where the second metric is enabled. This
// should be merged with the existing configuration and then both
// metrics should be enabled at that point.
metrics_enabled_config = json!(
remote_settings_config = json!(
{
"category.labeled_string_metric": true,
"metrics_enabled": {
"category.labeled_string_metric": true,
}
}
)
.to_string();
glean.set_metrics_enabled_config(
MetricsEnabledConfig::try_from(metrics_enabled_config).unwrap(),
);
glean
.apply_server_knobs_config(RemoteSettingsConfig::try_from(remote_settings_config).unwrap());
// 7. Now both metrics are enabled, setting a new value should work for
// both metrics with the merged configurations
@ -992,15 +995,16 @@ fn test_remote_settings_epoch() {
assert_eq!(0u8, current_epoch, "Current epoch must start at 0");
// 2. Set a configuration which will trigger incrementing the epoch
let metrics_enabled_config = json!(
let remote_settings_config = json!(
{
"category.string_metric": false
"metrics_enabled": {
"category.string_metric": false
}
}
)
.to_string();
glean.set_metrics_enabled_config(
MetricsEnabledConfig::try_from(metrics_enabled_config).unwrap(),
);
glean
.apply_server_knobs_config(RemoteSettingsConfig::try_from(remote_settings_config).unwrap());
// 3. Ensure the epoch updated
current_epoch = glean.remote_settings_epoch.load(Ordering::Acquire);
@ -1026,15 +1030,16 @@ fn test_remote_settings_epoch_updates_in_metric() {
);
// 2. Set a configuration to disable the `category.string_metric`
let metrics_enabled_config = json!(
let remote_settings_config = json!(
{
"category.string_metric": false
"metrics_enabled": {
"category.string_metric": false
}
}
)
.to_string();
glean.set_metrics_enabled_config(
MetricsEnabledConfig::try_from(metrics_enabled_config).unwrap(),
);
glean
.apply_server_knobs_config(RemoteSettingsConfig::try_from(remote_settings_config).unwrap());
// 3. Ensure the epoch was updated
let current_epoch = glean.remote_settings_epoch.load(Ordering::Acquire);
@ -1168,7 +1173,16 @@ fn disabled_pings_are_not_submitted() {
let dir = tempfile::tempdir().unwrap();
let (mut glean, _t) = new_glean(Some(dir));
let ping = PingType::new_internal("custom-disabled", true, false, true, true, vec![], false);
let ping = PingType::new_internal(
"custom-disabled",
true,
false,
true,
true,
false,
vec![],
vec![],
);
glean.register_ping_type(&ping);
// We need to store a metric as an empty ping is not stored.
@ -1203,3 +1217,53 @@ fn internal_pings_can_be_disabled() {
let submitted = glean.internal_pings.baseline.submit_sync(&glean, None);
assert!(!submitted);
}
#[test]
fn pings_are_controllable_from_remote_settings_config() {
let _ = env_logger::builder().is_test(true).try_init();
let dir = tempfile::tempdir().unwrap();
let (mut glean, _t) = new_glean(Some(dir));
let disabled_ping = PingType::new(
"custom-disabled",
true,
true,
true,
true,
false,
vec![],
vec![],
);
glean.register_ping_type(&disabled_ping);
let enabled_ping = PingType::new(
"custom-enabled",
true,
true,
true,
true,
true,
vec![],
vec![],
);
glean.register_ping_type(&enabled_ping);
assert!(!disabled_ping.submit_sync(&glean, None));
assert!(enabled_ping.submit_sync(&glean, None));
// Now, create a configuration to switch the enabled state of the two pings
let remote_settings_config = json!(
{
"pings_enabled": {
"custom-disabled": true,
"custom-enabled": false
}
}
)
.to_string();
glean
.apply_server_knobs_config(RemoteSettingsConfig::try_from(remote_settings_config).unwrap());
assert!(disabled_ping.submit_sync(&glean, None));
assert!(!enabled_ping.submit_sync(&glean, None));
}

Просмотреть файл

@ -22,13 +22,13 @@ mod experiment;
pub(crate) mod labeled;
mod memory_distribution;
mod memory_unit;
mod metrics_enabled_config;
mod numerator;
mod object;
mod ping;
mod quantity;
mod rate;
mod recorded_experiment;
mod remote_settings_config;
mod string;
mod string_list;
mod text;
@ -72,7 +72,7 @@ pub use self::uuid::UuidMetric;
pub use crate::histogram::HistogramType;
pub use recorded_experiment::RecordedExperiment;
pub use self::metrics_enabled_config::MetricsEnabledConfig;
pub use self::remote_settings_config::RemoteSettingsConfig;
/// A snapshot of all buckets and the accumulated sum of a distribution.
//
@ -180,7 +180,7 @@ pub trait MetricType {
// Technically nothing prevents multiple calls to should_record() to run in parallel,
// meaning both are reading self.meta().disabled and later writing it. In between it can
// also read remote_settings_metrics_config, which also could be modified in between those 2 reads.
// also read remote_settings_config, which also could be modified in between those 2 reads.
// This means we could write the wrong remote_settings_epoch | current_disabled value. All in all
// at worst we would see that metric enabled/disabled wrongly once.
// But since everything is tunneled through the dispatcher, this should never ever happen.
@ -200,11 +200,7 @@ pub trait MetricType {
}
// The epoch's didn't match so we need to look up the disabled flag
// by the base_identifier from the in-memory HashMap
let metrics_enabled = &glean
.remote_settings_metrics_config
.lock()
.unwrap()
.metrics_enabled;
let remote_settings_config = &glean.remote_settings_config.lock().unwrap();
// Get the value from the remote configuration if it is there, otherwise return the default value.
let current_disabled = {
let base_id = self.meta().base_identifier();
@ -215,8 +211,13 @@ pub trait MetricType {
// NOTE: The `!` preceding the `*is_enabled` is important for inverting the logic since the
// underlying property in the metrics.yaml is `disabled` and the outward API is treating it as
// if it were `enabled` to make it easier to understand.
if let Some(is_enabled) = metrics_enabled.get(identifier) {
u8::from(!*is_enabled)
if !remote_settings_config.metrics_enabled.is_empty() {
if let Some(is_enabled) = remote_settings_config.metrics_enabled.get(identifier) {
u8::from(!*is_enabled)
} else {
u8::from(self.meta().inner.disabled)
}
} else {
u8::from(self.meta().inner.disabled)
}

Просмотреть файл

@ -48,6 +48,10 @@ impl ObjectMetric {
/// * `value` - the value to set.
#[doc(hidden)]
pub fn set_sync(&self, glean: &Glean, value: JsonValue) {
if !self.should_record(glean) {
return;
}
let value = Metric::Object(serde_json::to_string(&value).unwrap());
glean.storage().record(glean, &self.meta, &value)
}
@ -65,6 +69,31 @@ impl ObjectMetric {
crate::launch_with_glean(move |glean| metric.set_sync(glean, value))
}
/// Sets to the specified structure.
///
/// Parses the passed JSON string.
/// If it can't be parsed into a valid object it records an invalid value error.
///
/// Note: This does not check the structure. This needs to be done by the wrapper.
///
/// # Arguments
///
/// * `object` - JSON representation of the object to set.
pub fn set_string(&self, object: String) {
let metric = self.clone();
crate::launch_with_glean(move |glean| {
let object = match serde_json::from_str(&object) {
Ok(object) => object,
Err(_) => {
let msg = "Value did not match predefined schema";
record_error(glean, &metric.meta, ErrorType::InvalidValue, msg, None);
return;
}
};
metric.set_sync(glean, object)
})
}
/// Record an `InvalidValue` error for this metric.
///
/// Only to be used by the RLB.

Просмотреть файл

@ -29,13 +29,12 @@ struct InnerPing {
pub precise_timestamps: bool,
/// Whether to include the {client|ping}_info sections on assembly.
pub include_info_sections: bool,
/// Whether this ping is enabled.
pub enabled: bool,
/// Other pings that should be scheduled when this ping is sent.
pub schedules_pings: Vec<String>,
/// The "reason" codes that this ping can send
pub reason_codes: Vec<String>,
/// Whether this ping is enabled.
/// Note: Data for disabled pings is still recorded.
/// It will not be cleared out on submit.
enabled: bool,
}
impl fmt::Debug for PingType {
@ -46,6 +45,8 @@ impl fmt::Debug for PingType {
.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("enabled", &self.0.enabled)
.field("schedules_pings", &self.0.schedules_pings)
.field("reason_codes", &self.0.reason_codes)
.finish()
}
@ -64,13 +65,20 @@ impl PingType {
/// * `name` - The name of the ping.
/// * `include_client_id` - Whether to include the client ID in the assembled ping when submitting.
/// * `send_if_empty` - Whether the ping should be sent empty or not.
/// * `precise_timestamps` - Whether the ping should use precise timestamps for the start and end time.
/// * `include_info_sections` - Whether the ping should include the client/ping_info sections.
/// * `enabled` - Whether or not this ping is enabled. Note: Data that would be sent on a disabled
/// ping will still be collected but is discarded rather than being submitted.
/// * `reason_codes` - The valid reason codes for this ping.
#[allow(clippy::too_many_arguments)]
pub fn new<A: Into<String>>(
name: A,
include_client_id: bool,
send_if_empty: bool,
precise_timestamps: bool,
include_info_sections: bool,
enabled: bool,
schedules_pings: Vec<String>,
reason_codes: Vec<String>,
) -> Self {
Self::new_internal(
@ -79,19 +87,22 @@ impl PingType {
send_if_empty,
precise_timestamps,
include_info_sections,
enabled,
schedules_pings,
reason_codes,
true,
)
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn new_internal<A: Into<String>>(
name: A,
include_client_id: bool,
send_if_empty: bool,
precise_timestamps: bool,
include_info_sections: bool,
reason_codes: Vec<String>,
enabled: bool,
schedules_pings: Vec<String>,
reason_codes: Vec<String>,
) -> Self {
let this = Self(Arc::new(InnerPing {
name: name.into(),
@ -99,8 +110,9 @@ impl PingType {
send_if_empty,
precise_timestamps,
include_info_sections,
reason_codes,
enabled,
schedules_pings,
reason_codes,
}));
// Register this ping.
@ -130,6 +142,22 @@ impl PingType {
self.0.include_info_sections
}
pub(crate) fn enabled(&self, glean: &Glean) -> bool {
let remote_settings_config = &glean.remote_settings_config.lock().unwrap();
if !remote_settings_config.pings_enabled.is_empty() {
if let Some(remote_enabled) = remote_settings_config.pings_enabled.get(self.name()) {
return *remote_enabled;
}
}
self.0.enabled
}
pub(crate) fn schedules_pings(&self) -> &[String] {
&self.0.schedules_pings
}
/// Submits the ping for eventual uploading.
///
/// The ping content is assembled as soon as possible, but upload is not
@ -166,11 +194,6 @@ impl PingType {
/// Whether the ping was succesfully assembled and queued.
#[doc(hidden)]
pub fn submit_sync(&self, glean: &Glean, reason: Option<&str>) -> bool {
if !self.0.enabled {
log::info!("Ping disabled: not submitting '{}' ping.", self.0.name);
return false;
}
if !glean.is_upload_enabled() {
log::info!("Glean disabled: not submitting any pings.");
return false;
@ -208,6 +231,15 @@ impl PingType {
false
}
Some(ping) => {
if !self.enabled(glean) {
log::info!(
"The ping '{}' is disabled and will be discarded and not submitted",
ping.name
);
return false;
}
// This metric is recorded *after* the ping is collected (since
// that is the only way to know *if* it will be submitted). The
// implication of this is that the count for a metrics ping will
@ -219,7 +251,10 @@ impl PingType {
.add_sync(glean, 1);
if let Err(e) = ping_maker.store_ping(glean.get_data_path(), &ping) {
log::warn!("IO error while writing ping to file: {}. Enqueuing upload of what we have in memory.", e);
log::warn!(
"IO error while writing ping to file: {}. Enqueuing upload of what we have in memory.",
e
);
glean.additional_metrics.io_errors.add_sync(glean, 1);
// `serde_json::to_string` only fails if serialization of the content
// fails or it contains maps with non-string keys.
@ -248,6 +283,17 @@ impl PingType {
ping.name
);
if !ping.schedules_pings.is_empty() {
log::info!(
"The ping '{}' is being used to schedule other pings: {:?}",
ping.name,
ping.schedules_pings
);
for scheduled_ping_name in &ping.schedules_pings {
glean.submit_ping_by_name(scheduled_ping_name, reason);
}
}
true
}
}

Просмотреть файл

@ -16,25 +16,31 @@ use serde::{Deserialize, Serialize};
/// }
/// ```
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct MetricsEnabledConfig {
pub struct RemoteSettingsConfig {
/// This is a `HashMap` consisting of base_identifiers as keys
/// and bool values representing an override for the `disabled`
/// property of the metric, only inverted to reduce confusion.
/// If a particular metric has a value of `true` here, it means
/// the default of the metric will be overriden and set to the
/// enabled state.
#[serde(flatten)]
#[serde(default)]
pub metrics_enabled: HashMap<String, bool>,
/// This is a `HashMap` consisting of ping names as keys and
/// boolean values representing on override for the default
/// enabled state of the ping of the same name.
#[serde(default)]
pub pings_enabled: HashMap<String, bool>,
}
impl MetricsEnabledConfig {
/// Creates a new MetricsEnabledConfig
impl RemoteSettingsConfig {
/// Creates a new RemoteSettingsConfig
pub fn new() -> Self {
Default::default()
}
}
impl TryFrom<String> for MetricsEnabledConfig {
impl TryFrom<String> for RemoteSettingsConfig {
type Error = crate::ErrorKind;
fn try_from(json: String) -> Result<Self, Self::Error> {

3
third_party/rust/glean-core/src/ping/mod.rs поставляемый
Просмотреть файл

@ -32,6 +32,8 @@ pub struct Ping<'a> {
pub headers: HeaderMap,
/// Whether the content contains {client|ping}_info sections.
pub includes_info_sections: bool,
/// Other pings that should be scheduled when this ping is sent.
pub schedules_pings: Vec<String>,
}
/// Collect a ping's data, assemble it into its full payload and store it on disk.
@ -314,6 +316,7 @@ impl PingMaker {
url_path,
headers: self.get_headers(glean),
includes_info_sections: ping.include_info_sections(),
schedules_pings: ping.schedules_pings().to_vec(),
})
}

Просмотреть файл

@ -337,7 +337,7 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
let ping_type = PingType::new("test", true, true, true, true, vec![]);
let ping_type = PingType::new("test", true, true, true, true, true, vec![], vec![]);
glean.register_ping_type(&ping_type);
// Submit the ping to populate the pending_pings directory
@ -364,7 +364,7 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
let ping_type = PingType::new("test", true, true, true, true, vec![]);
let ping_type = PingType::new("test", true, true, true, true, true, vec![], vec![]);
glean.register_ping_type(&ping_type);
// Submit the ping to populate the pending_pings directory
@ -400,7 +400,7 @@ mod test {
let (mut glean, dir) = new_glean(None);
// Register a ping for testing
let ping_type = PingType::new("test", true, true, true, true, vec![]);
let ping_type = PingType::new("test", true, true, true, true, true, vec![], vec![]);
glean.register_ping_type(&ping_type);
// Submit the ping to populate the pending_pings directory

24
third_party/rust/glean-core/src/upload/mod.rs поставляемый
Просмотреть файл

@ -1031,6 +1031,8 @@ mod test {
/* send_if_empty */ true,
true,
true,
true,
vec![],
vec![],
);
glean.register_ping_type(&ping_type);
@ -1070,6 +1072,8 @@ mod test {
/* send_if_empty */ true,
true,
true,
true,
vec![],
vec![],
);
glean.register_ping_type(&ping_type);
@ -1107,6 +1111,8 @@ mod test {
/* send_if_empty */ true,
true,
true,
true,
vec![],
vec![],
);
glean.register_ping_type(&ping_type);
@ -1144,6 +1150,8 @@ mod test {
/* send_if_empty */ true,
true,
true,
true,
vec![],
vec![],
);
glean.register_ping_type(&ping_type);
@ -1181,6 +1189,8 @@ mod test {
/* send_if_empty */ true,
true,
true,
true,
vec![],
vec![],
);
glean.register_ping_type(&ping_type);
@ -1220,6 +1230,8 @@ mod test {
/* send_if_empty */ true,
true,
true,
true,
vec![],
vec![],
);
glean.register_ping_type(&ping_type);
@ -1335,6 +1347,8 @@ mod test {
/* send_if_empty */ true,
true,
true,
true,
vec![],
vec![],
);
glean.register_ping_type(&ping_type);
@ -1408,6 +1422,8 @@ mod test {
/* send_if_empty */ true,
true,
true,
true,
vec![],
vec![],
);
glean.register_ping_type(&ping_type);
@ -1465,6 +1481,8 @@ mod test {
/* send_if_empty */ true,
true,
true,
true,
vec![],
vec![],
);
glean.register_ping_type(&ping_type);
@ -1543,6 +1561,8 @@ mod test {
/* send_if_empty */ true,
true,
true,
true,
vec![],
vec![],
);
glean.register_ping_type(&ping_type);
@ -1622,6 +1642,8 @@ mod test {
/* send_if_empty */ true,
true,
true,
true,
vec![],
vec![],
);
glean.register_ping_type(&ping_type);
@ -1703,6 +1725,8 @@ mod test {
/* send_if_empty */ true,
true,
true,
true,
vec![],
vec![],
);
glean.register_ping_type(&ping_type);

4
third_party/rust/glean-core/tests/event.rs поставляемый
Просмотреть файл

@ -167,6 +167,8 @@ fn test_sending_of_event_ping_when_it_fills_up() {
false,
true,
true,
true,
vec![],
vec!["max_capacity".to_string()],
));
}
@ -452,6 +454,8 @@ fn event_storage_trimming() {
false,
true,
true,
true,
vec![],
vec![],
));

46
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, true, vec![]);
let ping = PingType::new("metrics", true, false, true, true, true, vec![], 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, true, vec![]);
let ping = PingType::new("metrics", true, false, true, true, true, vec![], vec![]);
glean.register_ping_type(&ping);
// We need to store a metric as an empty ping is not stored.
@ -105,9 +105,18 @@ 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, true, vec![]);
let ping1 = PingType::new("custom-ping1", true, true, true, true, true, vec![], vec![]);
glean.register_ping_type(&ping1);
let ping2 = PingType::new("custom-ping2", true, false, true, true, vec![]);
let ping2 = PingType::new(
"custom-ping2",
true,
false,
true,
true,
true,
vec![],
vec![],
);
glean.register_ping_type(&ping2);
// No data is stored in either of the custom pings
@ -139,10 +148,10 @@ fn test_pings_submitted_metric() {
None,
);
let metrics_ping = PingType::new("metrics", true, false, true, true, vec![]);
let metrics_ping = PingType::new("metrics", true, false, true, true, true, vec![], vec![]);
glean.register_ping_type(&metrics_ping);
let baseline_ping = PingType::new("baseline", true, false, true, true, vec![]);
let baseline_ping = PingType::new("baseline", true, false, true, true, true, vec![], vec![]);
glean.register_ping_type(&baseline_ping);
// We need to store a metric as an empty ping is not stored.
@ -218,7 +227,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, true, vec![]);
let events_ping = PingType::new("events", true, true, true, true, true, vec![], vec![]);
glean.register_ping_type(&events_ping);
let counter = CounterMetric::new(CommonMetricData {
name: "counter".into(),
@ -247,3 +256,26 @@ fn events_ping_with_metric_but_no_events_is_not_sent() {
assert!(events_ping.submit_sync(&glean, None));
assert_eq!(1, get_queued_pings(glean.get_data_path()).unwrap().len());
}
#[test]
fn test_scheduled_pings_are_sent() {
let (mut glean, _t) = new_glean(None);
let piggyback_ping = PingType::new("piggyback", true, true, true, true, true, vec![], vec![]);
glean.register_ping_type(&piggyback_ping);
let trigger_ping = PingType::new(
"trigger",
true,
true,
true,
true,
true,
vec!["piggyback".into()],
vec![],
);
glean.register_ping_type(&trigger_ping);
assert!(trigger_ping.submit_sync(&glean, None));
assert_eq!(2, get_queued_pings(glean.get_data_path()).unwrap().len());
}

Просмотреть файл

@ -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, true, vec![]);
let ping_type = PingType::new("store1", true, false, true, true, true, vec![], vec![]);
glean.register_ping_type(&ping_type);
// Record something, so the ping will have data
@ -95,7 +95,7 @@ fn test_metrics_must_report_experimentation_id() {
})
.unwrap();
let ping_maker = PingMaker::new();
let ping_type = PingType::new("store1", true, false, true, true, vec![]);
let ping_type = PingType::new("store1", true, false, true, true, true, vec![], vec![]);
glean.register_ping_type(&ping_type);
// Record something, so the ping will have data
@ -149,7 +149,7 @@ fn experimentation_id_is_removed_if_send_if_empty_is_false() {
.unwrap();
let ping_maker = PingMaker::new();
let unknown_ping_type = PingType::new("unknown", true, false, true, true, vec![]);
let unknown_ping_type = PingType::new("unknown", true, false, true, true, true, vec![], vec![]);
glean.register_ping_type(&unknown_ping_type);
assert!(ping_maker
@ -165,7 +165,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, true, vec![]);
let unknown_ping_type = PingType::new("unknown", true, false, true, true, true, vec![], vec![]);
glean.register_ping_type(&ping_type);
assert!(ping_maker
@ -189,7 +189,8 @@ 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, true, vec![]);
let ping_type =
PingType::new(*ping_name, true, false, true, true, true, vec![], vec![]);
let ping = ping_maker
.collect(&glean, &ping_type, None, "", "")
.unwrap();
@ -202,7 +203,7 @@ fn seq_number_must_be_sequential() {
// Test that ping sequence numbers increase independently.
{
let ping_type = PingType::new("store1", true, false, true, true, vec![]);
let ping_type = PingType::new("store1", true, false, true, true, true, vec![], vec![]);
// 3rd ping of store1
let ping = ping_maker
@ -220,7 +221,7 @@ fn seq_number_must_be_sequential() {
}
{
let ping_type = PingType::new("store2", true, false, true, true, vec![]);
let ping_type = PingType::new("store2", true, false, true, true, true, vec![], vec![]);
// 3rd ping of store2
let ping = ping_maker
@ -231,7 +232,7 @@ fn seq_number_must_be_sequential() {
}
{
let ping_type = PingType::new("store1", true, false, true, true, vec![]);
let ping_type = PingType::new("store1", true, false, true, true, true, vec![], vec![]);
// 5th ping of store1
let ping = ping_maker
@ -246,7 +247,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, true, vec![]);
let ping_type = PingType::new("store1", true, false, true, true, true, vec![], vec![]);
glean.register_ping_type(&ping_type);
// Record something, so the ping will have data
@ -274,7 +275,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, true, vec![]);
let ping_type = PingType::new("store1", true, true, true, true, true, vec![], vec![]);
glean.register_ping_type(&ping_type);
assert!(ping_type.submit_sync(&glean, None));
@ -292,7 +293,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, true, vec![]);
let ping_type = PingType::new("store1", true, true, true, true, true, vec![], vec![]);
glean.register_ping_type(&ping_type);
assert!(ping_type.submit_sync(&glean, None));

2
third_party/rust/glean/.cargo-checksum.json поставляемый
Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"af0535de86b60e3e08cadcdb9e61ce4a699c168608d7e9e2ebb92d949e7f31ef","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"5627cc81e6187ab6c2b4dff061af16d559edcab64ba786bac39daa69c703c595","src/common_test.rs":"de47b53dcca37985c0a2b8c02daecbf32309aa54f5a4dd9290719c2c1fd0fa55","src/configuration.rs":"27075b12236021c54d0c99427bcbd417933ca02545275604d3c13f32ca25af13","src/core_metrics.rs":"fef8fb4e5fa57c179836c6eb2cf59278fe3b8b036dbe57b0ff02971b4acd822f","src/lib.rs":"d4010f265de330081467673df05bbd45efbdfeef28823f7dc11a903b11fb8976","src/net/http_uploader.rs":"01ad5bd91384411a12c74434cd1c5cd585078cb34faba4615c70bdb669a9bccb","src/net/mod.rs":"f47b96bb878f1a6c771cedbaeaeefb270bc87fb1d1bbbed1b282dddca16216ed","src/private/event.rs":"d7c70c02648584c19c73af89e5180d3c6153c911f2c6830f7d1599b18d6150eb","src/private/mod.rs":"3565eb569d2b96f938f130abe0fc3ee3f55e7e03fd6501e309d3ef6af72ef6ee","src/private/object.rs":"3f70363a196aea46cc163af025a53e48c117c6208babc4bce772bb4c337cced8","src/private/ping.rs":"a6262a3453c77cbf30766c19b535a1bf66a37b2a316e8f87baee03025255c33e","src/system.rs":"6eae5b41c15eba9cad6dbd116abe3519ee3e1fe034e79bdd692b029829a8c384","src/test.rs":"6388b9e8bf96e0fb56ad71b7a5b5630d209ae62f1a65c62e878cbc1757ddd585","tests/common/mod.rs":"08fb9483d9b6ed9fe873b4395245166ae8a15263be750c7a8e298c41d9604745","tests/init_fails.rs":"906bbf0faa613976623e0cf782bd86545b49d76afaab182af7634690b747ebf7","tests/never_init.rs":"19bad996e22f7d6958cc1a650528530aa7d1aeb4a8ab42229a90bbc0315c8ed1","tests/no_time_to_init.rs":"06c81148c27d383cb708c0c80a2e806024c9955337d7adfba8c53aaeade9be67","tests/overflowing_preinit.rs":"7ad4b2274dd9240b53430859a4eb1d2597cf508a5a678333f3d3abbadd2ed4a7","tests/persist_ping_lifetime.rs":"81415dc1d74743f02269f0d0dfa524003147056853f080276972e64a0b761d3c","tests/persist_ping_lifetime_nopanic.rs":"18379d3ffbf4a2c8c684c04ff7a0660b86dfbbb447db2d24dfed6073cb7ddf8f","tests/schema.rs":"9615eded31a2582c8f04c729d551c0c81a57029ba62a19184221c2e1cd39baf0","tests/simple.rs":"1b8b227249ae9d3cc281db07ed779bc75252c7849b1c48b4ac3d765228d65b20","tests/test-shutdown-blocking.sh":"9b16a01c190c7062474dd92182298a3d9a27928c8fa990340fdd798e6cdb7ab2","tests/test-thread-crashing.sh":"ff1bc8e5d7e4ba3a10d0d38bef222db8bfba469e7d30e45b1053d177a4084f09","tests/upload_timing.rs":"3024b7999a0c23f2c3d7e59725b5455522e4e9fdf63e3265b93fea4cec18725f"},"package":"0ceede8fb9c90ba1b77fb8290d3ae7b62bfcb422ad1d6e46bae1c8af3f22f12d"}
{"files":{"Cargo.toml":"e13e9991a07e8b9b60f2be6642b3c3b046d1a93665eb5862190412cac1f2fea4","LICENSE":"1f256ecad192880510e84ad60474eab7589218784b9a50bc7ceee34c2b91f1d5","README.md":"5627cc81e6187ab6c2b4dff061af16d559edcab64ba786bac39daa69c703c595","src/common_test.rs":"de47b53dcca37985c0a2b8c02daecbf32309aa54f5a4dd9290719c2c1fd0fa55","src/configuration.rs":"27075b12236021c54d0c99427bcbd417933ca02545275604d3c13f32ca25af13","src/core_metrics.rs":"fef8fb4e5fa57c179836c6eb2cf59278fe3b8b036dbe57b0ff02971b4acd822f","src/lib.rs":"3a43c992275f06c4189ffc9ca0775fe840b5598c2f6a39504aea3ae5df43fa23","src/net/http_uploader.rs":"01ad5bd91384411a12c74434cd1c5cd585078cb34faba4615c70bdb669a9bccb","src/net/mod.rs":"f47b96bb878f1a6c771cedbaeaeefb270bc87fb1d1bbbed1b282dddca16216ed","src/private/event.rs":"d7c70c02648584c19c73af89e5180d3c6153c911f2c6830f7d1599b18d6150eb","src/private/mod.rs":"3565eb569d2b96f938f130abe0fc3ee3f55e7e03fd6501e309d3ef6af72ef6ee","src/private/object.rs":"3f70363a196aea46cc163af025a53e48c117c6208babc4bce772bb4c337cced8","src/private/ping.rs":"31d33d7f661a7a17ccb69351328700b4d7b80024d1e128f406c3534f9d163475","src/system.rs":"6eae5b41c15eba9cad6dbd116abe3519ee3e1fe034e79bdd692b029829a8c384","src/test.rs":"39dd7468dcdaf17593b8b07970ced25c07cbd76853aaef2532fdcad0281a21d3","tests/common/mod.rs":"08fb9483d9b6ed9fe873b4395245166ae8a15263be750c7a8e298c41d9604745","tests/init_fails.rs":"46d7064bba9386c3065635434e17ac9212c6c2236b3cd12bd985fc3229e659a3","tests/never_init.rs":"7a6e8a011fbd945f2544f204367eeceff3f6039c99d98799477e3b2352ae6227","tests/no_time_to_init.rs":"4a5bdddc2f8226d2ad17038229e8767a6dd195977af49527fbb84a9f6b0154bb","tests/overflowing_preinit.rs":"7ad4b2274dd9240b53430859a4eb1d2597cf508a5a678333f3d3abbadd2ed4a7","tests/persist_ping_lifetime.rs":"81415dc1d74743f02269f0d0dfa524003147056853f080276972e64a0b761d3c","tests/persist_ping_lifetime_nopanic.rs":"18379d3ffbf4a2c8c684c04ff7a0660b86dfbbb447db2d24dfed6073cb7ddf8f","tests/schema.rs":"dde65bce8a715ca3bd9c54b2466d831dd5e0d559e0773fe7657827f22a66bb44","tests/simple.rs":"1835b5df6f76ff894b45805bd54eaab23ca2d9d2b0694ec64af3aa6132baf30e","tests/test-shutdown-blocking.sh":"a44d8d4bbe2ee3ede9e48121150ae7a5386025160c5cef2181ca142232c5fb27","tests/test-thread-crashing.sh":"8d5ed070754e09fbe55183bb2792ae6e234a95770e39397caf05e4ec4d6015db","tests/upload_timing.rs":"6a97aa355d808123af0914ffecf1da0ecb2cc441c95c63c600b14f97ce0d45a0"},"package":"782325c56864d3ce57e46840b8eb9318e8d85f5b80ba88fb85bb05d47e2e119b"}

4
third_party/rust/glean/Cargo.toml поставляемый
Просмотреть файл

@ -13,7 +13,7 @@
edition = "2021"
rust-version = "1.66"
name = "glean"
version = "59.0.0"
version = "60.0.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"
[dependencies.glean-core]
version = "59.0.0"
version = "60.0.0"
[dependencies.inherent]
version = "1"

8
third_party/rust/glean/src/lib.rs поставляемый
Просмотреть файл

@ -23,7 +23,7 @@
//! let cfg = ConfigurationBuilder::new(true, "/tmp/data", "org.mozilla.glean_core.example").build();
//! glean::initialize(cfg, ClientInfoMetrics::unknown());
//!
//! let prototype_ping = PingType::new("prototype", true, true, true, true, vec!());
//! let prototype_ping = PingType::new("prototype", true, true, true, true, true, vec!(), vec!());
//!
//! prototype_ping.submit(None);
//! ```
@ -187,9 +187,9 @@ pub fn test_get_experimentation_id() -> Option<String> {
/// Set the remote configuration values for the metrics' disabled property
///
/// See [`glean_core::Glean::set_metrics_enabled_config`].
pub fn glean_set_metrics_enabled_config(json: String) {
glean_core::glean_set_metrics_enabled_config(json)
/// See [`glean_core::Glean::glean_apply_server_knobs_config`].
pub fn glean_apply_server_knobs_config(json: String) {
glean_core::glean_apply_server_knobs_config(json)
}
/// Performs the collection/cleanup operations required by becoming active.

11
third_party/rust/glean/src/private/ping.rs поставляемый
Просмотреть файл

@ -27,13 +27,22 @@ impl PingType {
/// * `name` - The name of the ping.
/// * `include_client_id` - Whether to include the client ID in the assembled ping when.
/// * `send_if_empty` - Whether the ping should be sent empty or not.
/// * `precise_timestamps` - Whether the ping should use precise timestamps for the start and end time.
/// * `include_info_sections` - Whether the ping should include the client/ping_info sections.
/// * `enabled` - Whether or not this ping is enabled. Note: Data that would be sent on a disabled
/// ping will still be collected and is discarded instead of being submitted.
/// * `schedules_pings` - A list of pings which are triggered for submission when this ping is
/// submitted.
/// * `reason_codes` - The valid reason codes for this ping.
#[allow(clippy::too_many_arguments)]
pub fn new<A: Into<String>>(
name: A,
include_client_id: bool,
send_if_empty: bool,
precise_timestamps: bool,
include_info_sections: bool,
enabled: bool,
schedules_pings: Vec<String>,
reason_codes: Vec<String>,
) -> Self {
let inner = glean_core::metrics::PingType::new(
@ -42,6 +51,8 @@ impl PingType {
send_if_empty,
precise_timestamps,
include_info_sections,
enabled,
schedules_pings,
reason_codes,
);

29
third_party/rust/glean/src/test.rs поставляемый
Просмотреть файл

@ -49,7 +49,8 @@ fn send_a_ping() {
// Define a new ping and submit it.
const PING_NAME: &str = "test-ping";
let custom_ping = private::PingType::new(PING_NAME, true, true, true, true, vec![]);
let custom_ping =
private::PingType::new(PING_NAME, true, true, true, true, true, vec![], vec![]);
custom_ping.submit(None);
// Wait for the ping to arrive.
@ -90,7 +91,8 @@ fn send_a_ping_without_info_sections() {
// Define a new ping and submit it.
const PING_NAME: &str = "noinfo-ping";
let custom_ping = private::PingType::new(PING_NAME, true, true, true, false, vec![]);
let custom_ping =
private::PingType::new(PING_NAME, true, true, true, false, true, vec![], vec![]);
custom_ping.submit(None);
// Wait for the ping to arrive.
@ -594,7 +596,7 @@ fn ping_collection_must_happen_after_concurrently_scheduled_metrics_recordings()
);
let ping_name = "custom_ping_1";
let ping = private::PingType::new(ping_name, true, false, true, true, vec![]);
let ping = private::PingType::new(ping_name, true, false, true, true, true, vec![], vec![]);
let metric = private::StringMetric::new(CommonMetricData {
name: "string_metric".into(),
category: "telemetry".into(),
@ -1097,7 +1099,16 @@ fn flipping_upload_enabled_respects_order_of_events() {
.build();
// We create a ping and a metric before we initialize Glean
let sample_ping = PingType::new("sample-ping-1", true, false, true, true, vec![]);
let sample_ping = PingType::new(
"sample-ping-1",
true,
false,
true,
true,
true,
vec![],
vec![],
);
let metric = private::StringMetric::new(CommonMetricData {
name: "string_metric".into(),
category: "telemetry".into(),
@ -1141,7 +1152,7 @@ fn registering_pings_before_init_must_work() {
}
// Create a custom ping and attempt its registration.
let sample_ping = PingType::new("pre-register", true, true, true, true, vec![]);
let sample_ping = PingType::new("pre-register", true, true, true, true, true, vec![], vec![]);
// Create a custom configuration to use a fake uploader.
let dir = tempfile::tempdir().unwrap();
@ -1193,7 +1204,7 @@ fn test_a_ping_before_submission() {
let _t = new_glean(Some(cfg), true);
// Create a custom ping and register it.
let sample_ping = PingType::new("custom1", true, true, true, true, vec![]);
let sample_ping = PingType::new("custom1", true, true, true, true, true, vec![], vec![]);
let metric = CounterMetric::new(CommonMetricData {
name: "counter_metric".into(),
@ -1310,7 +1321,8 @@ fn signaling_done() {
// Define a new ping and submit it.
const PING_NAME: &str = "test-ping";
let custom_ping = private::PingType::new(PING_NAME, true, true, true, true, vec![]);
let custom_ping =
private::PingType::new(PING_NAME, true, true, true, true, true, vec![], vec![]);
custom_ping.submit(None);
custom_ping.submit(None);
@ -1381,7 +1393,8 @@ fn configure_ping_throttling() {
// Define a new ping.
const PING_NAME: &str = "test-ping";
let custom_ping = private::PingType::new(PING_NAME, true, true, true, true, vec![]);
let custom_ping =
private::PingType::new(PING_NAME, true, true, true, true, true, vec![], vec![]);
// Submit and receive it `pings_per_interval` times.
for _ in 0..pings_per_interval {

5
third_party/rust/glean/tests/init_fails.rs поставляемый
Просмотреть файл

@ -42,8 +42,9 @@ mod pings {
use once_cell::sync::Lazy;
#[allow(non_upper_case_globals)]
pub static validation: Lazy<PingType> =
Lazy::new(|| glean::private::PingType::new("validation", true, true, true, true, vec![]));
pub static validation: Lazy<PingType> = Lazy::new(|| {
glean::private::PingType::new("validation", true, true, true, true, true, vec![], vec![])
});
}
/// Test scenario: Glean initialization fails.

5
third_party/rust/glean/tests/never_init.rs поставляемый
Просмотреть файл

@ -38,8 +38,9 @@ mod pings {
use once_cell::sync::Lazy;
#[allow(non_upper_case_globals)]
pub static validation: Lazy<PingType> =
Lazy::new(|| glean::private::PingType::new("validation", true, true, true, true, vec![]));
pub static validation: Lazy<PingType> = Lazy::new(|| {
glean::private::PingType::new("validation", true, true, true, true, true, vec![], vec![])
});
}
/// Test scenario: Glean is never initialized.

Просмотреть файл

@ -40,8 +40,9 @@ mod pings {
use once_cell::sync::Lazy;
#[allow(non_upper_case_globals)]
pub static validation: Lazy<PingType> =
Lazy::new(|| glean::private::PingType::new("validation", true, true, true, true, vec![]));
pub static validation: Lazy<PingType> = Lazy::new(|| {
glean::private::PingType::new("validation", true, true, true, true, true, vec![], vec![])
});
}
/// Test scenario: Glean initialization fails.

3
third_party/rust/glean/tests/schema.rs поставляемый
Просмотреть файл

@ -170,7 +170,8 @@ fn validate_against_schema() {
text_metric.set("loooooong text".repeat(100));
// Define a new ping and submit it.
let custom_ping = glean::private::PingType::new(PING_NAME, true, true, true, true, vec![]);
let custom_ping =
glean::private::PingType::new(PING_NAME, true, true, true, true, true, vec![], vec![]);
custom_ping.submit(None);
// Wait for the ping to arrive.

5
third_party/rust/glean/tests/simple.rs поставляемый
Просмотреть файл

@ -40,8 +40,9 @@ mod pings {
use once_cell::sync::Lazy;
#[allow(non_upper_case_globals)]
pub static validation: Lazy<PingType> =
Lazy::new(|| glean::private::PingType::new("validation", true, true, true, true, vec![]));
pub static validation: Lazy<PingType> = Lazy::new(|| {
glean::private::PingType::new("validation", true, true, true, true, true, vec![], vec![])
});
}
/// Test scenario: A clean run

Просмотреть файл

@ -17,7 +17,7 @@ trap cleanup INT ABRT TERM EXIT
tmp="${TMPDIR:-/tmp}"
datapath=$(mktemp -d "${tmp}/glean_long_running.XXXX")
cargo run --example long-running -- "$datapath"
cargo run -p glean --example long-running -- "$datapath"
count=$(ls -1q "$datapath/pending_pings" | wc -l)
if [[ "$count" -eq 0 ]]; then

Просмотреть файл

@ -19,7 +19,7 @@ datapath=$(mktemp -d "${tmp}/glean_long_running.XXXX")
RUSTFLAGS="-C panic=abort" \
RUST_LOG=debug \
cargo run --example crashing-threads -- "$datapath"
cargo run -p glean --example crashing-threads -- "$datapath"
ret=$?
count=$(ls -1q "$datapath/pending_pings" | wc -l)

Просмотреть файл

@ -96,8 +96,9 @@ mod pings {
use once_cell::sync::Lazy;
#[allow(non_upper_case_globals)]
pub static validation: Lazy<PingType> =
Lazy::new(|| glean::private::PingType::new("validation", true, true, true, true, vec![]));
pub static validation: Lazy<PingType> = Lazy::new(|| {
glean::private::PingType::new("validation", true, true, true, true, true, vec![], vec![])
});
}
// Define a fake uploader that sleeps.

Просмотреть файл

@ -6,7 +6,7 @@ edition = "2018"
license = "MPL-2.0"
[dependencies]
glean = "59.0.0"
glean = "60.0.0"
log = "0.4"
nserror = { path = "../../../xpcom/rust/nserror" }
nsstring = { path = "../../../xpcom/rust/nsstring" }

Просмотреть файл

@ -9,7 +9,7 @@ license = "MPL-2.0"
[dependencies]
bincode = "1.0"
chrono = "0.4.10"
glean = "59.0.0"
glean = "60.0.0"
inherent = "1.0.0"
log = "0.4"
nsstring = { path = "../../../../xpcom/rust/nsstring", optional = true }

Просмотреть файл

@ -31,6 +31,8 @@ impl Ping {
send_if_empty: bool,
precise_timestamps: bool,
include_info_sections: bool,
enabled: bool,
schedules_pings: Vec<String>,
reason_codes: Vec<String>,
) -> Self {
if need_ipc() {
@ -42,6 +44,8 @@ impl Ping {
send_if_empty,
precise_timestamps,
include_info_sections,
enabled,
schedules_pings,
reason_codes,
))
}
@ -105,7 +109,7 @@ mod test {
// Smoke test for what should be the generated code.
static PROTOTYPE_PING: Lazy<Ping> =
Lazy::new(|| Ping::new("prototype", false, true, true, true, vec![]));
Lazy::new(|| Ping::new("prototype", false, true, true, true, true, vec![], vec![]));
#[test]
fn smoke_test_custom_ping() {

Просмотреть файл

@ -139,6 +139,8 @@ pub extern "C" fn jog_test_register_ping(
send_if_empty: bool,
precise_timestamps: bool,
include_info_sections: bool,
enabled: bool,
schedules_pings: &ThinVec<nsCString>,
reason_codes: &ThinVec<nsCString>,
) -> u32 {
let ping_name = name.to_string();
@ -146,12 +148,18 @@ pub extern "C" fn jog_test_register_ping(
.iter()
.map(|reason| reason.to_string())
.collect();
let schedules_pings = schedules_pings
.iter()
.map(|ping| ping.to_string())
.collect();
create_and_register_ping(
ping_name,
include_client_id,
send_if_empty,
precise_timestamps,
include_info_sections,
enabled,
schedules_pings,
reason_codes,
)
.expect("Creation or registration of ping failed.") // permitted to panic in test-only method.
@ -163,6 +171,8 @@ fn create_and_register_ping(
send_if_empty: bool,
precise_timestamps: bool,
include_info_sections: bool,
enabled: bool,
schedules_pings: Vec<String>,
reason_codes: Vec<String>,
) -> Result<u32, Box<dyn std::error::Error>> {
let ns_name = nsCString::from(&ping_name);
@ -172,6 +182,8 @@ fn create_and_register_ping(
send_if_empty,
precise_timestamps,
include_info_sections,
enabled,
schedules_pings,
reason_codes,
);
extern "C" {
@ -219,6 +231,8 @@ struct PingDefinitionData {
send_if_empty: bool,
precise_timestamps: bool,
include_info_sections: bool,
enabled: bool,
schedules_pings: Option<Vec<String>>,
reason_codes: Option<Vec<String>>,
}
@ -266,6 +280,8 @@ pub extern "C" fn jog_load_jogfile(jogfile_path: &nsAString) -> bool {
ping.send_if_empty,
ping.precise_timestamps,
ping.include_info_sections,
ping.enabled,
ping.schedules_pings.unwrap_or_else(Vec::new),
ping.reason_codes.unwrap_or_else(Vec::new),
);
}

Просмотреть файл

@ -56,6 +56,8 @@ known_ping_args = [
"send_if_empty",
"precise_timestamps",
"include_info_sections",
"enabled",
"schedules_pings",
"reason_codes",
]

Просмотреть файл

@ -148,10 +148,12 @@ pub fn create_and_register_ping(
send_if_empty: bool,
precise_timestamps: bool,
include_info_sections: bool,
enabled: bool,
schedules_pings: Vec<String>,
reason_codes: Vec<String>,
) -> Result<u32, Box<dyn std::error::Error>> {
let ping_id = NEXT_PING_ID.fetch_add(1, Ordering::SeqCst);
let ping = Ping::new(ping_name, include_client_id, send_if_empty, precise_timestamps, include_info_sections, reason_codes);
let ping = Ping::new(ping_name, include_client_id, send_if_empty, precise_timestamps, include_info_sections, enabled, schedules_pings, reason_codes);
assert!(
__jog_metric_maps::PING_MAP.write()?.insert(ping_id.into(), ping).is_none(),
"We should never insert a runtime ping with an already-used id."

Просмотреть файл

@ -21,6 +21,8 @@ pub static {{ obj.name|snake_case }}: Lazy<Ping> = Lazy::new(|| {
{{ obj.send_if_empty|rust }},
{{ obj.precise_timestamps|rust }},
{{ obj.include_info_sections|rust }},
{{ obj.enabled|rust }},
{{ obj.schedules_pings|rust }},
{{ obj.reason_codes|rust }},
)
});

Просмотреть файл

@ -197,12 +197,12 @@ pub extern "C" fn fog_test_get_experiment_data(
///
/// See [`glean_core::Glean::set_metrics_disabled_config`].
#[no_mangle]
pub extern "C" fn fog_set_metrics_feature_config(config_json: &nsACString) {
pub extern "C" fn fog_apply_server_knobs_config(config_json: &nsACString) {
// Normalize null and empty strings to a stringified empty map
if config_json == "null" || config_json.is_empty() {
glean::glean_set_metrics_enabled_config("{}".to_owned());
glean::glean_apply_server_knobs_config("{}".to_owned());
}
glean::glean_set_metrics_enabled_config(config_json.to_string());
glean::glean_apply_server_knobs_config(config_json.to_string());
}
/// Performs Glean tasks when client state changes to inactive

Просмотреть файл

@ -313,6 +313,8 @@
false,
true,
true,
true,
[],
[
"background",
"dirty_startup",
@ -325,6 +327,8 @@
true,
true,
true,
true,
[],
[]
],
[
@ -333,6 +337,8 @@
false,
true,
true,
true,
[],
[
"background",
"max_capacity",
@ -345,6 +351,8 @@
false,
true,
true,
true,
[],
[
"overdue",
"reschedule",
@ -359,6 +367,8 @@
true,
true,
false,
true,
[],
[]
]
]

Просмотреть файл

@ -21,6 +21,8 @@ pub static not_baseline: Lazy<Ping> = Lazy::new(|| {
false,
true,
true,
true,
vec![],
vec!["background".into(), "dirty_startup".into(), "foreground".into()],
)
});
@ -38,6 +40,8 @@ pub static not_deletion_request: Lazy<Ping> = Lazy::new(|| {
true,
true,
true,
true,
vec![],
vec![],
)
});
@ -53,6 +57,8 @@ pub static not_events: Lazy<Ping> = Lazy::new(|| {
false,
true,
true,
true,
vec![],
vec!["background".into(), "max_capacity".into(), "startup".into()],
)
});
@ -72,6 +78,8 @@ pub static not_metrics: Lazy<Ping> = Lazy::new(|| {
false,
true,
true,
true,
vec![],
vec!["overdue".into(), "reschedule".into(), "today".into(), "tomorrow".into(), "upgrade".into()],
)
});
@ -85,6 +93,8 @@ pub static not_ohttp: Lazy<Ping> = Lazy::new(|| {
true,
true,
false,
true,
vec![],
vec![],
)
});

Просмотреть файл

@ -21,9 +21,11 @@ add_task(function test_fog_metrics_disabled_remotely() {
// Create and set a feature configuration that disables the test metric.
const feature_config = {
"test_only.cheesy_string": false,
metrics_enabled: {
"test_only.cheesy_string": false,
},
};
Services.fog.setMetricsFeatureConfig(JSON.stringify(feature_config));
Services.fog.applyServerKnobsConfig(JSON.stringify(feature_config));
// Attempt to set another cheesy string in the test metric. This should not
// record because of the override to the metric's default value in the
@ -49,10 +51,12 @@ add_task(function test_fog_multiple_metrics_disabled_remotely() {
// Create and set a feature configuration that disables multiple test
// metrics.
var feature_config = {
"test_only.cheesy_string": false,
"test_only.meaning_of_life": false,
metrics_enabled: {
"test_only.cheesy_string": false,
"test_only.meaning_of_life": false,
},
};
Services.fog.setMetricsFeatureConfig(JSON.stringify(feature_config));
Services.fog.applyServerKnobsConfig(JSON.stringify(feature_config));
// Attempt to set the metrics again. This should not record because of the
// override to the metrics' default value in the feature configuration.
@ -65,10 +69,12 @@ add_task(function test_fog_multiple_metrics_disabled_remotely() {
// Change the feature configuration to re-enable the `cheesy_string` metric.
feature_config = {
"test_only.cheesy_string": true,
"test_only.meaning_of_life": false,
metrics_enabled: {
"test_only.cheesy_string": true,
"test_only.meaning_of_life": false,
},
};
Services.fog.setMetricsFeatureConfig(JSON.stringify(feature_config));
Services.fog.applyServerKnobsConfig(JSON.stringify(feature_config));
// Attempt to set the metrics again. This should only record `cheesy_string`
// because of the most recent feature configuration.
@ -101,9 +107,11 @@ add_task(function test_fog_metrics_feature_config_api_handles_null_values() {
// Create and set a feature configuration that disables the test metric.
const feature_config = {
"test_only.cheesy_string": false,
metrics_enabled: {
"test_only.cheesy_string": false,
},
};
Services.fog.setMetricsFeatureConfig(JSON.stringify(feature_config));
Services.fog.applyServerKnobsConfig(JSON.stringify(feature_config));
// Attempt to set another cheesy string in the test metric. This should not
// record because of the override to the metric's default value in the
@ -113,7 +121,7 @@ add_task(function test_fog_metrics_feature_config_api_handles_null_values() {
Assert.equal(str1, Glean.testOnly.cheesyString.testGetValue("test-ping"));
// Set the configuration to `null`.
Services.fog.setMetricsFeatureConfig(null);
Services.fog.applyServerKnobsConfig(null);
// Attempt to set another cheesy string in the test metric. This should now
// record because `null` doesn't change already existing configuration.
@ -122,7 +130,7 @@ add_task(function test_fog_metrics_feature_config_api_handles_null_values() {
// Set the configuration to `""` to replicate getting an empty string from
// Nimbus.
Services.fog.setMetricsFeatureConfig("");
Services.fog.applyServerKnobsConfig("");
// Attempt to set another cheesy string in the test metric. This should now
// record again because `""` doesn't change already existing configuration.
@ -140,9 +148,11 @@ add_task(function test_fog_metrics_disabled_reset_fog_behavior() {
// Create and set a feature configuration that disables the test metric.
const feature_config = {
"test_only.cheesy_string": false,
metrics_enabled: {
"test_only.cheesy_string": false,
},
};
Services.fog.setMetricsFeatureConfig(JSON.stringify(feature_config));
Services.fog.applyServerKnobsConfig(JSON.stringify(feature_config));
// Attempt to set another cheesy string in the test metric. This should not
// record because of the override to the metric's default value in the

Просмотреть файл

@ -289,7 +289,16 @@ add_task(async function test_jog_custom_pings() {
`"ping"`,
false
);
Services.fog.testRegisterRuntimePing("jog-ping", true, true, true, true, []);
Services.fog.testRegisterRuntimePing(
"jog-ping",
true,
true,
true,
true,
true,
[],
[]
);
Assert.ok("jogPing" in GleanPings);
let submitted = false;
Glean.jogCat.jogPingBool.set(false);
@ -639,9 +648,16 @@ add_task(function test_jog_dotted_categories_work() {
add_task(async function test_jog_ping_works() {
const kReason = "reason-1";
Services.fog.testRegisterRuntimePing("my-ping", true, true, true, true, [
kReason,
]);
Services.fog.testRegisterRuntimePing(
"my-ping",
true,
true,
true,
true,
true,
[],
[kReason]
);
let submitted = false;
GleanPings.myPing.testBeforeNextSubmit(reason => {
submitted = true;
@ -653,9 +669,16 @@ add_task(async function test_jog_ping_works() {
add_task(async function test_jog_noinfo_ping_works() {
const kReason = "reason-1";
Services.fog.testRegisterRuntimePing("noinfo-ping", true, true, true, false, [
kReason,
]);
Services.fog.testRegisterRuntimePing(
"noinfo-ping",
true,
true,
true,
false,
true,
[],
[kReason]
);
let submitted = false;
GleanPings.noinfoPing.testBeforeNextSubmit(reason => {
submitted = true;

Просмотреть файл

@ -312,14 +312,14 @@ FOG::TestGetExperimentData(const nsACString& aExperimentId, JSContext* aCx,
}
NS_IMETHODIMP
FOG::SetMetricsFeatureConfig(const nsACString& aJsonConfig) {
FOG::ApplyServerKnobsConfig(const nsACString& aJsonConfig) {
#ifdef MOZ_GLEAN_ANDROID
NS_WARNING(
"Don't set metric feature configs from Gecko in Android. Ignoring.");
return NS_OK;
#else
MOZ_ASSERT(XRE_IsParentProcess());
glean::impl::fog_set_metrics_feature_config(&aJsonConfig);
glean::impl::fog_apply_server_knobs_config(&aJsonConfig);
return NS_OK;
#endif
}
@ -408,17 +408,16 @@ FOG::TestRegisterRuntimeMetric(
}
NS_IMETHODIMP
FOG::TestRegisterRuntimePing(const nsACString& aName,
const bool aIncludeClientId,
const bool aSendIfEmpty,
const bool aPreciseTimestamps,
const bool aIncludeInfoSections,
const nsTArray<nsCString>& aReasonCodes,
uint32_t* aPingIdOut) {
FOG::TestRegisterRuntimePing(
const nsACString& aName, const bool aIncludeClientId,
const bool aSendIfEmpty, const bool aPreciseTimestamps,
const bool aIncludeInfoSections, const bool aEnabled,
const nsTArray<nsCString>& aSchedulesPings,
const nsTArray<nsCString>& aReasonCodes, uint32_t* aPingIdOut) {
*aPingIdOut = 0;
*aPingIdOut = glean::jog::jog_test_register_ping(
&aName, aIncludeClientId, aSendIfEmpty, aPreciseTimestamps,
aIncludeInfoSections, &aReasonCodes);
aIncludeInfoSections, aEnabled, &aSchedulesPings, &aReasonCodes);
return NS_OK;
}

Просмотреть файл

@ -113,7 +113,7 @@ interface nsIFOG : nsISupports
* {metric_base_identifier: boolean,}
* which may contain multiple metric object entries.
*/
void setMetricsFeatureConfig(in ACString aJsonConfig);
void applyServerKnobsConfig(in ACString aJsonConfig);
/**
* ** Test-only Method **
@ -184,6 +184,7 @@ interface nsIFOG : nsISupports
* @param aSendIfEmpty - Whether the ping should send even if empty.
* @param aIncludeInfoSections - Whether the ping should include
* {client|ping}_info sections.
* TODO(jer): docs
* @param aReasonCodes - The list of valid reasons for ping submission.
*/
uint32_t testRegisterRuntimePing(in ACString aName,
@ -191,5 +192,7 @@ interface nsIFOG : nsISupports
in boolean aSendIfEmpty,
in boolean aPreciseTimestamps,
in boolean aIncludeInfoSections,
in boolean aEnabled,
in Array<ACString> aSchedulesPings,
in Array<ACString> aReasonCodes);
};

Просмотреть файл

@ -207,7 +207,7 @@ export class _ExperimentManager {
lazy.NimbusFeatures.nimbusTelemetry.getVariable(
"gleanMetricConfiguration"
) ?? {};
Services.fog.setMetricsFeatureConfig(JSON.stringify(cfg));
Services.fog.applyServerKnobsConfig(JSON.stringify(cfg));
});
}

Просмотреть файл

@ -513,7 +513,9 @@ add_task(async function test_check_unseen_enrollments_telemetry_events() {
featureId: "nimbusTelemetry",
value: {
gleanMetricConfiguration: {
"nimbus_events.enrollment_status": true,
metrics_enabled: {
"nimbus_events.enrollment_status": true,
},
},
},
},