open-telemetry / opentelemetry-java-instrumentation

OpenTelemetry auto-instrumentation and instrumentation libraries for Java
https://opentelemetry.io
Apache License 2.0
1.87k stars 819 forks source link

Adobe ColdFusion trace support #10690

Open ghedwards opened 6 months ago

ghedwards commented 6 months ago

Is your feature request related to a problem? Please describe.

Adobe ColdFusion trace support

Describe the solution you'd like

Adobe ColdFusion trace support

Describe alternatives you've considered

No response

Additional context

No response

steverao commented 6 months ago

Sorry, I am not familiar with the framework you mentioned above. Is it a commercial software? Can you provide relevant introduction materials?

ghedwards commented 6 months ago

hi @steverao , ColdFusion is a server with a CFML / CFSCRIPT language built on top of Java / JSP ( I believe? ) ColdFusion is owned by Adobe https://www.adobe.com/au/products/coldfusion-family.html how ever there is also an opensource alternative https://www.lucee.org/

I made an attempt at implementing something in glowroot https://github.com/glowroot/glowroot/issues/1056 but I have limited experience in this space, happy to continue this conversation and provide assistance if it might result in some level of support.

steverao commented 6 months ago

hi @steverao , ColdFusion is a server with a CFML / CFSCRIPT language built on top of Java / JSP ( I believe? ) ColdFusion is owned by Adobe https://www.adobe.com/au/products/coldfusion-family.html how ever there is also an opensource alternative https://www.lucee.org/

I made an attempt at implementing something in glowroot glowroot/glowroot#1056 but I have limited experience in this space, happy to continue this conversation and provide assistance if it might result in some level of support.

Thank you for your response! This is relevant open source repo and document of Lucee:

What's your comment about it? @laurit

ghedwards commented 6 months ago

@steverao I believe the internal architecture of Lucee is likely to be a bit different to Adobe's ColdFusion product, but the principles are similar ( I believe ? ) and the languages are fairly compatible with each other.

laurit commented 6 months ago

We'd welcome a contribution for this

ghedwards commented 6 months ago

Any tips on getting started ?

laurit commented 6 months ago

I'd start by figuring out how to attach the agent and verifying that the agent works at all. https://helpx.adobe.com/coldfusion/installing/installing-the-server-configuration.html indicates that it might be using tomcat, if that is so then perhaps our tomcat and servlet instrumentations will already work and produce a SERVER span. If it so then you'll need to consider what else you wish to do? Perhaps set a better http.route?

ghedwards commented 6 months ago

It does work, I just want better routes and some better tracing

laurit commented 6 months ago

It does work, I just want better routes and some better tracing

First you need to figure out what would be an appropriate route for the framework at hand and then how to get access to it. Route is update by calling update method in https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/semconv/http/HttpServerRoute.java HttpServerRouteSource parameter is usually set to CONTROLLER.

ghedwards commented 6 months ago

Thanks, I've made a start based on research I had done for Glowroot instrumentation but its early days and I had issues compiling the project, something about Java 17 only libs. Documentation on internals of the Adobe CF engine are super sparse, here's a link to my branch and some additional resources for reference

https://github.com/cfmleditor/opentelemetry-java-instrumentation/tree/cfml-instrumentation

https://github.com/markmandel/JavaLoader/blob/develop/java/cfcdynamicproxy/src/com/compoundtheory/coldfusion/cfc/CFCDynamicProxy.java https://github.com/cfmleditor/glowroot/tree/cfmlplugin

garethedwards-tass commented 4 months ago

@laurit @steverao I've got something that I believe should be creating spans, but I'm missing something and I'm not sure how to fix it https://github.com/cfmleditor/opentelemetry-java-instrumentation/tree/cfml-instrumentation any advice would be appreciated.

laurit commented 4 months ago

@garethedwards-tass I'd start by commenting out all the instrumentation code you have. Firstly start with an advice that prints a line or stack trace when the method is called that you wish to instrument. Try it out and verify that you can see that line/stacktrace. If you can get the simple advice working you can start doing more complicated thins like creating the span. Now try modifying you simple advice and add the logic that creates the span, but don't remove what you initially had in the advice. Try it out and verify that you still can see the line that the advice prints. If you see if, then check whether you also can see the span wherever you sent it. If you don't then turn on debug logging with -Dotel.javaagent.debug=true and search for warnings and errors. Most likely you'll see a warning that your instrumentation could not be applied because io.cfmleditor.javaagent.HttpCfmlPageInstrumentationSingletons could not be found. If that is the case then see https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/docs/contributing/writing-instrumentation-module.md#tell-the-agent-which-classes-are-a-part-of-the-instrumentation-by-overriding-the-ishelperclass-method you'll have to implement the isHelperClass method. You have commented out https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/bc5e0329103331b712684916664f586e8d9fe99b/examples/extension/build.gradle#L117-L120 this may also inhibit using helper classes in your instrumentation.

ghedwards commented 4 months ago

@laurit sorry, switching between home and work accounts, I think this is a little beyond me, I've been playing with Glowroot instrumentation via the configurations built into the tool and I get get it recognizing the class load in question, I just can't get it working in open telemetry, and I don't understand why. I could try share what I've got in Glowroot if its of any consequence?

ghedwards commented 4 months ago
image image
ghedwards commented 4 months ago

@laurit could we try organise a date / time to have a quick chat about this stuff ?

trask commented 3 months ago

@ghedwards are you able to join the weekly Java SIG meeting Thursdays at 9am Pacific Time? (I will be missing this week, so maybe the week after?)

