Skip to content

Commit 7c46b1d

Browse files
committed
Introduce the splunk-otel-java-agent framework.
This framework will wire up the splunk distribution of opentelemetry java for auto-instrumentation and direct ingest. It leverages VCAP_SERVICES and the existence of a service binding with a specific name (splunk-o11y). Signed-off-by: Jason Plumb [email protected] Resolves issue #825
1 parent edad6b2 commit 7c46b1d

File tree

6 files changed

+205
-0
lines changed

6 files changed

+205
-0
lines changed

config/components.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ frameworks:
7171
- "JavaBuildpack::Framework::SealightsAgent"
7272
- "JavaBuildpack::Framework::SeekerSecurityProvider"
7373
- "JavaBuildpack::Framework::SpringAutoReconfiguration"
74+
- "JavaBuildpack::Framework::SplunkOtelJavaAgent"
7475
- "JavaBuildpack::Framework::SpringInsight"
7576
- "JavaBuildpack::Framework::SkyWalkingAgent"
7677
- "JavaBuildpack::Framework::YourKitProfiler"

config/splunk_otel_java_agent.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Cloud Foundry Java Buildpack
2+
# Copyright 2013-2020 the original author or authors.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# Configuration for the Splunk Distribution of OpenTelemetry Java Instrumentation
17+
# See https://github.com/signalfx/splunk-otel-java for more information
18+
---
19+
version: +
20+
repository_root: https://raw.githubusercontent.com/signalfx/splunk-otel-java/main/deployments/cloudfoundry/
21+
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Splunk Distribution of OpenTelemetry Java Instrumentation
2+
3+
The Splunk OpenTelemetry Java Agent buildpack framework will cause an application to be automatically instrumented
4+
with the [Splunk distribution of OpenTelemetry Java Instrumentation](https://github.com/signalfx/splunk-otel-java).
5+
6+
Trace data will be sent directly to Splunk Observability Cloud.
7+
8+
* **Detection criteria**: Existence of a bound service with the name `splunk-o11y`.
9+
* **Tags**: `splunk-otel-java-agent=<version>` to control which version of the instrumentation agent is used.
10+
* Default = latest available version
11+
12+
## User-Provided Service
13+
14+
Users are currently expected to provide their own "custom user provided service" (cups)
15+
instance and bind it to their application. The service MUST be named `splunk-o11y`.
16+
17+
For example, to create a service named `splunk-o11y` that represents Observability Cloud
18+
realm `us0` and represents a user environment named `cf-demo`, you could use the following
19+
commands:
20+
21+
```
22+
$ cf cups splunk-o11y -p \
23+
'{"splunk.realm": "us0", "splunk.access.token": "<redacted>", "otel.resource.attributes": "deployment.environment=cf-demo"}'
24+
$ cf bind-service myApp splunk-o11y
25+
$ cf restage myApp
26+
```
27+
28+
The `credential` field of the service should provide these entries:
29+
30+
| Name | Required? | Description
31+
|------------------------|-----------| -----------
32+
| `splunk.access.token` | Yes | The Splunk [org access token](https://docs.splunk.com/observability/admin/authentication-tokens/org-tokens.html).
33+
| `splunk.realm` | Yes | The Splunk realm where data will be sent. This is commonly `us0` or `eu0` etc.
34+
| `otel.*` or `splunk.*` | Optional | All additional credentials starting with these prefixes will be appended to the application's JVM arguments as system properties.
35+
36+
### Choosing a version
37+
38+
Most users should skip this and simply use the latest version of the agent available (the default).
39+
To override the default and choose a specific version, you can use the `JBP_CONFIG_*` mechanism
40+
and set the `JBP_CONFIG_SPLUNK_OTEL_JAVA_AGENT` environment variable for your application.
41+
42+
For example, to use version 1.16.0 of the Splunk OpenTelemetry Java Instrumentation, you
43+
could run:
44+
```
45+
$ cf set-env testapp JBP_CONFIG_SPLUNK_OTEL_JAVA_AGENT '{version: 1.16.0}'
46+
```
47+
48+
# Additional Resources
49+
50+
* [Splunk Observability](https://www.splunk.com/en_us/products/observability.html)
51+
* [Splunk Distribution of OpenTelemetry Java](https://github.com/signalfx/splunk-otel-java) on GitHub
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# frozen_string_literal: true
2+
3+
# Cloud Foundry Java Buildpack
4+
# Copyright 2013-2020 the original author or authors.
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
18+
require 'java_buildpack/component/versioned_dependency_component'
19+
require 'java_buildpack/framework'
20+
21+
module JavaBuildpack
22+
module Framework
23+
24+
# Main class for adding the Splunk OpenTelemetry instrumentation agent
25+
class SplunkOtelJavaAgent < JavaBuildpack::Component::VersionedDependencyComponent
26+
27+
# (see JavaBuildpack::Component::BaseComponent#compile)
28+
def compile
29+
download_jar
30+
end
31+
32+
# (see JavaBuildpack::Component::BaseComponent#release)
33+
def release
34+
java_opts = @droplet.java_opts
35+
java_opts.add_javaagent(@droplet.sandbox + jar_name)
36+
37+
credentials = @application.services.find_service(REQUIRED_SERVICE_NAME_FILTER)['credentials']
38+
# Add all otel.* and splunk.* credentials from the service bind as jvm system properties
39+
credentials&.each do |key, value|
40+
java_opts.add_system_property(key, value) if key.start_with?('splunk.') || key.start_with?('otel.')
41+
end
42+
43+
app_name = @application.details['application_name']
44+
java_opts.add_system_property('otel.service.name', app_name)
45+
end
46+
47+
protected
48+
49+
# (see JavaBuildpack::Component::VersionedDependencyComponent#supports?)
50+
def supports?
51+
@application.services.one_service? REQUIRED_SERVICE_NAME_FILTER
52+
end
53+
54+
REQUIRED_SERVICE_NAME_FILTER = /^splunk-o11y$/.freeze
55+
56+
end
57+
end
58+
end
341 Bytes
Binary file not shown.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# frozen_string_literal: true
2+
3+
# Cloud Foundry Java Buildpack
4+
# Copyright 2013-2020 the original author or authors.
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
18+
require 'spec_helper'
19+
require 'component_helper'
20+
require 'java_buildpack/framework/splunk_otel_java_agent'
21+
require 'java_buildpack/util/tokenized_version'
22+
23+
describe JavaBuildpack::Framework::SplunkOtelJavaAgent do
24+
include_context 'with component help'
25+
26+
let(:configuration) { { 'version' => '1.16.0' } }
27+
let(:vcap_application) { { 'application_name' => 'GreatServiceTM' } }
28+
29+
it 'does not detect without splunk-o11y service bind' do
30+
expect(component.detect).to be_nil
31+
end
32+
33+
context 'when detected' do
34+
35+
before do
36+
allow(services).to receive(:one_service?).with(/^splunk-o11y$/).and_return(true)
37+
end
38+
39+
it 'detects with splunk-otel-java' do
40+
expect(component.detect).to eq("splunk-otel-java-agent=#{version}")
41+
end
42+
43+
it 'downloads the splunk otel javaagent jar', cache_fixture: 'stub-splunk-otel-javaagent.jar' do
44+
45+
component.compile
46+
47+
expect(sandbox + "splunk_otel_java_agent-#{version}.jar").to exist
48+
end
49+
50+
it 'updates JAVA_OPTS' do
51+
allow(services).to receive(:find_service).and_return('credentials' => { 'splunk.access.token' => 'sekret',
52+
'ignored' => 'not used',
53+
'otel.foo' => 'bar' })
54+
component.release
55+
56+
expect(java_opts).to include(
57+
"-javaagent:$PWD/.java-buildpack/splunk_otel_java_agent/splunk_otel_java_agent-#{version}.jar"
58+
)
59+
expect(java_opts).to include('-Dsplunk.access.token=sekret')
60+
expect(java_opts).to include('-Dotel.foo=bar')
61+
end
62+
63+
it 'sets the service name from the application name' do
64+
allow(services).to receive(:find_service).and_return('credentials' => { 'splunk.access.token' => 'sekret' })
65+
# allow(details).to be( { 'application_name' => 'dick' })
66+
67+
component.release
68+
69+
expect(java_opts).to include('-Dotel.service.name=GreatServiceTM')
70+
end
71+
72+
end
73+
74+
end

0 commit comments

Comments
 (0)