55
66package io .opentelemetry .javaagent .tooling .config ;
77
8+ import static java .util .Collections .emptyList ;
9+ import static java .util .Collections .emptyMap ;
810import static java .util .logging .Level .WARNING ;
911
12+ import io .opentelemetry .api .incubator .config .DeclarativeConfigProperties ;
13+ import io .opentelemetry .instrumentation .api .incubator .config .internal .ExtendedDeclarativeConfigProperties ;
1014import java .util .Collections ;
1115import java .util .HashMap ;
1216import java .util .HashSet ;
17+ import java .util .List ;
1318import java .util .Map ;
1419import java .util .Set ;
1520import java .util .logging .Logger ;
21+ import java .util .stream .Collectors ;
1622
1723public final class MethodsConfigurationParser {
1824
@@ -23,6 +29,49 @@ public final class MethodsConfigurationParser {
2329 private static final String CONFIG_FORMAT =
2430 PACKAGE_CLASS_NAME_REGEX + "(?:\\ [" + METHOD_LIST_REGEX + "])?" ;
2531
32+ /**
33+ * Parse exclude methods configuration from declarative config.
34+ *
35+ * <p>First tries structured declarative config (YAML format), then falls back to old string/list
36+ * property format for backward compatibility.
37+ *
38+ * <p>Example YAML structure:
39+ *
40+ * <pre>{@code
41+ * exclude_methods:
42+ * - class: com.example.MyClass
43+ * methods: [method1, method2]
44+ * - class: com.example.AnotherClass
45+ * methods: [someMethod]
46+ * }</pre>
47+ */
48+ public static Map <String , Set <String >> parseExcludeMethods (
49+ ExtendedDeclarativeConfigProperties config ) {
50+ // First try structured declarative config (YAML format)
51+ List <DeclarativeConfigProperties > excludeList = config .getStructuredList ("exclude_methods" );
52+ if (excludeList != null ) {
53+ return excludeList .stream ()
54+ .filter (
55+ entry -> {
56+ String className = entry .getString ("class" );
57+ return className != null && !className .isEmpty ();
58+ })
59+ .collect (
60+ Collectors .toMap (
61+ entry -> entry .getString ("class" ),
62+ entry ->
63+ new HashSet <>(entry .getScalarList ("methods" , String .class , emptyList ()))));
64+ }
65+
66+ // Fall back to old string property format for backward compatibility
67+ String excludeMethodsString = config .getString ("exclude_methods" );
68+ if (excludeMethodsString != null ) {
69+ return parse (excludeMethodsString );
70+ }
71+
72+ return emptyMap ();
73+ }
74+
2675 /**
2776 * This method takes a string in a form of {@code
2877 * "io.package.ClassName[method1,method2];my.example[someMethodName];"} and returns a map where
@@ -32,13 +81,13 @@ public final class MethodsConfigurationParser {
3281 */
3382 public static Map <String , Set <String >> parse (String configString ) {
3483 if (configString == null || configString .trim ().isEmpty ()) {
35- return Collections . emptyMap ();
84+ return emptyMap ();
3685 } else if (!validateConfigString (configString )) {
3786 logger .log (
3887 WARNING ,
3988 "Invalid trace method config \" {0}\" . Must match 'package.Class$Name[method1,method2];*'." ,
4089 configString );
41- return Collections . emptyMap ();
90+ return emptyMap ();
4291 } else {
4392 Map <String , Set <String >> toTrace = new HashMap <>();
4493 String [] classMethods = configString .split (";" , -1 );
0 commit comments