ghedwards commented 3 months ago

@trask I can certainly try, it will be 2am for me though.

laurit commented 3 months ago

@ghedwards I doubt that we'll be able to help you much at the SIG meeting. An alternative approach you could consider is setting up something that would allow as easily run your extension and see why exactly it fails. There seems to be a docker images for coldfusion perhaps this could be used to build a reproducer? Or perhaps there is a freely downloadable version for which you could provide instructions on where to get it and how to test your extension with it.

ghedwards commented 3 months ago

@laurit @trask

Command Box is probably the easiest way to setup a dev instance, for someone who hasn't touched ColdFusion before https://www.ortussolutions.com/products/commandbox#overview , but you do have to be a bit careful you're grabbing the appropriate CF distro and that you can setup the JVM settings appropriately. I can try help with this if its something you're interested in pursuing.

I prefer the standalone versions from Adobe ( stand alone web server with the installer if you're willing ), requires a little bit of contact information, but the 30 day "trial" can be installed as a dev version that just restricts connections https://www.adobe.com/au/products/coldfusion/download-trial/try.html then its just a matter of finding and modifying the jvm.config and restarting the service.

ghedwards commented 3 months ago

@trask @laurit if we can setup a more private channel for communication I can see if I can get an AWS / EC2 instance for you to help test ?

laurit commented 3 months ago

Feel free to provide instructions for whichever is easier.

ghedwards commented 3 months ago

https://github.com/cfmleditor/awesome-cf-compose/tree/otel-agent/cf-2021-with-otel

Once up and running you should be able to run http://localhost:8500/CFIDE/administrator/ to start logging traces

laurit commented 3 months ago

Firstly in https://github.com/cfmleditor/awesome-cf-compose/blob/5c9445635f5374c23ed109420a0dbb6292546140/cf-2021-with-otel/agent/config.properties#L1 you are pointing to cfmleditor-cfmlpage-instrumentation-1.0-all.jar but the extension jar is really named cfmleditor-cfmlpage-instrumentation-1.0.jar (the -all file in the same extension shades some additional jars into the extension that you don't need). I changed the config file to match the actual file name. Secondly the extension jar seems to be incomplete it is missing the instrumentation module class and the SPI file, I rebuilt it from https://github.com/cfmleditor/opentelemetry-java-instrumentation/blob/cfml-instrumentation/examples/cfml/. That does not compile because missing import for ElementMatcher in https://github.com/cfmleditor/opentelemetry-java-instrumentation/blob/fa31401d45157020a290fa1cd38176f52d5704f8/examples/cfml/src/main/java/io/cfmleditor/javaagent/HttpCfmlPageInstrumentationModule.java#L26 I removed that method, you don't need it. I enabled debug logging by adding -Dio.opentelemetry.javaagent.slf4j.simpleLogger.logFile=/tmp/agent.log -Dotel.javaagent.debug=true to https://github.com/cfmleditor/awesome-cf-compose/blob/5c9445635f5374c23ed109420a0dbb6292546140/cf-2021-with-otel/docker-compose.yaml#L68 Now when running the application the log file contains

[otel.javaagent 2024-05-03 12:26:25:491 +0000] [http-nio-8500-exec-1] WARN io.opentelemetry.javaagent.tooling.instrumentation.MuzzleMatcher - Instrumentation skipped, mismatched references were found: acf [class io.cfmleditor.javaagent.HttpCfmlPageInstrumentationModule] o
n coldfusion.bootstrap.BootstrapClassLoader@b791e6e
[otel.javaagent 2024-05-03 12:26:25:492 +0000] [http-nio-8500-exec-1] WARN io.opentelemetry.javaagent.tooling.instrumentation.MuzzleMatcher - -- io.cfmleditor.javaagent.HttpCfmlPageInstrumentation$CfJspPageAdvice:50 Missing class io.cfmleditor.javaagent.HttpCfmlPageInstru
mentationSingletons

This can be fixed by adding

  @Override
  public boolean isHelperClass(String className) {
    return className.startsWith("io.cfmleditor.javaagent");
  }

to HttpCfmlPageInstrumentationModule. You'll also have to do something like

diff --git a/examples/cfml/src/main/java/io/cfmleditor/javaagent/HttpCfmlPageInstrumentation.java b/examples/cfml/src/main/java/io/cfmleditor/javaagent/HttpCfmlPageInstrumentation.java
index 2f894d055c..330c007858 100644
--- a/examples/cfml/src/main/java/io/cfmleditor/javaagent/HttpCfmlPageInstrumentation.java
+++ b/examples/cfml/src/main/java/io/cfmleditor/javaagent/HttpCfmlPageInstrumentation.java
@@ -46,11 +46,14 @@ public class HttpCfmlPageInstrumentation implements TypeInstrumentation {
         @Advice.Local("otelContext") Context context,
         @Advice.Local("otelScope") Scope scope) {

-      // System.out.printf("CfJspPageAdvice");
-      context = instrumenter().start(context, req);
-      if (context != null) {
-        scope = context.makeCurrent();
+      Context parentContext = io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge.currentContext();
+      if (!instrumenter().shouldStart(parentContext, req)) {
+        return;
       }
+
+      // System.out.printf("CfJspPageAdvice");
+      context = instrumenter().start(parentContext, req);
+      scope = context.makeCurrent();
     }

     @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)

as currently you are passing a null context to instrumenter().start() which will result in a NullPointerExceptions. After that your extension seems to work.