diff --git a/README.md b/README.md index aa4ad7fd..14b92140 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ ## Introduction -This repository contains AppOptics implementation that works with OpenTelemetry SDK and Auto agent. This is built on demo repo https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/examples/distro and added sub-projects by merging changes from https://github.com/appoptics/appoptics-opentelemetry-java (now archived) +This repository contains Solarwinds APM implementation that works with OpenTelemetry SDK and Auto agent. This is built on demo repo https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/examples/distro and added sub-projects by merging changes from https://github.com/appoptics/appoptics-opentelemetry-java (now archived) Here is the summary of the sub-projects: -- agent : Builds the full OT auto agent with extra AppOptics components. This is simply a repackaging build script that pull OT agent and our sub-projects to construct a new auto agent -- appoptics-opentelemetry-sdk : Builds the SDK artifact which has exactly the same interface as our existing AppOptics java agent SDK https://github.com/librato/joboe/tree/master/api . This is to be used as a base for `appoptics-opentelemetry-sdk-shaded` -- appoptics-opentelemetry-sdk-shaded : Same as appoptics-opentelemetry-sdk but can be used with the OT agent with shaded class names -- custom : Extra AppOptics components, contains all custom functionality, SPI and other extensions (for example Sampler, Tracer Provider etc) to be loaded by OT's agent classloader -- core-bootstrap : Core AppOptics components that need to be made available to bootstrap classloader. This is important for `appoptics-opentelemetry-sdk` as the classes from `appoptics-opentelemetry-sdk` are loaded by app loader, which has no access to OT's agent classloader which loads `custom` +- agent : Builds the full OT auto agent with extra Solarwinds APM components. This is simply a repackaging build script that pull OT agent and our sub-projects to construct a new auto agent +- appoptics-opentelemetry-sdk : (Archived as we have decided not to maintain backward-compatibility with AppOptics) Builds the SDK artifact which has exactly the same interface as our existing AppOptics java agent SDK https://github.com/librato/joboe/tree/master/api . This is to be used as a base for `appoptics-opentelemetry-sdk-shaded` +- appoptics-opentelemetry-sdk-shaded : (Archived as we have decided not to maintain backward-compatibility with AppOptics) Same as appoptics-opentelemetry-sdk but can be used with the OT agent with shaded class names +- custom : Extra Solarwinds APM components, contains all custom functionality, SPI and other extensions (for example Sampler, Tracer Provider etc) to be loaded by OT's agent classloader +- core-bootstrap : Core Solarwinds APM components that need to be made available to bootstrap classloader. This is important for `appoptics-opentelemetry-sdk` as the classes from `appoptics-opentelemetry-sdk` are loaded by app loader, which has no access to OT's agent classloader which loads `custom` - instrumentation : Additional instrumentation provided by us using the OT instrumentation framework (ByteBuddy) - sdk-extensions : Builds the AO extension jar which runs with the original OT agent (vs the agent built from `agent` sub-project) - sdk-extensions-bootstrap : Builds the AO extension jar dependencies that should be made available to bootstrap loader. It basically package the `core` and `metrics` from joboe @@ -16,15 +16,12 @@ More details for each of the sub-projects are listed in [Sub-Projects](#sub-proj ## Build #### Preparations -Since this project has dependencies on various internal artifacts from [joboe](https://github.com/librato/joboe), the build machine would need access to those artifacts. We currently do NOT have any internal maven server to host those artifacts. Hence the easiest way is to build and install those artifacts from joboe on the build machine: -1. Check out the dependency project (joboe) git clone https://github.com/librato/joboe.git -2. Navigate to the cloned joboe, check out the relevant branch `git checkout AO-16083-ot-v1` (this will change in the future if we merge this branch back to `develop`/`main`, in such case we will check out the joboe version referenced by this distro instead) -3. Build the joboe and install all the artifacts by executing `mvn clean install` at the project root (add -DskipTests flag to skip tests, possible to only build dependencies, core and metrics, as they are the only ones required by our OT implementation, though it might be easier to just build all) +Since this project has dependencies on various internal artifacts from [joboe](https://github.com/librato/joboe), the build machine would need access to those artifacts. Currently the Joboe core libraries for the OpenTelemetry custom distro are in the `otel` branch of the `Joboe` repo and are published to the Github Packages. #### Agent/Extensions Jars Simply run `gradle build` at the root folder. -The agent should be built at `agent\build\libs\agent-1.0-SNAPSHOT-all.jar`. +The agent should be built at `agent\build\libs\solarwinds-apm-agent-all.jar`. The sdk-extensions jar should be built at `sdk-extensions\build\libs\sdk-extensions-1.0-SNAPSHOT-all.jar`. #### SDK artifacts @@ -32,16 +29,16 @@ To build the `appoptics-opentelemetry-sdk` and `appoptics-opentelemetry-sdk-shad `gradle :appoptics-opentelemetry-sdk:publishToMavenLocal` and `gradle :appoptics-opentelemetry-sdk-shaded:publishToMavenLocal` -The artifacts will be published to local maven repo. +The artifacts will be published to local maven repo. (Use the Github Actions workflow `Release` to build and publish the custom distro to Github Packages.) ## Usage #### Agent Jar Attach the agent to jvm process arg such as: -`-javaagent:"C:\Users\patson.luk\git\opentelemetry-custom-distro\agent\build\libs\agent-1.0-SNAPSHOT-all.jar" -Dotel.appoptics.service.key=` +`-javaagent:"_the_path_to_the_jar_file" -Dotel.solarwinds.service.key=` Upon successful initialization, the log should print such as: ``` -[otel.javaagent 2021-06-30 13:04:07:759 -0700] [main] INFO com.appoptics.opentelemetry.extensions.AppOpticsTracerProviderConfigurer - Successfully initialized AppOptics OpenTelemetry extensions with service key ec3d********************************************************5468:ot +[otel.javaagent 2021-06-30 13:04:07:759 -0700] [main] INFO com.appoptics.opentelemetry.extensions.AppOpticsTracerProviderConfigurer - Successfully initialized Solarwinds APM OpenTelemetry extensions with service key ec3d********************************************************5468:ot ``` #### Extension Jar 1. Either download the auto agent directly from https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent-all.jar or build from source. To build from source: @@ -81,7 +78,7 @@ After the artifact `appoptics-opentelemetry-sdk-shaded` is built and published t ## Debug Various flags can be enabled to enable debugging -#### AppOptics core logs +#### Solarwinds APM core logs (WIP) #### Muzzling @@ -129,7 +126,7 @@ Our main implementation for OT SPI - which scans implementation using Java servi This is used by both the sub-projects `agent` and `sdk-extensions` #### core-bootstrap -Similar to `custom`, but this contains core AppOptics components that need to be made available to bootstrap classloader. This is important for `appoptics-opentelemetry-sdk` as classes from `appoptics-opentelemetry-sdk` are loaded by app loader, which has no access to OT's agent classloader which loads `custom` +Similar to `custom`, but this contains core Solarwinds APM components that need to be made available to bootstrap classloader. This is important for `appoptics-opentelemetry-sdk` as classes from `appoptics-opentelemetry-sdk` are loaded by app loader, which has no access to OT's agent classloader which loads `custom` #### instrumentation Our custom instrumentation added on top of the existing OT auto agent instrumentation. diff --git a/build.gradle b/build.gradle index 4ede6c01..11f25210 100644 --- a/build.gradle +++ b/build.gradle @@ -11,8 +11,8 @@ subprojects { opentelemetryJavaagent: "1.7.2", bytebuddy : "1.10.18", guava : "30.1-jre", - appopticsCore : "7.1.0", - agent : "0.6.0" // the custom distro agent version + appopticsCore : "7.2.0", + agent : "0.7.0" // the custom distro agent version ] versions.appopticsMetrics = "${versions.appopticsCore}" // they share the same version now versions.opentelemetryAlpha = "${versions.opentelemetry}-alpha" diff --git a/custom/src/main/java/com/appoptics/opentelemetry/extensions/initialize/Initializer.java b/custom/src/main/java/com/appoptics/opentelemetry/extensions/initialize/Initializer.java index cae3437e..7ae31895 100644 --- a/custom/src/main/java/com/appoptics/opentelemetry/extensions/initialize/Initializer.java +++ b/custom/src/main/java/com/appoptics/opentelemetry/extensions/initialize/Initializer.java @@ -32,6 +32,7 @@ public class Initializer { private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(Initializer.class.getName()); private static Future startupTasksFuture; + private static final String CONFIG_FILE = "solarwinds-apm-config.json"; static { ConfigProperty.AGENT_LOGGING.setParser(LogSettingParser.INSTANCE); @@ -61,19 +62,19 @@ public static Future initialize() throws InvalidConfigException { } catch (InvalidConfigException e) { exception = e; - LOGGER.warn("Failed to initialize AppOptics OpenTelemetry extensions due to config error: " + e.getMessage(), e); + LOGGER.warn("Failed to initialize SolarwindsAPM OpenTelemetry extensions due to config error: " + e.getMessage(), e); throw e; } finally { reportInit(exception); serviceKey = (String) ConfigManager.getConfig(ConfigProperty.AGENT_SERVICE_KEY); - LOGGER.info("Successfully initialized AppOptics OpenTelemetry extensions with service key " + ServiceKeyUtils.maskServiceKey(serviceKey)); + LOGGER.info("Successfully initialized SolarwindsAPM OpenTelemetry extensions with service key " + ServiceKeyUtils.maskServiceKey(serviceKey)); return future; } } private static void registerShutdownTasks() { - Thread shutdownThread = new Thread("AppOptics-shutdown-hook") { + Thread shutdownThread = new Thread("SolarwindsAPM-shutdown-hook") { @Override public void run() { SystemMonitorController.stop(); //stop system monitors, this might flush extra messages to reporters @@ -265,11 +266,11 @@ static ConfigContainer readConfigs(Map env, String explicitServi try { // read from the same directory as the agent jar file File jarDirectory = new File(Initializer.class.getProtectionDomain().getCodeSource().getLocation() .toURI()).getParentFile(); - File confFromJarDir = new File(jarDirectory, "javaagent.json"); + File confFromJarDir = new File(jarDirectory, CONFIG_FILE); config = new FileInputStream(confFromJarDir); location = confFromJarDir.getPath(); } catch (URISyntaxException | FileNotFoundException e) { - config = Initializer.class.getResourceAsStream("/javaagent.json"); //the file included within the jar + config = Initializer.class.getResourceAsStream("/" + CONFIG_FILE); //the file included within the jar location = "default"; } @@ -359,11 +360,11 @@ private static void processConfigs(ConfigContainer configs) throws InvalidConfig } else { if (!configs.containsProperty(ConfigProperty.AGENT_SERVICE_KEY)) { - LOGGER.warn("Could not find the service key! Please specify " + ConfigProperty.AGENT_SERVICE_KEY.getConfigFileKey() + " in javaagent.json"); + LOGGER.warn("Could not find the service key! Please specify " + ConfigProperty.AGENT_SERVICE_KEY.getConfigFileKey() + " in " + CONFIG_FILE); throw new InvalidConfigServiceKeyException("Service key not found"); } else { - LOGGER.warn("Service key is empty! Please specify " + ConfigProperty.AGENT_SERVICE_KEY.getConfigFileKey() + " in javaagent.json"); + LOGGER.warn("Service key is empty! Please specify " + ConfigProperty.AGENT_SERVICE_KEY.getConfigFileKey() + " in " + CONFIG_FILE); throw new InvalidConfigServiceKeyException("Service key is empty"); } } diff --git a/custom/src/main/resources/javaagent.json b/custom/src/main/resources/solarwinds-apm-config.json similarity index 100% rename from custom/src/main/resources/javaagent.json rename to custom/src/main/resources/solarwinds-apm-config.json