Skip to content

Commit 952f264

Browse files
authored
Merge pull request #2153 from digma-ai/extended-observability-experiment
extended-observability-experiment
2 parents c968580 + a26835f commit 952f264

File tree

13 files changed

+188
-20
lines changed

13 files changed

+188
-20
lines changed

build.gradle.kts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,18 @@ tasks {
249249
"org.digma.plugin.enable.devtools" to "true",
250250

251251
// "idea.ProcessCanceledException" to "disabled"
252+
253+
254+
//to use a local file for digma-agent or digma extension,
255+
// usually when developing and we want to test the plugin
256+
//see org.digma.intellij.plugin.idea.execution.OtelAgentPathProvider
257+
//don't forget to comment when done testing !
258+
//"digma.agent.override.path" to "/home/shalom/workspace/digma/digma-agent/build/libs/digma-agent-1.0.10-SNAPSHOT.jar"
259+
//"digma.otel.extension.override.path" to "/home/shalom/workspace/digma/otel-java-instrumentation/agent-extension/build/libs/digma-otel-agent-extension-0.8.12.jar"
260+
//can also change the url from where the jar is downloaded when IDE starts
261+
//"org.digma.otel.extensionUrl" to "some url
262+
//"org.digma.otel.digmaAgentUrl" to "some url
263+
252264
)
253265

254266

ide-common/src/main/java/org/digma/intellij/plugin/settings/ProjectSettings.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ public boolean isModified() {
4646
isJaegerLinkModeChanged(settings) ||
4747
isSpringBootObservabilityModeChanged(settings) ||
4848
isRuntimeObservabilityBackendUrlChanged(settings) ||
49-
isExtendedObservabilityChanged(settings);
49+
isExtendedObservabilityChanged(settings) ||
50+
isExtendedObservabilityExcludeChanged(settings);
5051
}
5152

