Bug 1673662 - Implement FOG C++ and JS APIs for String metrics r=brizental,janerik

Differential Revision: https://phabricator.services.mozilla.com/D95785
This commit is contained in:
Chris H-C 2020-11-06 16:39:39 +00:00
Родитель 4f13e2395d
Коммит 5d2e0b64dc
10 изменённых файлов: 257 добавлений и 1 удалений

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

@ -22,6 +22,38 @@ define_metric_ffi!(TIMESPAN_MAP {
stop -> fog_timespan_stop(), stop -> fog_timespan_stop(),
}); });
// The String functions are custom because test_get needs to use an outparam.
// If we can make test_get optional, we can go back to using the macro to
// generate the rest of the functions, or something.
#[no_mangle]
pub extern "C" fn fog_string_test_has_value(id: u32, storage_name: FfiStr) -> u8 {
match crate::metrics::__glean_metric_maps::STRING_MAP.get(&id.into()) {
Some(metric) => metric.test_get_value(storage_name.as_str()).is_some() as u8,
None => panic!("No metric for id {}", id),
}
}
#[cfg(feature = "with_gecko")]
#[no_mangle]
pub extern "C" fn fog_string_test_get_value(id: u32, storage_name: FfiStr, value: &mut nsACString) {
match crate::metrics::__glean_metric_maps::STRING_MAP.get(&id.into()) {
Some(metric) => {
value.assign(&metric.test_get_value(storage_name.as_str()).unwrap());
}
None => panic!("No metric for id {}", id),
}
}
#[cfg(feature = "with_gecko")]
#[no_mangle]
pub extern "C" fn fog_string_set(id: u32, value: &nsACString) {
match crate::metrics::__glean_metric_maps::STRING_MAP.get(&id.into()) {
Some(metric) => metric.set(value.to_utf8()),
None => panic!("No metric for id {}", id),
}
}
// The Uuid functions are custom because test_get needs to use an outparam. // The Uuid functions are custom because test_get needs to use an outparam.
// If we can make test_get optional, we can go back to using the macro to // If we can make test_get optional, we can go back to using the macro to
// generate the rest of the functions, or something. // generate the rest of the functions, or something.

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

@ -7,6 +7,7 @@
#include "mozilla/glean/Counter.h" #include "mozilla/glean/Counter.h"
#include "mozilla/glean/Timespan.h" #include "mozilla/glean/Timespan.h"
#include "mozilla/glean/String.h"
#include "mozilla/glean/Uuid.h" #include "mozilla/glean/Uuid.h"
#endif // mozilla_Glean_MetricTypes_h #endif // mozilla_Glean_MetricTypes_h

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

@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#include "mozilla/glean/String.h"
#include "nsString.h"
#include "mozilla/Components.h"
#include "nsIClassInfoImpl.h"
namespace mozilla {
namespace glean {
NS_IMPL_CLASSINFO(GleanString, nullptr, 0, {0})
NS_IMPL_ISUPPORTS_CI(GleanString, nsIGleanString)
NS_IMETHODIMP
GleanString::Set(const nsACString& value, JSContext* cx) {
this->mString.Set(value);
return NS_OK;
}
NS_IMETHODIMP
GleanString::TestHasValue(const nsACString& aStorageName, JSContext* cx,
bool* result) {
*result = this->mString.TestHasValue(PromiseFlatCString(aStorageName).get());
return NS_OK;
}
NS_IMETHODIMP
GleanString::TestGetValue(const nsACString& aStorageName, JSContext* cx,
nsACString& result) {
result.Assign(
this->mString.TestGetValue(PromiseFlatCString(aStorageName).get()));
return NS_OK;
}
} // namespace glean
} // namespace mozilla

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

@ -0,0 +1,97 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_glean_GleanString_h
#define mozilla_glean_GleanString_h
#include "nsIGleanMetrics.h"
#include "nsString.h"
namespace mozilla {
namespace glean {
namespace impl {
extern "C" {
void fog_string_set(uint32_t id, const nsACString& value);
uint32_t fog_string_test_has_value(uint32_t id, const char* storageName);
void fog_string_test_get_value(uint32_t id, const char* storageName,
nsACString& value);
}
class StringMetric {
public:
constexpr explicit StringMetric(uint32_t id) : mId(id) {}
/*
* Set to the specified value.
*
* Truncates the value if it is longer than 100 bytes and logs an error.
* See https://mozilla.github.io/glean/book/user/metrics/string.html#limits.
*
* @param value The string to set the metric to.
*/
void Set(const nsACString& value) const { fog_string_set(mId, value); }
/**
* **Test-only API**
*
* Tests whether a value is stored for the metric.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* Parent process only. Panics in child processes.
*
* @param aStorageName the name of the ping to retrieve the metric for.
* @return true if metric value exists, otherwise false
*/
bool TestHasValue(const char* aStorageName) const {
return fog_string_test_has_value(mId, aStorageName) != 0;
}
/**
* **Test-only API**
*
* Gets the currently stored value as a string.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @return value of the stored metric.
*/
nsCString TestGetValue(const char* aStorageName) const {
nsCString ret;
fog_string_test_get_value(mId, aStorageName, ret);
return ret;
}
private:
const uint32_t mId;
};
} // namespace impl
class GleanString final : public nsIGleanString {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGLEANSTRING
explicit GleanString(uint32_t id) : mString(id){};
private:
virtual ~GleanString() = default;
const impl::StringMetric mString;
};
} // namespace glean
} // namespace mozilla
#endif /* mozilla_glean_GleanString.h */

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

