Skip to content

Commit 1149685

Browse files
committed
Disabling all type of name checks except empty names and exceeding length
1 parent fdf4a63 commit 1149685

File tree

2 files changed

+79
-3
lines changed

2 files changed

+79
-3
lines changed

opentelemetry-sdk/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ experimental_metrics_periodicreader_with_async_runtime = ["metrics"]
5858
spec_unstable_metrics_views = ["metrics"]
5959
experimental_logs_batch_log_processor_with_async_runtime = ["logs"]
6060
experimental_trace_batch_span_processor_with_async_runtime = ["trace"]
61+
experimental_metrics_disable_name_validation = ["metrics"]
6162

6263

6364
[[bench]]

opentelemetry-sdk/src/metrics/meter.rs

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,16 @@ use super::noop::NoopSyncInstrument;
2323
const INSTRUMENT_NAME_MAX_LENGTH: usize = 255;
2424
// maximum length of instrument unit name
2525
const INSTRUMENT_UNIT_NAME_MAX_LENGTH: usize = 63;
26+
#[cfg(not(feature = "experimental_metrics_disable_name_validation"))]
2627
const INSTRUMENT_NAME_ALLOWED_NON_ALPHANUMERIC_CHARS: [char; 4] = ['_', '.', '-', '/'];
2728

2829
// instrument validation error strings
2930
const INSTRUMENT_NAME_EMPTY: &str = "instrument name must be non-empty";
3031
const INSTRUMENT_NAME_LENGTH: &str = "instrument name must be less than 256 characters";
32+
#[cfg(not(feature = "experimental_metrics_disable_name_validation"))]
3133
const INSTRUMENT_NAME_INVALID_CHAR: &str =
3234
"characters in instrument name must be ASCII and belong to the alphanumeric characters, '_', '.', '-' and '/'";
35+
#[cfg(not(feature = "experimental_metrics_disable_name_validation"))]
3336
const INSTRUMENT_NAME_FIRST_ALPHABETIC: &str =
3437
"instrument name must start with an alphabetic character";
3538
const INSTRUMENT_UNIT_LENGTH: &str = "instrument unit must be less than 64 characters";
@@ -572,6 +575,33 @@ fn validate_bucket_boundaries(boundaries: &[f64]) -> MetricResult<()> {
572575
Ok(())
573576
}
574577

578+
// Regex pattern for Windows Performance Counter names
579+
// #[cfg(feature = "experimental_metrics_disable_name_validation")]
580+
// fn is_valid_windows_perf_counter_name(name: &str) -> bool {
581+
// let pattern = r"^\\[A-Za-z0-9_ ]+\\[A-Za-z0-9_ /%-]+$";
582+
// let re = Regex::new(pattern).unwrap();
583+
// re.is_match(name)
584+
// }
585+
586+
#[cfg(feature = "experimental_metrics_disable_name_validation")]
587+
fn validate_instrument_name(name: &str) -> MetricResult<()> {
588+
if name.is_empty() {
589+
return Err(MetricError::InvalidInstrumentConfiguration(
590+
INSTRUMENT_NAME_EMPTY,
591+
));
592+
}
593+
if name.len() > INSTRUMENT_NAME_MAX_LENGTH {
594+
return Err(MetricError::InvalidInstrumentConfiguration(
595+
INSTRUMENT_NAME_LENGTH,
596+
));
597+
}
598+
599+
// No name restrictions when name validation is disabled,
600+
// except for empty names and length
601+
Ok(())
602+
}
603+
604+
#[cfg(not(feature = "experimental_metrics_disable_name_validation"))]
575605
fn validate_instrument_name(name: &str) -> MetricResult<()> {
576606
if name.is_empty() {
577607
return Err(MetricError::InvalidInstrumentConfiguration(
@@ -583,6 +613,7 @@ fn validate_instrument_name(name: &str) -> MetricResult<()> {
583613
INSTRUMENT_NAME_LENGTH,
584614
));
585615
}
616+
586617
if name.starts_with(|c: char| !c.is_ascii_alphabetic()) {
587618
return Err(MetricError::InvalidInstrumentConfiguration(
588619
INSTRUMENT_NAME_FIRST_ALPHABETIC,
@@ -676,12 +707,17 @@ mod tests {
676707
use crate::metrics::MetricError;
677708

678709
use super::{
679-
validate_instrument_name, validate_instrument_unit, INSTRUMENT_NAME_FIRST_ALPHABETIC,
680-
INSTRUMENT_NAME_INVALID_CHAR, INSTRUMENT_NAME_LENGTH, INSTRUMENT_UNIT_INVALID_CHAR,
681-
INSTRUMENT_UNIT_LENGTH,
710+
validate_instrument_name, validate_instrument_unit, INSTRUMENT_NAME_EMPTY,
711+
INSTRUMENT_NAME_LENGTH, INSTRUMENT_UNIT_INVALID_CHAR, INSTRUMENT_UNIT_LENGTH,
712+
};
713+
714+
#[cfg(not(feature = "experimental_metrics_disable_name_validation"))]
715+
use super::{
716+
INSTRUMENT_NAME_EMPTY, INSTRUMENT_NAME_FIRST_ALPHABETIC, INSTRUMENT_NAME_INVALID_CHAR,
682717
};
683718

684719
#[test]
720+
#[cfg(not(feature = "experimental_metrics_disable_name_validation"))]
685721
fn instrument_name_validation() {
686722
// (name, expected error)
687723
let instrument_name_test_cases = vec![
@@ -694,6 +730,45 @@ mod tests {
694730
("allow/slash", ""),
695731
("allow_under_score", ""),
696732
("allow.dots.ok", ""),
733+
("", INSTRUMENT_NAME_EMPTY),
734+
("\\allow\\slash /sec", INSTRUMENT_NAME_FIRST_ALPHABETIC),
735+
("\\allow\\$$slash /sec", INSTRUMENT_NAME_FIRST_ALPHABETIC),
736+
("/not / allowed", INSTRUMENT_NAME_FIRST_ALPHABETIC),
737+
];
738+
for (name, expected_error) in instrument_name_test_cases {
739+
let assert = |result: Result<_, MetricError>| {
740+
if expected_error.is_empty() {
741+
assert!(result.is_ok());
742+
} else {
743+
assert!(matches!(
744+
result.unwrap_err(),
745+
MetricError::InvalidInstrumentConfiguration(msg) if msg == expected_error
746+
));
747+
}
748+
};
749+
750+
assert(validate_instrument_name(name).map(|_| ()));
751+
}
752+
}
753+
754+
#[test]
755+
#[cfg(feature = "experimental_metrics_disable_name_validation")]
756+
fn instrument_name_validation() {
757+
// (name, expected error)
758+
let instrument_name_test_cases = vec![
759+
("validateName", ""),
760+
("_startWithNoneAlphabet", ""),
761+
("utf8char锈", ""),
762+
("a".repeat(255).leak(), ""),
763+
("a".repeat(256).leak(), INSTRUMENT_NAME_LENGTH),
764+
("invalid name", ""),
765+
("allow/slash", ""),
766+
("allow_under_score", ""),
767+
("allow.dots.ok", ""),
768+
("", INSTRUMENT_NAME_EMPTY),
769+
("\\allow\\slash /sec", ""),
770+
("\\allow\\$$slash /sec", ""),
771+
("/not / allowed", ""),
697772
];
698773
for (name, expected_error) in instrument_name_test_cases {
699774
let assert = |result: Result<_, MetricError>| {

0 commit comments

Comments
 (0)