Adding class/struct names to the labels #33
Replies: 6 comments 23 replies
-
Good point! Thanks for raising this issue. One correction: both of these approaches would have the same label cardinality. Adding another label only increases the cardinality if there are different combinations of labels present. But that's exactly what you're trying to achieve in either case: ensure that these different functions are stored as separate time series. I'm on the fence about this. Adding a separate class label would make it easy to look at all the metrics for a given class in a language-agnostic way (i.e. without having any regexes to handle differences between the separators the languages use). But I'm not sure how useful that actually is. If we had a separate label, we would need to ensure that queries always If we merge it in, you could kind of make the case that the |
Beta Was this translation helpful? Give feedback.
-
I think it makes most sense to not have any specialized fields which might not mean anything in other languages (ie, what would be contained in I wonder if we can encode this information in |
Beta Was this translation helpful? Give feedback.
-
I've always thought that the class/struct would just be part of the module, as in the end the name of a class acts as an additional scope for the name of the function. I didn't even think of asking what other points of view were, I thought Rust was always doing that, so I actually had that implemented in the helper that lists all the the functions that have autometrics annotations: #[test]
fn detect_trait_impl_block() {
let source = r#"
struct Foo{};
#[autometrics]
impl A for Foo {
fn m_a() {}
}
"#;
let list = list_function_names(String::new(), source, true).unwrap();
assert_eq!(list.len(), 1);
assert_eq!(
list[0],
ExpectedAmLabel {
module: "Foo".into(),
function: "m_a".into()
}
);
} |
Beta Was this translation helpful? Give feedback.
-
Maybe one way of thinking about this is focusing on the question of whether you'd ever want to look at the metrics for a specific class as a whole. If so, it would make sense to have a separate label. If not and we're just using this to ensure we don't accidentally merge metrics from different functions, then it would make sense to include in the function name. |
Beta Was this translation helpful? Give feedback.
-
What if each SDK was free to use a differently-structured Key-Value dictionary to describe the precise location of a function? My reasoning is that, even if a C++namespace A {
class MyClass {
void my_func() {}
}
}
namespace B {
class MyClass {
void my_func() {}
}
} PythonFile class MyClass:
def my_func():
pass File # Can have classes with the same name in different scripts/modules
class MyClass:
def my_func():
pass Moreover, it is my humble opinion that forcing a unified locating schema on completely different languages would result in a suboptimal solution. After all, classes don't exist in Go and Rust. Java also has inner classes to consider. And what about anonymous functions declared inside of another function's body? Letting each SDK decide for its own language would remove these limitations. C++ could save the location as an object like:
while Java would do:
and Python:
I'm not sure that this is doable and practice but it's definitely a big technical challenge. What do you think? |
Beta Was this translation helpful? Give feedback.
-
One other potential argument against adding a Folks that program in OO languages, please correct me if I'm wrong about this. cc @P2P-Nathan @jamsiedaly |
Beta Was this translation helpful? Give feedback.
-
Currently, when registering metrics we don't include class names in labels any of the language implementations. Because methods maybe even more than simple functions can have overlapping names this can result in duplicated data.
Using a TypeScript (albeit a bit contrived) example to illustrate:
and
will register the same metric name + label if they're co-located in the same file. We should consider adding class names to the labels as well to help distinguish which classes and methods get called in the timeseries data.
The way I see it there are two options:
Add classes as another label. This would make sense semantically to distinguish classes as a separate category that a user can later filter/group by. However, this would increase metrics cardinality, which given our approach we should be careful about extending. Moreover, most of the other existing stuff (like dashboards, query helpers in the tooltips) don't currently account for classes.
Prepend classes to the function name. If we consider classes not important enough to warrant increasing the number of metric+label combinations, we can simply add them to the function name label, e.g.: the example above would register
function.calls.count{function="Foo.sayHi"}
. This would avoid likely duplication issues and would signal to the user reading the label that the data comes from a class method.Personally, I'm leaning to the 2nd one but would be keen to hear what others think and if we have other options here.
Beta Was this translation helpful? Give feedback.
All reactions