@ -29,7 +29,7 @@ def generate_metric_ids(objs):
return lambda metric: metric_id_mapping[(metric.category, metric.name)] return lambda metric: metric_id_mapping[(metric.category, metric.name)]
IMPLEMENTED_CPP_TYPES = ["counter", "timespan", "uuid"] IMPLEMENTED_CPP_TYPES = ["counter", "string", "timespan", "uuid"]
def is_implemented_metric_type(typ): def is_implemented_metric_type(typ):

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

@ -59,6 +59,18 @@ TEST(FOG, TestCppCounterWorks)
ASSERT_EQ(42, mozilla::glean::test_only::bad_code.TestGetValue("test-ping")); ASSERT_EQ(42, mozilla::glean::test_only::bad_code.TestGetValue("test-ping"));
} }
TEST(FOG, TestCppStringWorks)
{
auto kValue = "cheez!"_ns;
mozilla::glean::test_only::cheesy_string.Set(kValue);
ASSERT_TRUE(
mozilla::glean::test_only::cheesy_string.TestHasValue("test-ping"));
ASSERT_STREQ(
kValue.get(),
mozilla::glean::test_only::cheesy_string.TestGetValue("test-ping").get());
}
TEST(FOG, TestCppTimespanWorks) TEST(FOG, TestCppTimespanWorks)
{ {
mozilla::glean::test_only::can_we_time_it.Start(); mozilla::glean::test_only::can_we_time_it.Start();

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

@ -23,6 +23,7 @@ if CONFIG["MOZ_GLEAN"]:
"bindings/Glean.h", "bindings/Glean.h",
"bindings/MetricTypes.h", "bindings/MetricTypes.h",
"bindings/private/Counter.h", "bindings/private/Counter.h",
"bindings/private/String.h",
"bindings/private/Timespan.h", "bindings/private/Timespan.h",
"bindings/private/Uuid.h", "bindings/private/Uuid.h",
] ]
@ -31,6 +32,7 @@ if CONFIG["MOZ_GLEAN"]:
"bindings/Category.cpp", "bindings/Category.cpp",
"bindings/Glean.cpp", "bindings/Glean.cpp",
"bindings/private/Counter.cpp", "bindings/private/Counter.cpp",
"bindings/private/String.cpp",
"bindings/private/Timespan.cpp", "bindings/private/Timespan.cpp",
"bindings/private/Uuid.cpp", "bindings/private/Uuid.cpp",
"ipc/FOGIPC.cpp", "ipc/FOGIPC.cpp",

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

@ -47,6 +47,23 @@ test_only:
send_in_pings: send_in_pings:
- test-ping - test-ping
cheesy_string:
type: string
description: |
Only the cheesiest of strings.
This is a test-only metric.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1673662
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1673662#c1
data_sensitivity:
- technical
notification_emails:
- glean-team@mozilla.com
expires: never
send_in_pings:
- test-ping
what_id_it: # Using a different metrics yaml style for fun. what_id_it: # Using a different metrics yaml style for fun.
type: uuid type: uuid
description: | description: |

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

@ -51,6 +51,52 @@ interface nsIGleanCounter : nsISupports
long testGetValue(in ACString aStorageName); long testGetValue(in ACString aStorageName);
}; };
[scriptable, uuid(d84a3555-46f1-48c1-9122-e8e88b069d2b)]
interface nsIGleanString : nsISupports
{
/*
* Set to the specified value.
*
* @param value The string to set the metric to.
*/
[implicit_jscontext]
void set(in ACString value);
/**
* **Test-only API**
*
* Tests whether a value is stored for the metric.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* Parent process only. Panics in child processes.
*
* @param aStorageName the name of the ping to retrieve the metric for.
* @return true if metric value exists, otherwise false
*/
[implicit_jscontext]
bool testHasValue(in ACString aStorageName);
/**
* **Test-only API**
*
* Gets the currently stored value as a string.
*
* This function will attempt to await the last parent-process task (if any)
* writing to the the metric's storage engine before returning a value.
* This function will not wait for data from child processes.
*
* This doesn't clear the stored value.
* Parent process only. Panics in child processes.
*
* @return value of the stored metric.
*/
[implicit_jscontext]
ACString testGetValue(in ACString aStorageName);
};
[scriptable, uuid(2586530c-030f-11eb-93cb-cbf30d25225a)] [scriptable, uuid(2586530c-030f-11eb-93cb-cbf30d25225a)]
interface nsIGleanTimespan : nsISupports interface nsIGleanTimespan : nsISupports
{ {

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

@ -32,6 +32,14 @@ add_task(function test_fog_counter_works() {
Assert.equal(31, Glean.test_only.bad_code.testGetValue("test-ping")); Assert.equal(31, Glean.test_only.bad_code.testGetValue("test-ping"));
}); });
add_task(async function test_fog_string_works() {
const value = "a cheesy string!";
Glean.test_only.cheesy_string.set(value);
Assert.ok(Glean.test_only.cheesy_string.testHasValue("test-ping"));
Assert.equal(value, Glean.test_only.cheesy_string.testGetValue("test-ping"));
});
add_task(async function test_fog_timespan_works() { add_task(async function test_fog_timespan_works() {
// We start, briefly sleep and then stop. // We start, briefly sleep and then stop.
// That guarantees some time to measure. // That guarantees some time to measure.