5253
private boolean isRefreshDelayChanged(SettingsState settings) {
@@ -85,6 +86,10 @@ private boolean isExtendedObservabilityChanged(SettingsState settings) {
8586
return !Objects.equals(settings.extendedObservability, mySettingsComponent.getExtendedObservability());
8687
}
8788

89+
private boolean isExtendedObservabilityExcludeChanged(SettingsState settings) {
90+
return !Objects.equals(settings.extendedObservabilityExcludes, mySettingsComponent.getExtendedObservabilityExclude());
91+
}
92+
8893
@Override
8994
public void apply() throws ConfigurationException {
9095
SettingsState settings = SettingsState.getInstance();
@@ -149,6 +154,7 @@ public void apply() throws ConfigurationException {
149154
settings.springBootObservabilityMode = mySettingsComponent.getSpringBootObservabilityMode();
150155
settings.runtimeObservabilityBackendUrl = mySettingsComponent.getRuntimeObservabilityBackendUrl();
151156
settings.extendedObservability = mySettingsComponent.getExtendedObservability();
157+
settings.extendedObservabilityExcludes = mySettingsComponent.getExtendedObservabilityExclude();
152158
settings.fireChanged();
153159
}
154160

@@ -164,6 +170,7 @@ public void reset() {
164170
mySettingsComponent.setSpringBootObservabilityMode(settings.springBootObservabilityMode);
165171
mySettingsComponent.setRuntimeObservabilityBackendUrl(settings.runtimeObservabilityBackendUrl);
166172
mySettingsComponent.setExtendedObservability(settings.extendedObservability);
173+
mySettingsComponent.setExtendedObservabilityExclude(settings.extendedObservabilityExcludes);
167174
}
168175

169176

ide-common/src/main/java/org/digma/intellij/plugin/settings/SettingsComponent.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,14 @@ public class SettingsComponent {
3030
private final JBLabel myRuntimeObservabilityBackendUrlLabel = new JBLabel("Runtime observability backend URL:");
3131
private final JBTextField myRuntimeObservabilityBackendUrlText = new JBTextField();
3232
private final JBTextField extendedObservabilityTextBox = new JBTextField();
33+
private final JBTextField extendedObservabilityExcludeTextBox = new JBTextField();
3334

3435
public SettingsComponent() {
3536

37+
extendedObservabilityTextBox.setToolTipText("packages names in format 'my.pkg1;my.pkg2");
38+
extendedObservabilityExcludeTextBox.setToolTipText("class/method names to exclude in format 'MyClass;MyOtherClass.myOtherMethod;*get");
39+
40+
3641
var defaultLabelForeground = JBColor.foreground();
3742

3843
var myUrlLabel = new JBLabel("Digma API URL: ");
@@ -156,6 +161,7 @@ public boolean verify(JComponent input) {
156161
.addLabeledComponent(mySpringBootObservabilityModeLabel, mySpringBootObservabilityModeComboBox, 1, false)
157162
.addLabeledComponent(myRuntimeObservabilityBackendUrlLabel, myRuntimeObservabilityBackendUrlText, 1, false)
158163
.addLabeledComponent("Extended Observability (beta)", extendedObservabilityTextBox, 1, false)
164+
.addLabeledComponent("Extended Observability Exclude (beta)", extendedObservabilityExcludeTextBox, 1, false)
159165
.addComponent(resetButton)
160166
.addComponentFillVertically(new JPanel(), 0)
161167
.getPanel();
@@ -278,6 +284,16 @@ public String getExtendedObservability() {
278284
return extendedObservabilityTextBox.getText();
279285
}
280286

287+
public void setExtendedObservabilityExclude(@Nullable String extendedObservabilityExclude) {
288+
extendedObservabilityExcludeTextBox.setText(extendedObservabilityExclude);
289+
}
290+
291+
@Nullable
292+
public String getExtendedObservabilityExclude() {
293+
return extendedObservabilityExcludeTextBox.getText();
294+
}
295+
296+
281297
private void resetToDefaults() {
282298
this.setApiUrlText(SettingsState.DEFAULT_API_URL);
283299
this.setApiToken(null);
@@ -289,5 +305,6 @@ private void resetToDefaults() {
289305
this.setSpringBootObservabilityMode(SettingsState.DEFAULT_SPRING_BOOT_OBSERVABILITY_MODE);
290306
this.setRuntimeObservabilityBackendUrl(SettingsState.DEFAULT_RUNTIME_OBSERVABILITY_BACKEND_URL);
291307
this.setExtendedObservability(null);
308+
this.setExtendedObservabilityExclude(null);
292309
}
293310
}

ide-common/src/main/java/org/digma/intellij/plugin/settings/SettingsState.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ public class SettingsState implements PersistentStateComponent<SettingsState>, D
5151
public String posthogToken;
5252
@Nullable
5353
public String extendedObservability;
54+
@Nullable
55+
public String extendedObservabilityExcludes;
5456

5557

5658
private final List<SettingsChangeListener> listeners = new ArrayList<>();

ide-common/src/main/kotlin/org/digma/intellij/plugin/posthog/SettingsChangeTracker.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class SettingsChangeTracker {
7777
myTrackedSettings["refreshDelay"] = SettingsState.getInstance().refreshDelay.toString()
7878
myTrackedSettings["springBootObservabilityMode"] = SettingsState.getInstance().springBootObservabilityMode.name
7979
myTrackedSettings["extendedObservability"] = SettingsState.getInstance().extendedObservability.toString()
80+
myTrackedSettings["extendedObservabilityExcludes"] = SettingsState.getInstance().extendedObservabilityExcludes.toString()
8081
}
8182

8283

jvm-common/build.gradle.kts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,29 @@ tasks {
3939
src(
4040
listOf(
4141
properties.getProperty("otel-agent"),
42-
properties.getProperty("digma-extension")
42+
properties.getProperty("digma-extension"),
43+
properties.getProperty("digma-agent")
4344
)
4445
)
4546

46-
logger.lifecycle("copying jars $properties")
47+
logger.lifecycle("jars to download $properties")
4748

4849
dest(File(project.sourceSets.main.get().output.resourcesDir, "otelJars"))
4950
overwrite(true)
51+
//if a jar is downloaded with version then its name needs to change. it may happen
52+
// in development if the url for some of the jars is changed to download from somewhere else.
53+
//usually latest jar is downloaded without version
54+
eachFile {
55+
name = if (name.startsWith("digma-otel-agent-extension", true)) {
56+
"digma-otel-agent-extension.jar"
57+
} else if (name.startsWith("digma-agent", true)) {
58+
"digma-agent.jar"
59+
} else if (name.startsWith("opentelemetry-javaagent", true)) {
60+
"opentelemetry-javaagent.jar"
61+
} else {
62+
name
63+
}
64+
}
5065
}
5166

5267
processResources {

jvm-common/src/main/kotlin/org/digma/intellij/plugin/idea/execution/JavaParametersMerger.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,10 @@ open class JavaParametersMerger(
9595
protected fun smartMergeJavaToolOptions(myJavaToolOptions: String, currentJavaToolOptions: String): String {
9696

9797
//merge two java tool options strings. values from myJavaToolOptions override values from currentJavaToolOptions
98+
//we want to preserve the order , existing java tool options properties should be first
9899

99-
val myOptions = javaToolOptionsToMap(myJavaToolOptions)
100100
val currentOptions = javaToolOptionsToMap(currentJavaToolOptions)
101+
val myOptions = javaToolOptionsToMap(myJavaToolOptions)
101102

102103
val result = mutableMapOf<String, String?>()
103104
result.putAll(currentOptions)

jvm-common/src/main/kotlin/org/digma/intellij/plugin/idea/execution/JavaToolOptionsBuilder.kt

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ open class JavaToolOptionsBuilder(
1414

1515
private val otelAgentPathProvider = OtelAgentPathProvider(configuration)
1616

17+
@Suppress("MemberVisibilityCanBePrivate")
1718
protected val javaToolOptions = StringBuilder(" ")
1819

1920

@@ -39,12 +40,29 @@ open class JavaToolOptionsBuilder(
3940
}
4041

4142

42-
open fun withOtelAgent(useAgent: Boolean): JavaToolOptionsBuilder {
43+
open fun withOtelAgent(useAgent: Boolean, parametersExtractor: ParametersExtractor): JavaToolOptionsBuilder {
4344

4445
if (useAgent) {
46+
4547
if (!otelAgentPathProvider.hasAgentPath()) {
46-
throw JavaToolOptionsBuilderException("useAgent is true but can't find agent paths")
48+
throw JavaToolOptionsBuilderException("useAgent is true but can't find agent or extension paths")
49+
}
50+
51+
if (isExtendedObservabilityConfigured()) {
52+
53+
if (!otelAgentPathProvider.hasDigmaAgentPath()) {
54+
throw JavaToolOptionsBuilderException("can't find digma-agent path")
55+
}
56+
57+
javaToolOptions
58+
.append("-javaagent:${otelAgentPathProvider.digmaAgentPath}")
59+
.append(" ")
60+
61+
withDigmaAgentDebug()
62+
63+
4764
}
65+
4866
javaToolOptions
4967
.append("-javaagent:${otelAgentPathProvider.otelAgentPath}")
5068
.append(" ")
@@ -141,12 +159,33 @@ open class JavaToolOptionsBuilder(
141159
}
142160

143161

162+
open fun withDigmaAgentDebug(): JavaToolOptionsBuilder {
163+
if (java.lang.Boolean.getBoolean("digma.agent.debug") ||
164+
java.lang.Boolean.valueOf(System.getenv("DIGMA_AGENT_DEBUG"))
165+
) {
166+
javaToolOptions
167+
.append("-Ddigma.agent.debug=true")
168+
.append(" ")
169+
}
170+
return this
171+
}
172+
173+
144174
open fun withExtendedObservability(): JavaToolOptionsBuilder {
145-
if (!SettingsState.getInstance().extendedObservability.isNullOrBlank()) {
175+
176+
if (isExtendedObservabilityConfigured()) {
177+
146178
javaToolOptions
147179
.append("-Ddigma.autoinstrument.packages=${SettingsState.getInstance().extendedObservability}")
148180
.append(" ")
181+
182+
if (!SettingsState.getInstance().extendedObservabilityExcludes.isNullOrBlank()) {
183+
javaToolOptions
184+
.append("-Ddigma.autoinstrument.packages.exclude.names=${SettingsState.getInstance().extendedObservabilityExcludes}")
185+
.append(" ")
186+
}
149187
}
188+
150189
return this
151190
}
152191

@@ -254,14 +293,34 @@ open class JavaToolOptionsBuilder(
254293

255294

256295
open fun build(): String {
296+
297+
//always disable extended observability extension because we changed to digma-agent
298+
disableExtendedObservabilityExtension()
299+
257300
return javaToolOptions.toString()
258301
}
259302

260303

304+
private fun disableExtendedObservabilityExtension() {
305+
//todo: need to disable the extended observability extension completely in the otel agent extension
306+
// project after some time that we use digma-agent and all users upgraded the plugin.
307+
// can't disable it yet because some users may still use older version of the plugin and are using extended observability.
308+
javaToolOptions
309+
.append("-Dotel.instrumentation.digma-methods.enabled=false")
310+
.append(" ")
311+
}
312+
313+
261314
open fun getExporterUrl(): String {
262315
return SettingsState.getInstance().runtimeObservabilityBackendUrl
263316
}
264317

318+
319+
@Suppress("MemberVisibilityCanBePrivate")
320+
fun isExtendedObservabilityConfigured(): Boolean {
321+
return !SettingsState.getInstance().extendedObservability.isNullOrBlank()
322+
}
323+
265324
}
266325

267326

jvm-common/src/main/kotlin/org/digma/intellij/plugin/idea/execution/OTELJarProvider.kt

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,27 @@ private const val RESOURCE_LOCATION = "otelJars"
1717

1818
private const val OTEL_AGENT_JAR_PROP_NAME = "otel-agent"
1919
private const val DIGMA_EXTENSION_JAR_PROP_NAME = "digma-extension"
20+
private const val DIGMA_AGENT_JAR_PROP_NAME = "digma-agent"
2021
private const val OTEL_AGENT_JAR_NAME = "opentelemetry-javaagent.jar"
2122
private const val DIGMA_AGENT_EXTENSION_JAR_NAME = "digma-otel-agent-extension.jar"
22-
23+
private const val DIGMA_AGENT_JAR_NAME = "digma-agent.jar"
24+
25+
26+
/**
27+
* Downloads and provides the instrumentation jars.
28+
*
29+
* jars urls and path may be overridden for development to another download url or a local path,
30+
* for example when developing the digma-agent or otel extension.
31+
* system properties can be injected in runIde task or in idea custom properties.
32+
*
33+
* to override the download url see the method tryDownloadLatest, it will try to get the url from system
34+
* property if exists. this is useful for example for downloading a different version of some of the jars.
35+
*
36+
* to override the final path see org.digma.intellij.plugin.idea.execution.OtelAgentPathProvider, it will
37+
* first check if system property exists and use it instead of the default. this is useful when developing
38+
* the digma agent or otel extension and you want to use the local build jar.
39+
*
40+
*/
2341

2442
//Do not change to light service because it will always register.
2543
// we want it to register only in Idea.
@@ -63,9 +81,9 @@ class OTELJarProvider {
6381

6482
fun getDigmaAgentExtensionJarPath(): String? {
6583
ensureFilesExist()
66-
val digmaJar = getDigmaAgentExtensionJar()
67-
if (digmaJar.exists()) {
68-
return digmaJar.absolutePath
84+
val digmaExtensionJar = getDigmaAgentExtensionJar()
85+
if (digmaExtensionJar.exists()) {
86+
return digmaExtensionJar.absolutePath
6987
}
7088
return null
7189
}
@@ -74,6 +92,19 @@ class OTELJarProvider {
7492
return File(downloadDir, DIGMA_AGENT_EXTENSION_JAR_NAME)
7593
}
7694

95+
fun getDigmaAgentJarPath(): String? {
96+
ensureFilesExist()
97+
val digmaAgentJar = getDigmaAgentJar()
98+
if (digmaAgentJar.exists()) {
99+
return digmaAgentJar.absolutePath
100+
}
101+
return null
102+
}
103+
104+
private fun getDigmaAgentJar(): File {
105+
return File(downloadDir, DIGMA_AGENT_JAR_NAME)
106+
}
107+
77108

78109
private fun ensureFilesExist() {
79110

@@ -89,8 +120,9 @@ class OTELJarProvider {
89120

90121
private fun filesExist(): Boolean {
91122
val otelJar = getOtelAgentJar()
92-
val digmaJar = getDigmaAgentExtensionJar()
93-
return otelJar.exists() && digmaJar.exists()
123+
val digmaExtensionJar = getDigmaAgentExtensionJar()
124+
val digmaAgentJar = getDigmaAgentJar()
125+
return otelJar.exists() && digmaExtensionJar.exists() && digmaAgentJar.exists()
94126
}
95127

96128

@@ -109,6 +141,7 @@ class OTELJarProvider {
109141
if (downloadDir.exists()) {
110142
copyFileFromResource(OTEL_AGENT_JAR_NAME)
111143
copyFileFromResource(DIGMA_AGENT_EXTENSION_JAR_NAME)
144+
copyFileFromResource(DIGMA_AGENT_JAR_NAME)
112145
Log.log(logger::info, "otel agent jars unpacked to {}", downloadDir)
113146
}
114147
} catch (e: Exception) {
@@ -143,9 +176,11 @@ class OTELJarProvider {
143176
try {
144177
val otelUrl = System.getProperty("org.digma.otel.agentUrl", jarsUrls.getProperty(OTEL_AGENT_JAR_PROP_NAME))
145178
val extensionUrl = System.getProperty("org.digma.otel.extensionUrl", jarsUrls.getProperty(DIGMA_EXTENSION_JAR_PROP_NAME))
179+
val digmaAgentUrl = System.getProperty("org.digma.otel.digmaAgentUrl", jarsUrls.getProperty(DIGMA_AGENT_JAR_PROP_NAME))
146180

147181
downloadAndCopyJar(URL(otelUrl), getOtelAgentJar())
148182
downloadAndCopyJar(URL(extensionUrl), getDigmaAgentExtensionJar())
183+
downloadAndCopyJar(URL(digmaAgentUrl), getDigmaAgentJar())
149184
} catch (e: Exception) {
150185
Log.warnWithException(logger, e, "could not download latest otel jars")
151186
}

0 commit comments

Comments
 (0)