Skip to content

Commit 7bda4d4

Browse files
Merge branch 'master' into alexeyk/debug-ci-timeout
2 parents ab90b23 + 9de0da8 commit 7bda4d4

File tree

12 files changed

+206
-8
lines changed

12 files changed

+206
-8
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
kotlin version: 2.0.21
2+
error message: The daemon has terminated unexpectedly on startup attempt #1 with error code: 0. The daemon process output:
3+
1. Kotlin compile daemon is ready
4+

dd-java-agent/agent-ci-visibility/src/main/java/datadog/trace/civisibility/source/index/RepoIndexBuilder.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ private static final class RepoIndexingFileVisitor implements FileVisitor<Path>
104104
private final RepoIndexingStats indexingStats;
105105
private final Path repoRoot;
106106
private final AtomicInteger sourceRootCounter;
107+
private final boolean followSymlinks;
107108

108109
private RepoIndexingFileVisitor(
109110
Config config,
@@ -120,16 +121,23 @@ private RepoIndexingFileVisitor(
120121
packageTree = new PackageTree(config);
121122
indexingStats = new RepoIndexingStats();
122123
sourceRootCounter = new AtomicInteger();
124+
followSymlinks = config.isCiVisibilityRepoIndexFollowSymlinks();
123125
}
124126

125127
@Override
126128
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
127-
if (Files.isSymbolicLink(dir) && readSymbolicLink(dir).startsWith(repoRoot)) {
128-
// The path is a symlink that points inside the repo.
129-
// We'll visit the folder that it points to anyway,
130-
// moreover, we don't want two different results for one file
131-
// (one containing the symlink, the other - the actual folder).
132-
return FileVisitResult.SKIP_SUBTREE;
129+
if (Files.isSymbolicLink(dir)) {
130+
if (!followSymlinks) {
131+
// Configured to skip symlinks
132+
return FileVisitResult.SKIP_SUBTREE;
133+
}
134+
if (readSymbolicLink(dir).startsWith(repoRoot)) {
135+
// The path is a symlink that points inside the repo.
136+
// We'll visit the folder that it points to anyway,
137+
// moreover, we don't want two different results for one file
138+
// (one containing the symlink, the other - the actual folder).
139+
return FileVisitResult.SKIP_SUBTREE;
140+
}
133141
}
134142
return FileVisitResult.CONTINUE;
135143
}

dd-trace-api/src/main/java/datadog/trace/api/config/CiVisibilityConfig.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ public final class CiVisibilityConfig {
4444
"civisibility.ciprovider.integration.enabled";
4545
public static final String CIVISIBILITY_REPO_INDEX_DUPLICATE_KEY_CHECK_ENABLED =
4646
"civisibility.repo.index.duplicate.key.check.enabled";
47+
public static final String CIVISIBILITY_REPO_INDEX_FOLLOW_SYMLINKS =
48+
"civisibility.repo.index.follow.symlinks";
4749
public static final String CIVISIBILITY_EXECUTION_SETTINGS_CACHE_SIZE =
4850
"civisibility.execution.settings.cache.size";
4951
public static final String CIVISIBILITY_JVM_INFO_CACHE_SIZE = "civisibility.jvm.info.cache.size";

internal-api/src/main/java/datadog/trace/api/Config.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@
254254
import static datadog.trace.api.config.CiVisibilityConfig.CIVISIBILITY_REMOTE_ENV_VARS_PROVIDER_KEY;
255255
import static datadog.trace.api.config.CiVisibilityConfig.CIVISIBILITY_REMOTE_ENV_VARS_PROVIDER_URL;
256256
import static datadog.trace.api.config.CiVisibilityConfig.CIVISIBILITY_REPO_INDEX_DUPLICATE_KEY_CHECK_ENABLED;
257+
import static datadog.trace.api.config.CiVisibilityConfig.CIVISIBILITY_REPO_INDEX_FOLLOW_SYMLINKS;
257258
import static datadog.trace.api.config.CiVisibilityConfig.CIVISIBILITY_RESOURCE_FOLDER_NAMES;
258259
import static datadog.trace.api.config.CiVisibilityConfig.CIVISIBILITY_RUM_FLUSH_WAIT_MILLIS;
259260
import static datadog.trace.api.config.CiVisibilityConfig.CIVISIBILITY_SCALATEST_FORK_MONITOR_ENABLED;
@@ -1001,6 +1002,7 @@ public static String getHostName() {
10011002
private final boolean ciVisibilityTestSkippingEnabled;
10021003
private final boolean ciVisibilityCiProviderIntegrationEnabled;
10031004
private final boolean ciVisibilityRepoIndexDuplicateKeyCheckEnabled;
1005+
private final boolean ciVisibilityRepoIndexFollowSymlinks;
10041006
private final int ciVisibilityExecutionSettingsCacheSize;
10051007
private final int ciVisibilityJvmInfoCacheSize;
10061008
private final int ciVisibilityCoverageRootPackagesLimit;
@@ -2261,6 +2263,8 @@ PROFILING_DATADOG_PROFILER_ENABLED, isDatadogProfilerSafeInCurrentEnvironment())
22612263
configProvider.getBoolean(CIVISIBILITY_CIPROVIDER_INTEGRATION_ENABLED, true);
22622264
ciVisibilityRepoIndexDuplicateKeyCheckEnabled =
22632265
configProvider.getBoolean(CIVISIBILITY_REPO_INDEX_DUPLICATE_KEY_CHECK_ENABLED, true);
2266+
ciVisibilityRepoIndexFollowSymlinks =
2267+
configProvider.getBoolean(CIVISIBILITY_REPO_INDEX_FOLLOW_SYMLINKS, false);
22642268
ciVisibilityExecutionSettingsCacheSize =
22652269
configProvider.getInteger(CIVISIBILITY_EXECUTION_SETTINGS_CACHE_SIZE, 16);
22662270
ciVisibilityJvmInfoCacheSize = configProvider.getInteger(CIVISIBILITY_JVM_INFO_CACHE_SIZE, 8);
@@ -3822,6 +3826,10 @@ public boolean isCiVisibilityRepoIndexDuplicateKeyCheckEnabled() {
38223826
return ciVisibilityRepoIndexDuplicateKeyCheckEnabled;
38233827
}
38243828

3829+
public boolean isCiVisibilityRepoIndexFollowSymlinks() {
3830+
return ciVisibilityRepoIndexFollowSymlinks;
3831+
}
3832+
38253833
public int getCiVisibilityExecutionSettingsCacheSize() {
38263834
return ciVisibilityExecutionSettingsCacheSize;
38273835
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package datadog.trace.api.telemetry;
2+
3+
import java.util.ArrayList;
4+
import java.util.Collection;
5+
import java.util.Collections;
6+
import java.util.List;
7+
import java.util.concurrent.ArrayBlockingQueue;
8+
import java.util.concurrent.BlockingQueue;
9+
import org.slf4j.Logger;
10+
import org.slf4j.LoggerFactory;
11+
12+
public class ConfigInversionMetricCollector
13+
implements MetricCollector<ConfigInversionMetricCollector.ConfigInversionMetric> {
14+
private static final Logger log = LoggerFactory.getLogger(ConfigInversionMetricCollector.class);
15+
private static final String CONFIG_INVERSION_KEY_TAG = "config_name:";
16+
private static final String CONFIG_INVERSION_METRIC_NAME = "untracked.config.detected";
17+
private static final String NAMESPACE = "tracers";
18+
private static final ConfigInversionMetricCollector INSTANCE =
19+
new ConfigInversionMetricCollector();
20+
21+
private final BlockingQueue<ConfigInversionMetricCollector.ConfigInversionMetric> metricsQueue;
22+
23+
private ConfigInversionMetricCollector() {
24+
this.metricsQueue = new ArrayBlockingQueue<>(RAW_QUEUE_SIZE);
25+
}
26+
27+
public static ConfigInversionMetricCollector getInstance() {
28+
return INSTANCE;
29+
}
30+
31+
public void setUndocumentedEnvVarMetric(String configName) {
32+
setMetricConfigInversionMetric(CONFIG_INVERSION_KEY_TAG + configName);
33+
}
34+
35+
private void setMetricConfigInversionMetric(final String... tags) {
36+
if (!metricsQueue.offer(
37+
new ConfigInversionMetricCollector.ConfigInversionMetric(
38+
NAMESPACE, true, CONFIG_INVERSION_METRIC_NAME, "count", 1, tags))) {
39+
log.debug("Unable to add telemetry metric {} for {}", CONFIG_INVERSION_METRIC_NAME, tags[0]);
40+
}
41+
}
42+
43+
@Override
44+
public void prepareMetrics() {
45+
// Nothing to do here
46+
}
47+
48+
@Override
49+
public Collection<ConfigInversionMetricCollector.ConfigInversionMetric> drain() {
50+
if (this.metricsQueue.isEmpty()) {
51+
return Collections.emptyList();
52+
}
53+
List<ConfigInversionMetricCollector.ConfigInversionMetric> drained =
54+
new ArrayList<>(this.metricsQueue.size());
55+
this.metricsQueue.drainTo(drained);
56+
return drained;
57+
}
58+
59+
public static class ConfigInversionMetric extends MetricCollector.Metric {
60+
public ConfigInversionMetric(
61+
String namespace,
62+
boolean common,
63+
String metricName,
64+
String type,
65+
Number value,
66+
final String... tags) {
67+
super(namespace, common, metricName, type, value, tags);
68+
}
69+
}
70+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package datadog.trace.api.telemetry
2+
3+
import datadog.trace.test.util.DDSpecification
4+
5+
import static datadog.trace.api.telemetry.ConfigInversionMetricCollector.CONFIG_INVERSION_METRIC_NAME
6+
7+
class ConfigInversionMetricCollectorTest extends DDSpecification {
8+
9+
def "should emit metric when unsupported env var is used"() {
10+
setup:
11+
def collector = ConfigInversionMetricCollector.getInstance()
12+
13+
when:
14+
ConfigInversionMetricCollectorTestHelper.checkAndEmitUnsupported("DD_UNKNOWN_FEATURE")
15+
collector.prepareMetrics()
16+
def metrics = collector.drain()
17+
18+
then:
19+
metrics.size() == 1
20+
def metric = metrics[0]
21+
metric.type == 'count'
22+
metric.value == 1
23+
metric.namespace == 'tracers'
24+
metric.metricName == CONFIG_INVERSION_METRIC_NAME
25+
metric.tags.size() == 1
26+
metric.tags[0] == 'config_name:DD_UNKNOWN_FEATURE'
27+
}
28+
29+
def "should not emit metric when supported env var is used"() {
30+
setup:
31+
def collector = ConfigInversionMetricCollector.getInstance()
32+
33+
when:
34+
ConfigInversionMetricCollectorTestHelper.checkAndEmitUnsupported("DD_ENV")
35+
collector.prepareMetrics()
36+
def metrics = collector.drain()
37+
38+
then:
39+
metrics.isEmpty()
40+
}
41+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package datadog.trace.api.telemetry;
2+
3+
import java.util.Arrays;
4+
import java.util.HashSet;
5+
import java.util.Set;
6+
7+
// Lightweight helper class to simulate Config Inversion ConfigHelper scenario where telemetry
8+
// metrics are emitted for "unknown" environment variables.
9+
public class ConfigInversionMetricCollectorTestHelper {
10+
private static final Set<String> SUPPORTED_ENV_VARS =
11+
new HashSet<>(Arrays.asList("DD_ENV", "DD_SERVICE"));
12+
13+
private static final ConfigInversionMetricCollector configInversionMetricCollector =
14+
ConfigInversionMetricCollector.getInstance();
15+
16+
public static void checkAndEmitUnsupported(String envVarName) {
17+
if (!SUPPORTED_ENV_VARS.contains(envVarName)) {
18+
configInversionMetricCollector.setUndocumentedEnvVarMetric(envVarName);
19+
}
20+
}
21+
}

telemetry/src/main/java/datadog/telemetry/TelemetryRequestBody.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ public void writeEndpoint(final Endpoint endpoint) throws IOException {
329329
bodyWriter.name("operation_name").value(endpoint.getOperation());
330330
bodyWriter.name("resource_name").value(endpoint.getResource());
331331
if (endpoint.getRequestBodyType() != null) {
332-
bodyWriter.name("request-body-type").jsonValue(endpoint.getRequestBodyType());
332+
bodyWriter.name("request_body_type").jsonValue(endpoint.getRequestBodyType());
333333
}
334334
if (endpoint.getResponseBodyType() != null) {
335335
bodyWriter.name("response_body_type").jsonValue(endpoint.getResponseBodyType());

telemetry/src/main/java/datadog/telemetry/TelemetrySystem.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import datadog.telemetry.integration.IntegrationPeriodicAction;
1111
import datadog.telemetry.log.LogPeriodicAction;
1212
import datadog.telemetry.metric.CiVisibilityMetricPeriodicAction;
13+
import datadog.telemetry.metric.ConfigInversionMetricPeriodicAction;
1314
import datadog.telemetry.metric.CoreMetricsPeriodicAction;
1415
import datadog.telemetry.metric.IastMetricPeriodicAction;
1516
import datadog.telemetry.metric.OtelEnvMetricPeriodicAction;
@@ -51,6 +52,7 @@ static Thread createTelemetryRunnable(
5152
if (telemetryMetricsEnabled) {
5253
actions.add(new CoreMetricsPeriodicAction());
5354
actions.add(new OtelEnvMetricPeriodicAction());
55+
actions.add(new ConfigInversionMetricPeriodicAction());
5456
actions.add(new IntegrationPeriodicAction());
5557
actions.add(new WafMetricPeriodicAction());
5658
if (Verbosity.OFF != Config.get().getIastTelemetryVerbosity()) {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package datadog.telemetry.metric;
2+
3+
import datadog.trace.api.telemetry.ConfigInversionMetricCollector;
4+
import datadog.trace.api.telemetry.MetricCollector;
5+
import edu.umd.cs.findbugs.annotations.NonNull;
6+
7+
public class ConfigInversionMetricPeriodicAction extends MetricPeriodicAction {
8+
@Override
9+
@NonNull
10+
public MetricCollector collector() {
11+
return ConfigInversionMetricCollector.getInstance();
12+
}
13+
}

0 commit comments

Comments
 (0)