splunk-otel 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/CODEOWNERS +14 -0
- data/.github/workflows/main.yml +48 -0
- data/.gitignore +13 -0
- data/.gitlab-ci.yml +23 -0
- data/.rubocop.yml +27 -0
- data/CHANGELOG.md +10 -0
- data/CODE_OF_CONDUCT.md +90 -0
- data/CONTRIBUTING.md +88 -0
- data/Gemfile +6 -0
- data/LICENSE +177 -0
- data/MIGRATING.md +61 -0
- data/README.md +190 -0
- data/Rakefile +15 -0
- data/SECURITY.md +7 -0
- data/conf/otel-collector-config.yaml +21 -0
- data/docker-compose.yml +11 -0
- data/docs/README.md +3 -0
- data/docs/advanced-config.md +52 -0
- data/docs/correlating-traces-and-logs.md +23 -0
- data/docs/instrumenting-rails.md +7 -0
- data/docs/troubleshooting.md +14 -0
- data/examples/basic/README.md +94 -0
- data/examples/basic/collector_trace.png +0 -0
- data/examples/basic/console.rb +63 -0
- data/examples/basic/direct_trace.png +0 -0
- data/examples/basic/docker-compose.yml +9 -0
- data/examples/rails-7-barebones/.bundle/config +2 -0
- data/examples/rails-7-barebones/.gitignore +1 -0
- data/examples/rails-7-barebones/Dockerfile +16 -0
- data/examples/rails-7-barebones/Gemfile +17 -0
- data/examples/rails-7-barebones/README.md +24 -0
- data/examples/rails-7-barebones/app.ru +34 -0
- data/examples/rails-7-barebones/config/initializers/splunk_otel.rb +4 -0
- data/examples/rails-7-barebones/docker-compose.yml +34 -0
- data/examples/rails-7-barebones/tests-e2e/rails_7_barebones_test.rb +27 -0
- data/examples/rails-7-barebones/wait-for.sh +191 -0
- data/lib/splunk/otel/common.rb +47 -0
- data/lib/splunk/otel/instrumentation/action_pack/instrumentation.rb +41 -0
- data/lib/splunk/otel/instrumentation/action_pack/railtie.rb +28 -0
- data/lib/splunk/otel/instrumentation/action_pack/version.rb +11 -0
- data/lib/splunk/otel/instrumentation/action_pack.rb +14 -0
- data/lib/splunk/otel/instrumentation/rack/middleware.rb +25 -0
- data/lib/splunk/otel/instrumentation/rack.rb +3 -0
- data/lib/splunk/otel/logging.rb +24 -0
- data/lib/splunk/otel/version.rb +7 -0
- data/lib/splunk/otel.rb +170 -0
- data/scripts/install-release-deps.sh +10 -0
- data/scripts/release.sh +38 -0
- data/splunk-otel.gemspec +51 -0
- metadata +316 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "test-unit"
|
4
|
+
require "net/http"
|
5
|
+
require "json"
|
6
|
+
|
7
|
+
module Splunk
|
8
|
+
# Rails7BarebonesTest
|
9
|
+
class Rails7BarebonesTest < Test::Unit::TestCase
|
10
|
+
test "generates spans" do
|
11
|
+
app_host = ENV.fetch "APP_HOST", "localhost"
|
12
|
+
app_port = ENV.fetch("APP_PORT", "3000").to_i
|
13
|
+
collector_host = ENV.fetch "COLLECTOR_HOST", "localhost"
|
14
|
+
collector_port = ENV.fetch("COLLECTOR_PORT", "8378").to_i
|
15
|
+
|
16
|
+
Net::HTTP.get(app_host, "/", app_port)
|
17
|
+
|
18
|
+
response = Net::HTTP.get(collector_host, "/?timeout=20&count=1", collector_port)
|
19
|
+
spans = JSON.parse(response)
|
20
|
+
assert spans.count >= 1
|
21
|
+
|
22
|
+
assert(spans.all? { |span| span["traceId"].to_s != "" })
|
23
|
+
assert(spans.all? { |span| span["spanId"].to_s != "" })
|
24
|
+
assert(spans.all? { |span| span["operationName"].to_s != "" })
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
# The MIT License (MIT)
|
4
|
+
#
|
5
|
+
# Copyright (c) 2017 Eficode Oy
|
6
|
+
#
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
12
|
+
# furnished to do so, subject to the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be included in all
|
15
|
+
# copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
23
|
+
# SOFTWARE.
|
24
|
+
|
25
|
+
VERSION="2.2.3"
|
26
|
+
|
27
|
+
set -- "$@" -- "$TIMEOUT" "$QUIET" "$PROTOCOL" "$HOST" "$PORT" "$result"
|
28
|
+
TIMEOUT=15
|
29
|
+
QUIET=0
|
30
|
+
# The protocol to make the request with, either "tcp" or "http"
|
31
|
+
PROTOCOL="tcp"
|
32
|
+
|
33
|
+
echoerr() {
|
34
|
+
if [ "$QUIET" -ne 1 ]; then printf "%s\n" "$*" 1>&2; fi
|
35
|
+
}
|
36
|
+
|
37
|
+
usage() {
|
38
|
+
exitcode="$1"
|
39
|
+
cat << USAGE >&2
|
40
|
+
Usage:
|
41
|
+
$0 host:port|url [-t timeout] [-- command args]
|
42
|
+
-q | --quiet Do not output any status messages
|
43
|
+
-t TIMEOUT | --timeout=timeout Timeout in seconds, zero for no timeout
|
44
|
+
-v | --version Show the version of this tool
|
45
|
+
-- COMMAND ARGS Execute command with args after the test finishes
|
46
|
+
USAGE
|
47
|
+
exit "$exitcode"
|
48
|
+
}
|
49
|
+
|
50
|
+
wait_for() {
|
51
|
+
case "$PROTOCOL" in
|
52
|
+
tcp)
|
53
|
+
if ! command -v nc >/dev/null; then
|
54
|
+
echoerr 'nc command is missing!'
|
55
|
+
exit 1
|
56
|
+
fi
|
57
|
+
;;
|
58
|
+
http)
|
59
|
+
if ! command -v wget >/dev/null; then
|
60
|
+
echoerr 'wget command is missing!'
|
61
|
+
exit 1
|
62
|
+
fi
|
63
|
+
;;
|
64
|
+
esac
|
65
|
+
|
66
|
+
TIMEOUT_END=$(($(date +%s) + TIMEOUT))
|
67
|
+
|
68
|
+
while :; do
|
69
|
+
case "$PROTOCOL" in
|
70
|
+
tcp)
|
71
|
+
nc -w 1 -z "$HOST" "$PORT" > /dev/null 2>&1
|
72
|
+
;;
|
73
|
+
http)
|
74
|
+
wget --timeout=1 -q "$HOST" -O /dev/null > /dev/null 2>&1
|
75
|
+
;;
|
76
|
+
*)
|
77
|
+
echoerr "Unknown protocol '$PROTOCOL'"
|
78
|
+
exit 1
|
79
|
+
;;
|
80
|
+
esac
|
81
|
+
|
82
|
+
result=$?
|
83
|
+
|
84
|
+
if [ $result -eq 0 ] ; then
|
85
|
+
if [ $# -gt 7 ] ; then
|
86
|
+
for result in $(seq $(($# - 7))); do
|
87
|
+
result=$1
|
88
|
+
shift
|
89
|
+
set -- "$@" "$result"
|
90
|
+
done
|
91
|
+
|
92
|
+
TIMEOUT=$2 QUIET=$3 PROTOCOL=$4 HOST=$5 PORT=$6 result=$7
|
93
|
+
shift 7
|
94
|
+
exec "$@"
|
95
|
+
fi
|
96
|
+
exit 0
|
97
|
+
fi
|
98
|
+
|
99
|
+
if [ $TIMEOUT -ne 0 -a $(date +%s) -ge $TIMEOUT_END ]; then
|
100
|
+
echo "Operation timed out" >&2
|
101
|
+
exit 1
|
102
|
+
fi
|
103
|
+
|
104
|
+
sleep 1
|
105
|
+
done
|
106
|
+
}
|
107
|
+
|
108
|
+
while :; do
|
109
|
+
case "$1" in
|
110
|
+
http://*|https://*)
|
111
|
+
HOST="$1"
|
112
|
+
PROTOCOL="http"
|
113
|
+
shift 1
|
114
|
+
;;
|
115
|
+
*:* )
|
116
|
+
HOST=$(printf "%s\n" "$1"| cut -d : -f 1)
|
117
|
+
PORT=$(printf "%s\n" "$1"| cut -d : -f 2)
|
118
|
+
shift 1
|
119
|
+
;;
|
120
|
+
-v | --version)
|
121
|
+
echo $VERSION
|
122
|
+
exit
|
123
|
+
;;
|
124
|
+
-q | --quiet)
|
125
|
+
QUIET=1
|
126
|
+
shift 1
|
127
|
+
;;
|
128
|
+
-q-*)
|
129
|
+
QUIET=0
|
130
|
+
echoerr "Unknown option: $1"
|
131
|
+
usage 1
|
132
|
+
;;
|
133
|
+
-q*)
|
134
|
+
QUIET=1
|
135
|
+
result=$1
|
136
|
+
shift 1
|
137
|
+
set -- -"${result#-q}" "$@"
|
138
|
+
;;
|
139
|
+
-t | --timeout)
|
140
|
+
TIMEOUT="$2"
|
141
|
+
shift 2
|
142
|
+
;;
|
143
|
+
-t*)
|
144
|
+
TIMEOUT="${1#-t}"
|
145
|
+
shift 1
|
146
|
+
;;
|
147
|
+
--timeout=*)
|
148
|
+
TIMEOUT="${1#*=}"
|
149
|
+
shift 1
|
150
|
+
;;
|
151
|
+
--)
|
152
|
+
shift
|
153
|
+
break
|
154
|
+
;;
|
155
|
+
--help)
|
156
|
+
usage 0
|
157
|
+
;;
|
158
|
+
-*)
|
159
|
+
QUIET=0
|
160
|
+
echoerr "Unknown option: $1"
|
161
|
+
usage 1
|
162
|
+
;;
|
163
|
+
*)
|
164
|
+
QUIET=0
|
165
|
+
echoerr "Unknown argument: $1"
|
166
|
+
usage 1
|
167
|
+
;;
|
168
|
+
esac
|
169
|
+
done
|
170
|
+
|
171
|
+
if ! [ "$TIMEOUT" -ge 0 ] 2>/dev/null; then
|
172
|
+
echoerr "Error: invalid timeout '$TIMEOUT'"
|
173
|
+
usage 3
|
174
|
+
fi
|
175
|
+
|
176
|
+
case "$PROTOCOL" in
|
177
|
+
tcp)
|
178
|
+
if [ "$HOST" = "" ] || [ "$PORT" = "" ]; then
|
179
|
+
echoerr "Error: you need to provide a host and port to test."
|
180
|
+
usage 2
|
181
|
+
fi
|
182
|
+
;;
|
183
|
+
http)
|
184
|
+
if [ "$HOST" = "" ]; then
|
185
|
+
echoerr "Error: you need to provide a host to test."
|
186
|
+
usage 2
|
187
|
+
fi
|
188
|
+
;;
|
189
|
+
esac
|
190
|
+
|
191
|
+
wait_for "$@"
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Splunk
|
4
|
+
module Otel
|
5
|
+
# functions for shared functionality that will be used by multiple
|
6
|
+
# instrumentation libraries. Like creating RUM headers used by any
|
7
|
+
# HTTP library.
|
8
|
+
module Common
|
9
|
+
CORS_EXPOSE_HEADER = "Access-Control-Expose-Headers"
|
10
|
+
SERVER_TIMING_HEADER = "Server-Timing"
|
11
|
+
|
12
|
+
# rubocop:disable Lint/MissingCopEnableDirective
|
13
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
14
|
+
# rubocop:disable Metrics/MethodLength
|
15
|
+
# rubocop:disable Metrics/AbcSize
|
16
|
+
def rum_headers(headers)
|
17
|
+
span = OpenTelemetry::Trace.current_span
|
18
|
+
|
19
|
+
return headers if span == OpenTelemetry::Trace::Span::INVALID
|
20
|
+
|
21
|
+
version = "00"
|
22
|
+
trace_id = span.context.hex_trace_id
|
23
|
+
span_id = span.context.hex_span_id
|
24
|
+
flags = span.context.trace_flags.sampled? ? "01" : "00"
|
25
|
+
|
26
|
+
trace_parent = [version, trace_id, span_id, flags]
|
27
|
+
headers[SERVER_TIMING_HEADER] = if (headers[SERVER_TIMING_HEADER] || "").empty?
|
28
|
+
"traceparent;desc=\"#{trace_parent.join("-")}\""
|
29
|
+
else
|
30
|
+
# rubocop:disable Layout/LineLength
|
31
|
+
"#{headers[SERVER_TIMING_HEADER]}, traceparent;desc=\"#{trace_parent.join("-")}\""
|
32
|
+
end
|
33
|
+
|
34
|
+
# TODO: check if this needs to be conditioned on CORS
|
35
|
+
headers[CORS_EXPOSE_HEADER] = if (headers[CORS_EXPOSE_HEADER] || "").empty?
|
36
|
+
SERVER_TIMING_HEADER
|
37
|
+
else
|
38
|
+
"#{headers[CORS_EXPOSE_HEADER]}, #{SERVER_TIMING_HEADER}"
|
39
|
+
end
|
40
|
+
|
41
|
+
headers
|
42
|
+
end
|
43
|
+
|
44
|
+
module_function :rum_headers
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "opentelemetry"
|
4
|
+
require "opentelemetry-instrumentation-base"
|
5
|
+
|
6
|
+
module Splunk
|
7
|
+
module Otel
|
8
|
+
module Instrumentation
|
9
|
+
module ActionPack
|
10
|
+
# The Instrumentation class contains logic to detect and install the ActionPack instrumentation
|
11
|
+
class Instrumentation < OpenTelemetry::Instrumentation::Base
|
12
|
+
MINIMUM_VERSION = Gem::Version.new("5.2.0")
|
13
|
+
|
14
|
+
install do |_config|
|
15
|
+
require_railtie
|
16
|
+
end
|
17
|
+
|
18
|
+
present do
|
19
|
+
defined?(::ActionController)
|
20
|
+
end
|
21
|
+
|
22
|
+
compatible do
|
23
|
+
gem_version >= MINIMUM_VERSION
|
24
|
+
end
|
25
|
+
|
26
|
+
option :enable_recognize_route, default: false, validate: :boolean
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def gem_version
|
31
|
+
::ActionPack.version
|
32
|
+
end
|
33
|
+
|
34
|
+
def require_railtie
|
35
|
+
require_relative "railtie"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rack/etag"
|
4
|
+
require_relative "../rack"
|
5
|
+
|
6
|
+
module Splunk
|
7
|
+
module Otel
|
8
|
+
module Instrumentation
|
9
|
+
module ActionPack
|
10
|
+
# Install the Rack middleware for RUM responses
|
11
|
+
class Railtie < ::Rails::Railtie
|
12
|
+
config.before_initialize do |app|
|
13
|
+
case Rails.version
|
14
|
+
when /^7\./
|
15
|
+
# TODO: can be removed once https://github.com/rails/rails/issues/45607 is merged
|
16
|
+
app.middleware.insert_before(
|
17
|
+
::Rack::ETag,
|
18
|
+
Splunk::Otel::Rack::RumMiddleware
|
19
|
+
)
|
20
|
+
else
|
21
|
+
app.middleware.use Splunk::Otel::Rack::RumMiddleware
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Splunk
|
4
|
+
module Otel
|
5
|
+
module Instrumentation
|
6
|
+
# Contains the RUM instrumentation for the ActionPack gem
|
7
|
+
module ActionPack
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
require_relative "./action_pack/instrumentation"
|
14
|
+
require_relative "./action_pack/version"
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "splunk/otel/common"
|
4
|
+
|
5
|
+
module Splunk
|
6
|
+
module Otel
|
7
|
+
module Rack
|
8
|
+
# RumMiddleware propagates context and instruments Rack responses
|
9
|
+
# by way of its middleware system
|
10
|
+
class RumMiddleware
|
11
|
+
def initialize(app)
|
12
|
+
@app = app
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
status, headers, body = @app.call(env)
|
17
|
+
|
18
|
+
headers = Splunk::Otel::Common.rum_headers(headers)
|
19
|
+
|
20
|
+
[status, headers, body]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Splunk
|
4
|
+
module Otel
|
5
|
+
# functions for log correlation
|
6
|
+
module Logging
|
7
|
+
# return log formatted trace context
|
8
|
+
def format_correlation
|
9
|
+
resource_attributes = OpenTelemetry.tracer_provider.resource.attribute_enumerator.to_h
|
10
|
+
service_name = resource_attributes["service.name"]
|
11
|
+
span = OpenTelemetry::Trace.current_span
|
12
|
+
|
13
|
+
if span == OpenTelemetry::Trace::Span::INVALID
|
14
|
+
"service.name=#{service_name}"
|
15
|
+
else
|
16
|
+
%W[service.name=#{service_name} trace_id=#{span.context.hex_trace_id}
|
17
|
+
span_id=#{span.context.hex_span_id}].join(" ")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module_function :format_correlation
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/splunk/otel.rb
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "otel/version"
|
4
|
+
require "opentelemetry/sdk"
|
5
|
+
|
6
|
+
# FIXME: without this, otlp doesn't work out-of-the-box
|
7
|
+
require "opentelemetry-exporter-otlp"
|
8
|
+
|
9
|
+
module Splunk
|
10
|
+
# main module for application startup configuration
|
11
|
+
module Otel
|
12
|
+
# custom exception types in this gem must inherit from Splunk::Otel::Error
|
13
|
+
# this allows the user to rescue a generic exception type to catch all exceptions
|
14
|
+
class Error < StandardError; end
|
15
|
+
|
16
|
+
# Configures the OpenTelemetry SDK and instrumentation with Splunk defaults.
|
17
|
+
#
|
18
|
+
# @yieldparam [Configurator] configurator Yields a configurator to the
|
19
|
+
# provided block
|
20
|
+
#
|
21
|
+
# Example usage:
|
22
|
+
# Without a block defaults are installed without any instrumentation
|
23
|
+
#
|
24
|
+
# Splunk::Otel.configure
|
25
|
+
#
|
26
|
+
# Install instrumentation individually with optional config
|
27
|
+
#
|
28
|
+
# Splunk::Otel.configure do |c|
|
29
|
+
# c.use 'OpenTelemetry::Instrumentation::Faraday', tracer_middleware: SomeMiddleware
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# Install all instrumentation with optional config
|
33
|
+
#
|
34
|
+
# Splunk::Otel.configure do |c|
|
35
|
+
# c.use_all 'OpenTelemetry::Instrumentation::Faraday' => { tracer_middleware: SomeMiddleware }
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# Add a span processor
|
39
|
+
#
|
40
|
+
# Splunk::Otel.configure do |c|
|
41
|
+
# c.add_span_processor SpanProcessor.new(SomeExporter.new)
|
42
|
+
# end
|
43
|
+
#
|
44
|
+
# Configure everything
|
45
|
+
#
|
46
|
+
# Splunk::Otel.configure do |c|
|
47
|
+
# c.logger = Logger.new(File::NULL)
|
48
|
+
# c.add_span_processor SpanProcessor.new(SomeExporter.new)
|
49
|
+
# c.use_all
|
50
|
+
# end
|
51
|
+
def configure(service_name: ENV.fetch("OTEL_SERVICE_NAME", "unnamed-ruby-service"),
|
52
|
+
auto_instrument: false)
|
53
|
+
set_default_propagators
|
54
|
+
set_access_token_header
|
55
|
+
set_default_exporter
|
56
|
+
set_default_span_limits
|
57
|
+
|
58
|
+
# run SDK's setup function
|
59
|
+
OpenTelemetry::SDK.configure do |c|
|
60
|
+
c.service_name = service_name
|
61
|
+
c.resource = OpenTelemetry::SDK::Resources::Resource.create(
|
62
|
+
"splunk.distro.version" => Splunk::Otel::VERSION
|
63
|
+
)
|
64
|
+
|
65
|
+
c.use_all if auto_instrument
|
66
|
+
yield c if block_given?
|
67
|
+
end
|
68
|
+
|
69
|
+
# set span limits to GDI defaults if not set by the user
|
70
|
+
OpenTelemetry.tracer_provider.span_limits = gdi_span_limits
|
71
|
+
|
72
|
+
verify_service_name
|
73
|
+
end
|
74
|
+
|
75
|
+
# verify `service.name` is set and print a warning if it is still the default
|
76
|
+
def verify_service_name
|
77
|
+
provider_resource = OpenTelemetry.tracer_provider.instance_variable_get(:@resource)
|
78
|
+
resource_attributes = provider_resource.instance_variable_get(:@attributes)
|
79
|
+
service_name = resource_attributes[OpenTelemetry::SemanticConventions::Resource::SERVICE_NAME]
|
80
|
+
OpenTelemetry.logger.warn service_name_warning if service_name == "unknown_service"
|
81
|
+
end
|
82
|
+
|
83
|
+
def set_default_exporter
|
84
|
+
set_endpoint
|
85
|
+
default_env_vars({ "OTEL_EXPORTER_OTLP_TRACES_COMPRESSION" => "gzip",
|
86
|
+
"OTEL_EXPORTER_OTLP_COMPRESSION" => "gzip",
|
87
|
+
"OTEL_TRACES_EXPORTER" => "otlp" })
|
88
|
+
end
|
89
|
+
|
90
|
+
def set_endpoint
|
91
|
+
traces_endpoint = ENV.fetch("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", nil)
|
92
|
+
endpoint = ENV.fetch("OTEL_EXPORTER_OTLP_ENDPOINT", nil)
|
93
|
+
splunk_realm = ENV.fetch("SPLUNK_REALM", nil)
|
94
|
+
|
95
|
+
# if user hasn't set traces endpoint or endpoint but has set the realm then
|
96
|
+
# set the endpoints to be https://api.<SPLUNK_REALM>.signalfx.com
|
97
|
+
# if either endpoint variable was set by the user then use those even if
|
98
|
+
# they've also set SPLUNK_REALM
|
99
|
+
return unless traces_endpoint.to_s.empty?
|
100
|
+
return unless endpoint.to_s.empty?
|
101
|
+
|
102
|
+
ENV["OTEL_EXPORTER_OTLP_TRACES_ENDPOINT"] = if splunk_realm.to_s.empty? || splunk_realm.to_s.eql?("none")
|
103
|
+
"http://localhost:4318/v1/traces"
|
104
|
+
else
|
105
|
+
"https://ingest.#{splunk_realm}.signalfx.com/v2/trace/otlp"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# add the access token header if the env variable is set
|
110
|
+
def set_access_token_header
|
111
|
+
splunk_access_token = ENV.fetch("SPLUNK_ACCESS_TOKEN", nil)
|
112
|
+
return if splunk_access_token.nil?
|
113
|
+
|
114
|
+
access_header = "x-sf-token=#{splunk_access_token}"
|
115
|
+
headers = ENV.fetch("OTEL_EXPORTER_OTLP_HEADERS", nil)
|
116
|
+
ENV["OTEL_EXPORTER_OTLP_HEADERS"] = if headers.to_s.empty?
|
117
|
+
access_header
|
118
|
+
else
|
119
|
+
"#{headers},#{access_header}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def set_default_propagators
|
124
|
+
default_env_vars({ "OTEL_PROPAGATORS" => "tracecontext,baggage" })
|
125
|
+
end
|
126
|
+
|
127
|
+
def set_default_span_limits
|
128
|
+
default_env_vars({ "OTEL_SPAN_LINK_COUNT_LIMIT" => "1000",
|
129
|
+
"OTEL_RUBY_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT" => "12000" })
|
130
|
+
end
|
131
|
+
|
132
|
+
def gdi_span_limits
|
133
|
+
infinite_defaults = { "OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT" => :attribute_count_limit,
|
134
|
+
"OTEL_SPAN_EVENT_COUNT_LIMIT" => :event_count_limit,
|
135
|
+
"OTEL_SPAN_LINK_COUNT_LIMIT" => :link_count_limit,
|
136
|
+
"OTEL_EVENT_ATTRIBUTE_COUNT_LIMIT" => :event_attribute_count_limit,
|
137
|
+
"OTEL_LINK_ATTRIBUTE_COUNT_LIMIT" => :link_attribute_count_limit }
|
138
|
+
|
139
|
+
defaults = {}
|
140
|
+
infinite_defaults.each do |k, v|
|
141
|
+
defaults[v] = Float::INFINITY if ENV[k].nil?
|
142
|
+
end
|
143
|
+
|
144
|
+
OpenTelemetry::SDK::Trace::SpanLimits.new(**defaults)
|
145
|
+
end
|
146
|
+
|
147
|
+
# set environment varaible default's if the user hasn't set them
|
148
|
+
def default_env_vars(env)
|
149
|
+
env.each do |k, v|
|
150
|
+
ENV[k] = v if ENV[k].nil?
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def service_name_warning
|
155
|
+
<<~WARNING
|
156
|
+
service.name attribute is not set, your service is unnamed and will be difficult to identify.
|
157
|
+
set your service name using the OTEL_SERVICE_NAME environment variable.
|
158
|
+
E.g. `OTEL_SERVICE_NAME="<YOUR_SERVICE_NAME_HERE>"`
|
159
|
+
WARNING
|
160
|
+
end
|
161
|
+
|
162
|
+
module_function :configure, :gdi_span_limits, :set_default_propagators, :set_default_exporter,
|
163
|
+
:verify_service_name, :service_name_warning, :default_env_vars,
|
164
|
+
:set_default_span_limits, :set_access_token_header, :set_endpoint
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
require "splunk/otel/logging"
|
169
|
+
require "splunk/otel/common"
|
170
|
+
require "splunk/otel/instrumentation/action_pack"
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
# instructions from https://github.com/cli/cli/blob/trunk/docs/install_linux.md#debian-ubuntu-linux-apt
|
6
|
+
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | gpg --dearmor -o /usr/share/keyrings/githubcli-archive-keyring.gpg
|
7
|
+
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null
|
8
|
+
|
9
|
+
apt-get update
|
10
|
+
apt-get -y install ca-certificates curl gnupg lsb-release gh
|
data/scripts/release.sh
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
|
5
|
+
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
6
|
+
ROOT_DIR="${SCRIPT_DIR}/../"
|
7
|
+
cd "${ROOT_DIR}"
|
8
|
+
|
9
|
+
print_usage() {
|
10
|
+
cat <<EOF
|
11
|
+
Usage: $(basename "$0") tag
|
12
|
+
Tag example: v1.2.3
|
13
|
+
EOF
|
14
|
+
}
|
15
|
+
|
16
|
+
if [[ $# != 1 ]]
|
17
|
+
then
|
18
|
+
print_usage
|
19
|
+
exit 1
|
20
|
+
fi
|
21
|
+
|
22
|
+
release_tag="$1"
|
23
|
+
# without the starting 'v'
|
24
|
+
release_version=$(echo "$release_tag" | cut -c2-)
|
25
|
+
|
26
|
+
create_gh_release() {
|
27
|
+
echo ">>> Creating GitHub release $release_tag ..."
|
28
|
+
gh release create "$release_tag" \
|
29
|
+
--repo "signalfx/splunk-otel-ruby" \
|
30
|
+
--draft \
|
31
|
+
--title "Release $release_tag"
|
32
|
+
}
|
33
|
+
|
34
|
+
create_gh_release
|
35
|
+
|
36
|
+
bundle install
|
37
|
+
bundle exec rake build
|
38
|
+
bundle exec gem push pkg/splunk-otel-${release_version}.gem
|