Skip to content

Commit 760d759

Browse files
authored
DocGenerator fixes (open-telemetry#13968)
1 parent fc7e166 commit 760d759

File tree

8 files changed

+213
-76
lines changed

8 files changed

+213
-76
lines changed

instrumentation-docs/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ tasks {
2222
val runAnalysis by registering(JavaExec::class) {
2323
dependsOn(classes)
2424

25+
systemProperty("basePath", project.rootDir)
2526
mainClass.set("io.opentelemetry.instrumentation.docs.DocGeneratorApplication")
2627
classpath(sourceSets["main"].runtimeClasspath)
2728
}

instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/DocGeneratorApplication.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@
77

88
import static java.util.Locale.Category.FORMAT;
99

10-
import com.fasterxml.jackson.core.JsonProcessingException;
1110
import io.opentelemetry.instrumentation.docs.internal.InstrumentationModule;
1211
import io.opentelemetry.instrumentation.docs.utils.FileManager;
1312
import io.opentelemetry.instrumentation.docs.utils.YamlHelper;
1413
import java.io.BufferedWriter;
1514
import java.io.IOException;
16-
import java.nio.charset.Charset;
1715
import java.nio.file.Files;
1816
import java.nio.file.Paths;
1917
import java.util.List;
@@ -26,20 +24,25 @@ public class DocGeneratorApplication {
2624

2725
private static final Logger logger = Logger.getLogger(DocGeneratorApplication.class.getName());
2826

29-
public static void main(String[] args) throws JsonProcessingException {
30-
FileManager fileManager = new FileManager("instrumentation/");
27+
public static void main(String[] args) throws IOException {
28+
// Identify path to repo so we can use absolute paths
29+
String baseRepoPath = System.getProperty("basePath");
30+
if (baseRepoPath == null) {
31+
baseRepoPath = "./";
32+
} else {
33+
baseRepoPath += "/";
34+
}
35+
36+
FileManager fileManager = new FileManager(baseRepoPath);
3137
List<InstrumentationModule> modules = new InstrumentationAnalyzer(fileManager).analyze();
3238

3339
try (BufferedWriter writer =
34-
Files.newBufferedWriter(
35-
Paths.get("docs/instrumentation-list.yaml"), Charset.defaultCharset())) {
40+
Files.newBufferedWriter(Paths.get(baseRepoPath + "docs/instrumentation-list.yaml"))) {
3641
writer.write("# This file is generated and should not be manually edited.\n");
3742
writer.write("# The structure and contents are a work in progress and subject to change.\n");
3843
writer.write(
3944
"# For more information see: https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/13468\n\n");
4045
YamlHelper.generateInstrumentationYaml(modules, writer);
41-
} catch (IOException e) {
42-
logger.severe("Error writing instrumentation list: " + e.getMessage());
4346
}
4447

4548
printStats(modules);

instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/InstrumentationAnalyzer.java

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@
77

88
import static io.opentelemetry.instrumentation.docs.parsers.GradleParser.parseGradleFile;
99

10-
import com.fasterxml.jackson.core.JsonProcessingException;
1110
import com.fasterxml.jackson.databind.exc.ValueInstantiationException;
1211
import io.opentelemetry.instrumentation.docs.internal.DependencyInfo;
1312
import io.opentelemetry.instrumentation.docs.internal.EmittedMetrics;
1413
import io.opentelemetry.instrumentation.docs.internal.InstrumentationModule;
1514
import io.opentelemetry.instrumentation.docs.internal.InstrumentationType;
15+
import io.opentelemetry.instrumentation.docs.parsers.MetricParser;
1616
import io.opentelemetry.instrumentation.docs.utils.FileManager;
1717
import io.opentelemetry.instrumentation.docs.utils.InstrumentationPath;
1818
import io.opentelemetry.instrumentation.docs.utils.YamlHelper;
19+
import java.io.IOException;
1920
import java.util.ArrayList;
2021
import java.util.HashMap;
2122
import java.util.HashSet;
@@ -41,7 +42,7 @@ class InstrumentationAnalyzer {
4142
* @return a list of {@link InstrumentationModule} objects with aggregated types
4243
*/
4344
public static List<InstrumentationModule> convertToInstrumentationModules(
44-
List<InstrumentationPath> paths) {
45+
String rootPath, List<InstrumentationPath> paths) {
4546
Map<String, InstrumentationModule> moduleMap = new HashMap<>();
4647

4748
for (InstrumentationPath path : paths) {
@@ -50,7 +51,7 @@ public static List<InstrumentationModule> convertToInstrumentationModules(
5051
moduleMap.put(
5152
key,
5253
new InstrumentationModule.Builder()
53-
.srcPath(path.srcPath().replace("/javaagent", "").replace("/library", ""))
54+
.srcPath(sanitizePathName(rootPath, path.srcPath()))
5455
.instrumentationName(path.instrumentationName())
5556
.namespace(path.namespace())
5657
.group(path.group())
@@ -61,16 +62,21 @@ public static List<InstrumentationModule> convertToInstrumentationModules(
6162
return new ArrayList<>(moduleMap.values());
6263
}
6364

65+
private static String sanitizePathName(String rootPath, String path) {
66+
return path.replace(rootPath, "").replace("/javaagent", "").replace("/library", "");
67+
}
68+
6469
/**
6570
* Traverses the given root directory to find all instrumentation paths and then analyzes them.
66-
* Extracts version information from each instrumentation's build.gradle file, and other
67-
* information from metadata.yaml files.
71+
* Extracts version information from each instrumentation's build.gradle file, metric data from
72+
* files in the .telemetry directories, and other information from metadata.yaml files.
6873
*
6974
* @return a list of {@link InstrumentationModule}
7075
*/
71-
List<InstrumentationModule> analyze() throws JsonProcessingException {
76+
List<InstrumentationModule> analyze() throws IOException {
7277
List<InstrumentationPath> paths = fileManager.getInstrumentationPaths();
73-
List<InstrumentationModule> modules = convertToInstrumentationModules(paths);
78+
List<InstrumentationModule> modules =
79+
convertToInstrumentationModules(fileManager.rootDir(), paths);
7480

7581
for (InstrumentationModule module : modules) {
7682
List<String> gradleFiles = fileManager.findBuildGradleFiles(module.getSrcPath());
@@ -86,12 +92,10 @@ List<InstrumentationModule> analyze() throws JsonProcessingException {
8692
}
8793
}
8894

89-
String emittedMetrics = fileManager.getMetrics(module.getSrcPath());
90-
if (emittedMetrics != null) {
91-
EmittedMetrics metrics = YamlHelper.emittedMetricsParser(emittedMetrics);
92-
if (metrics != null && metrics.getMetrics() != null) {
93-
module.setMetrics(metrics.getMetrics());
94-
}
95+
EmittedMetrics metrics =
96+
MetricParser.getMetricsFromFiles(fileManager.rootDir(), module.getSrcPath());
97+
if (!metrics.getMetrics().isEmpty()) {
98+
module.setMetrics(metrics.getMetrics());
9599
}
96100
}
97101
return modules;
@@ -100,7 +104,7 @@ List<InstrumentationModule> analyze() throws JsonProcessingException {
100104
void analyzeVersions(List<String> files, InstrumentationModule module) {
101105
Map<InstrumentationType, Set<String>> versions = new HashMap<>();
102106
for (String file : files) {
103-
String fileContents = fileManager.readFileToString(file);
107+
String fileContents = FileManager.readFileToString(file);
104108
if (fileContents == null) {
105109
continue;
106110
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.instrumentation.docs.parsers;
7+
8+
import io.opentelemetry.instrumentation.docs.internal.EmittedMetrics;
9+
import io.opentelemetry.instrumentation.docs.utils.FileManager;
10+
import io.opentelemetry.instrumentation.docs.utils.YamlHelper;
11+
import java.io.IOException;
12+
import java.nio.file.Files;
13+
import java.nio.file.Path;
14+
import java.nio.file.Paths;
15+
import java.util.ArrayList;
16+
import java.util.Collections;
17+
import java.util.HashMap;
18+
import java.util.List;
19+
import java.util.Map;
20+
import java.util.logging.Logger;
21+
import java.util.stream.Stream;
22+
23+
public class MetricParser {
24+
private static final Logger logger = Logger.getLogger(MetricParser.class.getName());
25+
26+
/**
27+
* Looks for metric files in the .telemetry directory, and combines them into a single list of
28+
* metrics.
29+
*
30+
* @param instrumentationDirectory the directory to traverse
31+
* @return contents of aggregated files
32+
*/
33+
public static EmittedMetrics getMetricsFromFiles(
34+
String rootDir, String instrumentationDirectory) {
35+
StringBuilder metricsContent = new StringBuilder("metrics:\n");
36+
Path telemetryDir = Paths.get(rootDir + "/" + instrumentationDirectory, ".telemetry");
37+
38+
if (Files.exists(telemetryDir) && Files.isDirectory(telemetryDir)) {
39+
try (Stream<Path> files = Files.list(telemetryDir)) {
40+
files
41+
.filter(path -> path.getFileName().toString().startsWith("metrics-"))
42+
.forEach(
43+
path -> {
44+
String content = FileManager.readFileToString(path.toString());
45+
if (content != null) {
46+
// Skip the first line of yaml ("metrics:") so we can aggregate into one list
47+
int firstNewline = content.indexOf('\n');
48+
if (firstNewline != -1) {
49+
String contentWithoutFirstLine = content.substring(firstNewline + 1);
50+
metricsContent.append(contentWithoutFirstLine);
51+
}
52+
}
53+
});
54+
} catch (IOException e) {
55+
logger.severe("Error reading metrics files: " + e.getMessage());
56+
}
57+
}
58+
59+
return parseMetrics(metricsContent.toString());
60+
}
61+
62+
/**
63+
* Takes in a raw string representation of the aggregated EmittedMetrics yaml, deduplicates the
64+
* metrics by name and then returns a new EmittedMetrics object.
65+
*
66+
* @param input raw string representation of EmittedMetrics yaml
67+
* @return EmittedMetrics
68+
*/
69+
// visible for testing
70+
public static EmittedMetrics parseMetrics(String input) {
71+
EmittedMetrics metrics = YamlHelper.emittedMetricsParser(input);
72+
if (metrics.getMetrics() == null) {
73+
return new EmittedMetrics(Collections.emptyList());
74+
}
75+
76+
// deduplicate metrics by name
77+
Map<String, EmittedMetrics.Metric> deduplicatedMetrics = new HashMap<>();
78+
for (EmittedMetrics.Metric metric : metrics.getMetrics()) {
79+
deduplicatedMetrics.put(metric.getName(), metric);
80+
}
81+
82+
List<EmittedMetrics.Metric> uniqueMetrics = new ArrayList<>(deduplicatedMetrics.values());
83+
return new EmittedMetrics(uniqueMetrics);
84+
}
85+
86+
private MetricParser() {}
87+
}

instrumentation-docs/src/main/java/io/opentelemetry/instrumentation/docs/utils/FileManager.java

Lines changed: 6 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,17 @@
1717
import java.util.stream.Stream;
1818
import javax.annotation.Nullable;
1919

20-
public class FileManager {
20+
public record FileManager(String rootDir) {
2121
private static final Logger logger = Logger.getLogger(FileManager.class.getName());
22-
private final String rootDir;
2322

24-
public FileManager(String rootDir) {
25-
this.rootDir = rootDir;
26-
}
27-
28-
public List<InstrumentationPath> getInstrumentationPaths() {
29-
Path rootPath = Paths.get(rootDir);
23+
public List<InstrumentationPath> getInstrumentationPaths() throws IOException {
24+
Path rootPath = Paths.get(rootDir + "instrumentation");
3025

3126
try (Stream<Path> walk = Files.walk(rootPath)) {
3227
return walk.filter(Files::isDirectory)
3328
.filter(dir -> isValidInstrumentationPath(dir.toString()))
3429
.map(dir -> parseInstrumentationPath(dir.toString()))
3530
.collect(Collectors.toList());
36-
} catch (IOException e) {
37-
logger.severe("Error traversing directory: " + e.getMessage());
38-
return new ArrayList<>();
3931
}
4032
}
4133

@@ -85,7 +77,7 @@ public static boolean isValidInstrumentationPath(String filePath) {
8577
}
8678

8779
public List<String> findBuildGradleFiles(String instrumentationDirectory) {
88-
Path rootPath = Paths.get(instrumentationDirectory);
80+
Path rootPath = Paths.get(rootDir + instrumentationDirectory);
8981

9082
try (Stream<Path> walk = Files.walk(rootPath)) {
9183
return walk.filter(Files::isRegularFile)
@@ -103,49 +95,20 @@ public List<String> findBuildGradleFiles(String instrumentationDirectory) {
10395

10496
@Nullable
10597
public String getMetaDataFile(String instrumentationDirectory) {
106-
String metadataFile = instrumentationDirectory + "/metadata.yaml";
98+
String metadataFile = rootDir + instrumentationDirectory + "/metadata.yaml";
10799
if (Files.exists(Paths.get(metadataFile))) {
108100
return readFileToString(metadataFile);
109101
}
110102
return null;
111103
}
112104

113105
@Nullable
114-
public String readFileToString(String filePath) {
106+
public static String readFileToString(String filePath) {
115107
try {
116108
return Files.readString(Paths.get(filePath));
117109
} catch (IOException e) {
118110
logger.severe("Error reading file: " + e.getMessage());
119111
return null;
120112
}
121113
}
122-
123-
/**
124-
* Looks for metric files in the .telemetry directory
125-
*
126-
* @param instrumentationDirectory the directory to traverse
127-
* @return contents of file
128-
*/
129-
public String getMetrics(String instrumentationDirectory) {
130-
StringBuilder metricsContent = new StringBuilder();
131-
Path telemetryDir = Paths.get(instrumentationDirectory, ".telemetry");
132-
133-
if (Files.exists(telemetryDir) && Files.isDirectory(telemetryDir)) {
134-
try (Stream<Path> files = Files.list(telemetryDir)) {
135-
files
136-
.filter(path -> path.getFileName().toString().startsWith("metrics-"))
137-
.forEach(
138-
path -> {
139-
String content = readFileToString(path.toString());
140-
if (content != null) {
141-
metricsContent.append(content).append("\n");
142-
}
143-
});
144-
} catch (IOException e) {
145-
logger.severe("Error reading metrics files: " + e.getMessage());
146-
}
147-
}
148-
149-
return metricsContent.toString();
150-
}
151114
}

instrumentation-docs/src/test/java/io/opentelemetry/instrumentation/docs/InstrumentationAnalyzerTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ void testConvertToInstrumentationModule() {
4141
InstrumentationType.LIBRARY));
4242

4343
List<InstrumentationModule> modules =
44-
InstrumentationAnalyzer.convertToInstrumentationModules(paths);
44+
InstrumentationAnalyzer.convertToInstrumentationModules("test", paths);
4545

4646
assertThat(modules.size()).isEqualTo(2);
4747

0 commit comments

Comments
 (0)