opentelemetry-config 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +49 -0
- data/lib/opentelemetry/config/env_substitution.rb +84 -0
- data/lib/opentelemetry/config/generated_constants.rb +32 -23
- data/lib/opentelemetry/config/logs.rb +127 -0
- data/lib/opentelemetry/config/resource.rb +1 -1
- data/lib/opentelemetry/config/version.rb +1 -1
- data/lib/opentelemetry/config.rb +20 -1
- metadata +8 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e6246820b0b2b5312be2c696c49f6def8f666425b3b5365a44e811fb455a3003
|
|
4
|
+
data.tar.gz: 38e2b961380f9394cdfa067590e40230e597436d5a349bbc28df3b8aaf58999c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2dbb1307ce50f1bc2390b1ed90741ae07f74499fade71f1de4540cf5ca930d09e6eca24eb34ca728723a930b3327d0fd9da9b799fb7ad63359e324c9773284cf
|
|
7
|
+
data.tar.gz: 7e0aa84b67fa17b591343b5cafb9ec58dc5cdff3507dcbbefbfe044bfcbc63f56b8d1603f08317221f759e9a8a0bbf71d2f8ddb93c73a81bd11235386d308d35
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Release History: opentelemetry-config
|
|
2
2
|
|
|
3
|
+
### v0.2.0 / 2026-10-20
|
|
4
|
+
|
|
5
|
+
* ADDED: Add declarative configuration for logger_provider (#2439)
|
|
6
|
+
* ADDED: Substitute environment variables in configuration files (#2468)
|
|
7
|
+
* FIXED: Correct schema_url unsupported warning (#2466)
|
|
8
|
+
* FIXED: Parse nullable objects without properties as present (#2465)
|
|
9
|
+
|
|
3
10
|
### v0.1.1 / 2026-10-13
|
|
4
11
|
|
|
5
12
|
* FIXED: Ignore SDK env defaults in declarative config (#2429)
|
data/README.md
CHANGED
|
@@ -17,6 +17,8 @@ It works with:
|
|
|
17
17
|
- `opentelemetry-sdk` — Traces
|
|
18
18
|
- `opentelemetry-exporter-otlp` — OTLP HTTP exporter
|
|
19
19
|
- `opentelemetry-instrumentation-all` — Instrumentation for gems
|
|
20
|
+
- `opentelemetry-logs-sdk` — Logs (optional, see [Logs](#logs))
|
|
21
|
+
- `opentelemetry-exporter-otlp-logs` — OTLP HTTP log exporter (optional)
|
|
20
22
|
|
|
21
23
|
This code is still under development and is not a complete implementation of the declarative configuration specification. Until the code becomes stable, declarative configuration functionality will live outside stable OpenTelemetry libraries.
|
|
22
24
|
|
|
@@ -70,6 +72,24 @@ File-based configuration uses the values in the YAML file and the schema default
|
|
|
70
72
|
for omitted settings. It does not inherit the SDK's `OTEL_*` environment-variable
|
|
71
73
|
defaults.
|
|
72
74
|
|
|
75
|
+
To use an environment variable in the file, reference it in a value as
|
|
76
|
+
`${NAME}`, `${env:NAME}`, or `${NAME:-default}`. The default applies when the
|
|
77
|
+
variable is unset or empty. Use `$$` for a literal `$`. Values are typed after
|
|
78
|
+
substitution, so quote a reference to keep it a string.
|
|
79
|
+
|
|
80
|
+
```yaml
|
|
81
|
+
resource:
|
|
82
|
+
attributes:
|
|
83
|
+
- name: service.name
|
|
84
|
+
value: ${OTEL_SERVICE_NAME:-unknown_service}
|
|
85
|
+
tracer_provider:
|
|
86
|
+
processors:
|
|
87
|
+
- batch:
|
|
88
|
+
exporter:
|
|
89
|
+
otlp_http:
|
|
90
|
+
endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318}/v1/traces
|
|
91
|
+
```
|
|
92
|
+
|
|
73
93
|
Some Ruby-specific SDK settings have no equivalent in the configuration schema:
|
|
74
94
|
|
|
75
95
|
- `OTEL_RUBY_BSP_START_THREAD_ON_BOOT` is ignored. A configured batch span
|
|
@@ -185,6 +205,35 @@ propagator:
|
|
|
185
205
|
|
|
186
206
|
Supported propagator names: `tracecontext`, `baggage`, `b3`, `b3multi`, `jaeger`, `ottrace`, `xray`, `google_cloud_trace_context`.
|
|
187
207
|
|
|
208
|
+
### Logs
|
|
209
|
+
|
|
210
|
+
Logs support is optional. Add `opentelemetry-logs-sdk` to your Gemfile, along with `opentelemetry-exporter-otlp-logs` if you use the `otlp_http` exporter, and require them before calling `configure`. If a required gem isn't loaded, the logger provider or processor that needs it is skipped with a warning.
|
|
211
|
+
|
|
212
|
+
```ruby
|
|
213
|
+
require 'opentelemetry-sdk'
|
|
214
|
+
require 'opentelemetry-logs-sdk'
|
|
215
|
+
require 'opentelemetry-exporter-otlp-logs'
|
|
216
|
+
require 'opentelemetry-config'
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
The configured logger provider is installed as `OpenTelemetry.logger_provider`.
|
|
220
|
+
|
|
221
|
+
```yaml
|
|
222
|
+
logger_provider:
|
|
223
|
+
limits:
|
|
224
|
+
attribute_count_limit: 128
|
|
225
|
+
processors:
|
|
226
|
+
- batch:
|
|
227
|
+
exporter:
|
|
228
|
+
otlp_http:
|
|
229
|
+
endpoint: http://localhost:4318/v1/logs
|
|
230
|
+
- simple:
|
|
231
|
+
exporter:
|
|
232
|
+
console:
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Supported processors: `batch`, `simple`. Supported exporters: `console`, `otlp_http`.
|
|
236
|
+
|
|
188
237
|
## Examples
|
|
189
238
|
|
|
190
239
|
A runnable example application is available in the [`example/`][example-dir] directory. It demonstrates traces configured from YAML with console output.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright The OpenTelemetry Authors
|
|
4
|
+
#
|
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
6
|
+
|
|
7
|
+
module OpenTelemetry
|
|
8
|
+
module Config
|
|
9
|
+
# Loads configuration file YAML with environment variable substitution.
|
|
10
|
+
#
|
|
11
|
+
# References of the form +${NAME}+, +${env:NAME}+, and +${NAME:-default}+ are
|
|
12
|
+
# replaced in scalar values, and +$$+ escapes a literal +$+. Mapping keys are
|
|
13
|
+
# left untouched. Types are resolved after substitution, so a plain
|
|
14
|
+
# +${PORT}+ loads as an Integer while a quoted +"${PORT}"+ stays a String.
|
|
15
|
+
module EnvSubstitution
|
|
16
|
+
# Raised when a configuration file contains an invalid substitution reference.
|
|
17
|
+
class Error < StandardError; end
|
|
18
|
+
|
|
19
|
+
# A colon followed by "-" starts a default value, not a prefix.
|
|
20
|
+
REFERENCE = /\$\{(?:(?<prefix>[a-zA-Z][a-zA-Z0-9_]*):(?!-))?(?<content>[^}]+)\}/
|
|
21
|
+
ENV_REFERENCE = /\A(?<name>[a-zA-Z_][a-zA-Z0-9_]*)(?::-(?<default>[^\n]*))?\z/
|
|
22
|
+
PERMITTED_CLASSES = %w[Date Time].freeze
|
|
23
|
+
private_constant :REFERENCE, :ENV_REFERENCE, :PERMITTED_CLASSES
|
|
24
|
+
|
|
25
|
+
module_function
|
|
26
|
+
|
|
27
|
+
# Parses YAML and substitutes environment variables in its scalar values.
|
|
28
|
+
#
|
|
29
|
+
# @param content [String] YAML document
|
|
30
|
+
# @param env [Hash{String => String}] environment variables to substitute
|
|
31
|
+
# @return [Object, nil] the loaded document, or nil when it is empty
|
|
32
|
+
# @raise [Error] when a substitution reference is invalid
|
|
33
|
+
# @raise [Psych::Exception] when the YAML is invalid or uses a disallowed
|
|
34
|
+
# class or alias
|
|
35
|
+
def load(content, env = ENV)
|
|
36
|
+
document = Psych.parse(content)
|
|
37
|
+
return unless document
|
|
38
|
+
|
|
39
|
+
substitute_node(document, env)
|
|
40
|
+
|
|
41
|
+
class_loader = Psych::ClassLoader::Restricted.new(PERMITTED_CLASSES, [])
|
|
42
|
+
scanner = Psych::ScalarScanner.new(class_loader)
|
|
43
|
+
Psych::Visitors::NoAliasRuby.new(scanner, class_loader).accept(document)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Substitutes environment variable references in a string.
|
|
47
|
+
#
|
|
48
|
+
# @param value [String]
|
|
49
|
+
# @param env [Hash{String => String}] environment variables to substitute
|
|
50
|
+
# @return [String]
|
|
51
|
+
# @raise [Error] when a substitution reference is invalid
|
|
52
|
+
def substitute(value, env = ENV)
|
|
53
|
+
# Split on escapes first so a "$" they produce never starts a reference.
|
|
54
|
+
value.split('$$', -1).map do |segment|
|
|
55
|
+
segment.gsub(REFERENCE) { resolve(Regexp.last_match, env) }
|
|
56
|
+
end.join('$')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Substitutes scalar values in a node tree, skipping mapping keys.
|
|
60
|
+
def substitute_node(node, env)
|
|
61
|
+
case node
|
|
62
|
+
when Psych::Nodes::Scalar
|
|
63
|
+
node.value = substitute(node.value, env)
|
|
64
|
+
when Psych::Nodes::Mapping
|
|
65
|
+
node.children.each_slice(2) { |_key, value| substitute_node(value, env) }
|
|
66
|
+
else
|
|
67
|
+
Array(node.children).each { |child| substitute_node(child, env) }
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Returns the replacement for a matched reference.
|
|
72
|
+
def resolve(match, env)
|
|
73
|
+
reference = ENV_REFERENCE.match(match[:content]) if match[:prefix].nil? || match[:prefix] == 'env'
|
|
74
|
+
raise Error, "invalid substitution reference #{match[0]}" unless reference
|
|
75
|
+
|
|
76
|
+
value = env[reference[:name]]
|
|
77
|
+
return value unless value.nil? || value.empty?
|
|
78
|
+
|
|
79
|
+
reference[:default].to_s
|
|
80
|
+
end
|
|
81
|
+
private_class_method :substitute_node, :resolve
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -12,6 +12,15 @@ module OpenTelemetry
|
|
|
12
12
|
module Config
|
|
13
13
|
# Generated struct definitions mirroring the OpenTelemetry configuration schema.
|
|
14
14
|
module Model
|
|
15
|
+
# Parses the nullable object at +key+ with +klass+. An explicit null
|
|
16
|
+
# parses as an object with every property omitted.
|
|
17
|
+
def self.nullable_from_hash(klass, h, key)
|
|
18
|
+
return nil unless h.key?(key)
|
|
19
|
+
|
|
20
|
+
value = h[key]
|
|
21
|
+
klass.from_hash(value.nil? ? {} : value)
|
|
22
|
+
end
|
|
23
|
+
|
|
15
24
|
Aggregation = Struct.new(
|
|
16
25
|
:default,
|
|
17
26
|
:drop,
|
|
@@ -27,8 +36,8 @@ module OpenTelemetry
|
|
|
27
36
|
new(
|
|
28
37
|
default: h.key?('default'),
|
|
29
38
|
drop: h.key?('drop'),
|
|
30
|
-
explicit_bucket_histogram:
|
|
31
|
-
base2_exponential_bucket_histogram:
|
|
39
|
+
explicit_bucket_histogram: Model.nullable_from_hash(ExplicitBucketHistogramAggregation, h, 'explicit_bucket_histogram'),
|
|
40
|
+
base2_exponential_bucket_histogram: Model.nullable_from_hash(Base2ExponentialBucketHistogramAggregation, h, 'base2_exponential_bucket_histogram'),
|
|
32
41
|
last_value: h.key?('last_value'),
|
|
33
42
|
sum: h.key?('sum')
|
|
34
43
|
)
|
|
@@ -276,8 +285,8 @@ module OpenTelemetry
|
|
|
276
285
|
always_off: h.key?('always_off'),
|
|
277
286
|
always_on: h.key?('always_on'),
|
|
278
287
|
parent_threshold: ExperimentalComposableParentThresholdSampler.from_hash(h['parent_threshold']),
|
|
279
|
-
probability:
|
|
280
|
-
rule_based:
|
|
288
|
+
probability: Model.nullable_from_hash(ExperimentalComposableProbabilitySampler, h, 'probability'),
|
|
289
|
+
rule_based: Model.nullable_from_hash(ExperimentalComposableRuleBasedSampler, h, 'rule_based'),
|
|
281
290
|
additional_properties: h.except('always_off', 'always_on', 'parent_threshold', 'probability', 'rule_based')
|
|
282
291
|
)
|
|
283
292
|
end
|
|
@@ -736,9 +745,9 @@ module OpenTelemetry
|
|
|
736
745
|
return nil unless h.is_a?(Hash)
|
|
737
746
|
|
|
738
747
|
new(
|
|
739
|
-
otlp_http:
|
|
740
|
-
otlp_grpc:
|
|
741
|
-
otlp_file_development:
|
|
748
|
+
otlp_http: Model.nullable_from_hash(OtlpHttpExporter, h, 'otlp_http'),
|
|
749
|
+
otlp_grpc: Model.nullable_from_hash(OtlpGrpcExporter, h, 'otlp_grpc'),
|
|
750
|
+
otlp_file_development: Model.nullable_from_hash(ExperimentalOtlpFileExporter, h, 'otlp_file/development'),
|
|
742
751
|
console: h.key?('console'),
|
|
743
752
|
additional_properties: h.except('otlp_http', 'otlp_grpc', 'otlp_file/development', 'console')
|
|
744
753
|
)
|
|
@@ -907,7 +916,7 @@ module OpenTelemetry
|
|
|
907
916
|
|
|
908
917
|
new(
|
|
909
918
|
endpoint: h['endpoint'],
|
|
910
|
-
tls:
|
|
919
|
+
tls: Model.nullable_from_hash(GrpcTls, h, 'tls'),
|
|
911
920
|
headers: Array(h['headers']).filter_map { |e| NameStringValuePair.from_hash(e) },
|
|
912
921
|
headers_list: h['headers_list'],
|
|
913
922
|
compression: h['compression'],
|
|
@@ -932,7 +941,7 @@ module OpenTelemetry
|
|
|
932
941
|
|
|
933
942
|
new(
|
|
934
943
|
endpoint: h['endpoint'],
|
|
935
|
-
tls:
|
|
944
|
+
tls: Model.nullable_from_hash(GrpcTls, h, 'tls'),
|
|
936
945
|
headers: Array(h['headers']).filter_map { |e| NameStringValuePair.from_hash(e) },
|
|
937
946
|
headers_list: h['headers_list'],
|
|
938
947
|
compression: h['compression'],
|
|
@@ -958,7 +967,7 @@ module OpenTelemetry
|
|
|
958
967
|
|
|
959
968
|
new(
|
|
960
969
|
endpoint: h['endpoint'],
|
|
961
|
-
tls:
|
|
970
|
+
tls: Model.nullable_from_hash(HttpTls, h, 'tls'),
|
|
962
971
|
headers: Array(h['headers']).filter_map { |e| NameStringValuePair.from_hash(e) },
|
|
963
972
|
headers_list: h['headers_list'],
|
|
964
973
|
compression: h['compression'],
|
|
@@ -985,7 +994,7 @@ module OpenTelemetry
|
|
|
985
994
|
|
|
986
995
|
new(
|
|
987
996
|
endpoint: h['endpoint'],
|
|
988
|
-
tls:
|
|
997
|
+
tls: Model.nullable_from_hash(HttpTls, h, 'tls'),
|
|
989
998
|
headers: Array(h['headers']).filter_map { |e| NameStringValuePair.from_hash(e) },
|
|
990
999
|
headers_list: h['headers_list'],
|
|
991
1000
|
compression: h['compression'],
|
|
@@ -1063,7 +1072,7 @@ module OpenTelemetry
|
|
|
1063
1072
|
return nil unless h.is_a?(Hash)
|
|
1064
1073
|
|
|
1065
1074
|
new(
|
|
1066
|
-
prometheus_development:
|
|
1075
|
+
prometheus_development: Model.nullable_from_hash(ExperimentalPrometheusMetricExporter, h, 'prometheus/development'),
|
|
1067
1076
|
additional_properties: h.except('prometheus/development')
|
|
1068
1077
|
)
|
|
1069
1078
|
end
|
|
@@ -1098,10 +1107,10 @@ module OpenTelemetry
|
|
|
1098
1107
|
return nil unless h.is_a?(Hash)
|
|
1099
1108
|
|
|
1100
1109
|
new(
|
|
1101
|
-
otlp_http:
|
|
1102
|
-
otlp_grpc:
|
|
1103
|
-
otlp_file_development:
|
|
1104
|
-
console:
|
|
1110
|
+
otlp_http: Model.nullable_from_hash(OtlpHttpMetricExporter, h, 'otlp_http'),
|
|
1111
|
+
otlp_grpc: Model.nullable_from_hash(OtlpGrpcMetricExporter, h, 'otlp_grpc'),
|
|
1112
|
+
otlp_file_development: Model.nullable_from_hash(ExperimentalOtlpFileMetricExporter, h, 'otlp_file/development'),
|
|
1113
|
+
console: Model.nullable_from_hash(ConsoleMetricExporter, h, 'console'),
|
|
1105
1114
|
additional_properties: h.except('otlp_http', 'otlp_grpc', 'otlp_file/development', 'console')
|
|
1106
1115
|
)
|
|
1107
1116
|
end
|
|
@@ -1144,10 +1153,10 @@ module OpenTelemetry
|
|
|
1144
1153
|
always_off: h.key?('always_off'),
|
|
1145
1154
|
always_on: h.key?('always_on'),
|
|
1146
1155
|
composite_development: ExperimentalComposableSampler.from_hash(h['composite/development']),
|
|
1147
|
-
jaeger_remote_development:
|
|
1148
|
-
parent_based:
|
|
1149
|
-
probability_development:
|
|
1150
|
-
trace_id_ratio_based:
|
|
1156
|
+
jaeger_remote_development: Model.nullable_from_hash(ExperimentalJaegerRemoteSampler, h, 'jaeger_remote/development'),
|
|
1157
|
+
parent_based: Model.nullable_from_hash(ParentBasedSampler, h, 'parent_based'),
|
|
1158
|
+
probability_development: Model.nullable_from_hash(ExperimentalProbabilitySampler, h, 'probability/development'),
|
|
1159
|
+
trace_id_ratio_based: Model.nullable_from_hash(TraceIdRatioBasedSampler, h, 'trace_id_ratio_based'),
|
|
1151
1160
|
additional_properties: h.except('always_off', 'always_on', 'composite/development', 'jaeger_remote/development', 'parent_based', 'probability/development', 'trace_id_ratio_based')
|
|
1152
1161
|
)
|
|
1153
1162
|
end
|
|
@@ -1191,9 +1200,9 @@ module OpenTelemetry
|
|
|
1191
1200
|
return nil unless h.is_a?(Hash)
|
|
1192
1201
|
|
|
1193
1202
|
new(
|
|
1194
|
-
otlp_http:
|
|
1195
|
-
otlp_grpc:
|
|
1196
|
-
otlp_file_development:
|
|
1203
|
+
otlp_http: Model.nullable_from_hash(OtlpHttpExporter, h, 'otlp_http'),
|
|
1204
|
+
otlp_grpc: Model.nullable_from_hash(OtlpGrpcExporter, h, 'otlp_grpc'),
|
|
1205
|
+
otlp_file_development: Model.nullable_from_hash(ExperimentalOtlpFileExporter, h, 'otlp_file/development'),
|
|
1197
1206
|
console: h.key?('console'),
|
|
1198
1207
|
additional_properties: h.except('otlp_http', 'otlp_grpc', 'otlp_file/development', 'console')
|
|
1199
1208
|
)
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright The OpenTelemetry Authors
|
|
4
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
|
|
6
|
+
module OpenTelemetry
|
|
7
|
+
module Config
|
|
8
|
+
# Logs component builder for configuring LoggerProvider from declarative config.
|
|
9
|
+
module Logs
|
|
10
|
+
module_function
|
|
11
|
+
|
|
12
|
+
# Builds a LoggerProvider from the parsed YAML logger_provider config.
|
|
13
|
+
# Returns nil if config is nil or opentelemetry-logs-sdk isn't loaded.
|
|
14
|
+
def build_logger_provider(config, resource)
|
|
15
|
+
return unless config
|
|
16
|
+
|
|
17
|
+
unless defined?(OpenTelemetry::SDK::Logs::LoggerProvider)
|
|
18
|
+
OpenTelemetry.logger.warn('logger_provider is configured but opentelemetry-logs-sdk is not loaded. ' \
|
|
19
|
+
'Add `gem "opentelemetry-logs-sdk"` to your Gemfile.')
|
|
20
|
+
return
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
lp = OpenTelemetry::SDK::Logs::LoggerProvider.new(
|
|
24
|
+
resource: resource,
|
|
25
|
+
log_record_limits: build_log_record_limits(config.limits)
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
Array(config.processors).each do |proc_cfg|
|
|
29
|
+
lp.add_log_record_processor(build_log_record_processor(proc_cfg))
|
|
30
|
+
rescue StandardError => e
|
|
31
|
+
OpenTelemetry.logger.warn("Failed to build log record processor: #{e.message}")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
lp
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Builds a log record processor (simple or batch) from config.
|
|
38
|
+
def build_log_record_processor(proc_cfg)
|
|
39
|
+
raise ArgumentError, 'must not specify multiple log record processor types' if proc_cfg.batch && proc_cfg.simple
|
|
40
|
+
|
|
41
|
+
if proc_cfg.batch
|
|
42
|
+
build_batch_log_record_processor(proc_cfg.batch)
|
|
43
|
+
elsif proc_cfg.simple
|
|
44
|
+
build_simple_log_record_processor(proc_cfg.simple)
|
|
45
|
+
else
|
|
46
|
+
raise ArgumentError, 'unsupported log record processor type, must be one of simple or batch'
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Builds a BatchLogRecordProcessor with exporter and optional tuning options.
|
|
51
|
+
def build_batch_log_record_processor(cfg)
|
|
52
|
+
exporter = build_log_record_exporter(cfg.exporter)
|
|
53
|
+
opts = {
|
|
54
|
+
schedule_delay: cfg.schedule_delay&.to_f,
|
|
55
|
+
exporter_timeout: cfg.export_timeout&.to_f,
|
|
56
|
+
max_queue_size: cfg.max_queue_size&.to_i,
|
|
57
|
+
max_export_batch_size: cfg.max_export_batch_size&.to_i
|
|
58
|
+
}.compact
|
|
59
|
+
|
|
60
|
+
OpenTelemetry::SDK::Logs::Export::BatchLogRecordProcessor.new(exporter, **opts)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Builds a SimpleLogRecordProcessor wrapping the configured exporter.
|
|
64
|
+
def build_simple_log_record_processor(cfg)
|
|
65
|
+
OpenTelemetry::SDK::Logs::Export::SimpleLogRecordProcessor.new(build_log_record_exporter(cfg.exporter))
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Builds a log record exporter from config; supports console and otlp_http.
|
|
69
|
+
def build_log_record_exporter(exp_cfg)
|
|
70
|
+
raise ArgumentError, 'no exporter config' unless exp_cfg
|
|
71
|
+
|
|
72
|
+
configured = 0
|
|
73
|
+
exporter = nil
|
|
74
|
+
|
|
75
|
+
if exp_cfg.console
|
|
76
|
+
configured += 1
|
|
77
|
+
exporter = OpenTelemetry::SDK::Logs::Export::ConsoleLogRecordExporter.new
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
if exp_cfg.otlp_http
|
|
81
|
+
configured += 1
|
|
82
|
+
exporter = build_otlp_http_log_record_exporter(exp_cfg.otlp_http)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
raise ArgumentError, 'must not specify multiple exporters' if configured > 1
|
|
86
|
+
raise ArgumentError, 'no valid log record exporter' if exporter.nil?
|
|
87
|
+
|
|
88
|
+
exporter
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Builds an OTLP HTTP log record exporter from the given endpoint, headers, and TLS config.
|
|
92
|
+
def build_otlp_http_log_record_exporter(cfg)
|
|
93
|
+
unless defined?(OpenTelemetry::Exporter::OTLP::Logs::LogsExporter)
|
|
94
|
+
raise ArgumentError, 'otlp_http requires opentelemetry-exporter-otlp-logs. ' \
|
|
95
|
+
'Add `gem "opentelemetry-exporter-otlp-logs"` to your Gemfile.'
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
headers = Trace.headers_to_hash(cfg)
|
|
99
|
+
opts = {
|
|
100
|
+
endpoint: cfg.endpoint,
|
|
101
|
+
certificate_file: cfg.tls&.ca_file,
|
|
102
|
+
client_certificate_file: cfg.tls&.cert_file,
|
|
103
|
+
client_key_file: cfg.tls&.key_file,
|
|
104
|
+
headers: headers.empty? ? nil : headers,
|
|
105
|
+
compression: cfg.compression,
|
|
106
|
+
timeout: cfg.timeout && (cfg.timeout / 1000.0)
|
|
107
|
+
}.compact
|
|
108
|
+
|
|
109
|
+
OpenTelemetry::Exporter::OTLP::Logs::LogsExporter.new(**opts)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Builds LogRecordLimits from config; returns the SDK default when config is nil.
|
|
113
|
+
def build_log_record_limits(limits_cfg)
|
|
114
|
+
return OpenTelemetry::SDK::Logs::LogRecordLimits::DEFAULT unless limits_cfg
|
|
115
|
+
|
|
116
|
+
opts = {
|
|
117
|
+
attribute_count_limit: limits_cfg.attribute_count_limit,
|
|
118
|
+
attribute_length_limit: limits_cfg.attribute_value_length_limit
|
|
119
|
+
}.compact
|
|
120
|
+
|
|
121
|
+
OpenTelemetry::SDK::Logs::LogRecordLimits.new(**opts)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
private_constant :Logs
|
|
126
|
+
end
|
|
127
|
+
end
|
|
@@ -31,7 +31,7 @@ module OpenTelemetry
|
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
OpenTelemetry.logger.warn('Config: schema_url is supported; ignoring.') if resource_cfg.schema_url
|
|
34
|
+
OpenTelemetry.logger.warn('Config: schema_url is not supported; ignoring.') if resource_cfg.schema_url
|
|
35
35
|
|
|
36
36
|
attrs = detected.merge(explicit)
|
|
37
37
|
custom = OpenTelemetry::SDK::Resources::Resource.create(attrs)
|
data/lib/opentelemetry/config.rb
CHANGED
|
@@ -7,6 +7,8 @@ require 'date'
|
|
|
7
7
|
require 'yaml'
|
|
8
8
|
|
|
9
9
|
require_relative 'config/defaults'
|
|
10
|
+
require_relative 'config/env_substitution'
|
|
11
|
+
require_relative 'config/logs'
|
|
10
12
|
require_relative 'config/propagation'
|
|
11
13
|
require_relative 'config/resource'
|
|
12
14
|
require_relative 'config/constants'
|
|
@@ -48,13 +50,16 @@ module OpenTelemetry
|
|
|
48
50
|
end
|
|
49
51
|
|
|
50
52
|
content = File.read(path)
|
|
51
|
-
OpenTelemetry::Config::Model::OpenTelemetryConfiguration.from_hash(
|
|
53
|
+
OpenTelemetry::Config::Model::OpenTelemetryConfiguration.from_hash(EnvSubstitution.load(content))
|
|
52
54
|
rescue Errno::ENOENT => e
|
|
53
55
|
OpenTelemetry.logger.error("Config file not found: #{e.message}")
|
|
54
56
|
nil
|
|
55
57
|
rescue Psych::SyntaxError => e
|
|
56
58
|
OpenTelemetry.logger.error("YAML parse error: #{e.message}")
|
|
57
59
|
nil
|
|
60
|
+
rescue EnvSubstitution::Error => e
|
|
61
|
+
OpenTelemetry.logger.error("Config file substitution error: #{e.message}")
|
|
62
|
+
nil
|
|
58
63
|
end
|
|
59
64
|
|
|
60
65
|
# Creates the components described by a configuration model without
|
|
@@ -81,11 +86,13 @@ module OpenTelemetry
|
|
|
81
86
|
|
|
82
87
|
# tracer_provider will be noop if opentelemetry-sdk is not installed
|
|
83
88
|
tracer_provider = Trace.build_tracer_provider(config.tracer_provider, resource)
|
|
89
|
+
logger_provider = Logs.build_logger_provider(config.logger_provider, resource)
|
|
84
90
|
|
|
85
91
|
propagators = configure_propagation(config.propagator)
|
|
86
92
|
|
|
87
93
|
RubySDK.new(
|
|
88
94
|
tracer_provider: tracer_provider,
|
|
95
|
+
logger_provider: logger_provider,
|
|
89
96
|
propagator: propagators,
|
|
90
97
|
resource: resource
|
|
91
98
|
)
|
|
@@ -100,9 +107,21 @@ module OpenTelemetry
|
|
|
100
107
|
return ruby_sdk if ruby_sdk.equal?(NOOP_SDK)
|
|
101
108
|
|
|
102
109
|
OpenTelemetry.tracer_provider = ruby_sdk.tracer_provider if ruby_sdk.tracer_provider
|
|
110
|
+
install_logger_provider(ruby_sdk.logger_provider) if ruby_sdk.logger_provider
|
|
103
111
|
OpenTelemetry.propagation = ruby_sdk.propagator if ruby_sdk.propagator
|
|
104
112
|
ruby_sdk
|
|
105
113
|
end
|
|
114
|
+
|
|
115
|
+
private
|
|
116
|
+
|
|
117
|
+
def install_logger_provider(provider)
|
|
118
|
+
if OpenTelemetry.respond_to?(:logger_provider=)
|
|
119
|
+
OpenTelemetry.logger_provider = provider
|
|
120
|
+
else
|
|
121
|
+
OpenTelemetry.logger.warn('Cannot install the configured logger provider: OpenTelemetry.logger_provider= ' \
|
|
122
|
+
'is not defined. Require opentelemetry-logs-sdk.')
|
|
123
|
+
end
|
|
124
|
+
end
|
|
106
125
|
end
|
|
107
126
|
end
|
|
108
127
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: opentelemetry-config
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- OpenTelemetry Authors
|
|
@@ -43,14 +43,14 @@ dependencies:
|
|
|
43
43
|
requirements:
|
|
44
44
|
- - "~>"
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: 0.34
|
|
46
|
+
version: '0.34'
|
|
47
47
|
type: :runtime
|
|
48
48
|
prerelease: false
|
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: 0.34
|
|
53
|
+
version: '0.34'
|
|
54
54
|
- !ruby/object:Gem::Dependency
|
|
55
55
|
name: opentelemetry-sdk
|
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -79,7 +79,9 @@ files:
|
|
|
79
79
|
- lib/opentelemetry/config.rb
|
|
80
80
|
- lib/opentelemetry/config/constants.rb
|
|
81
81
|
- lib/opentelemetry/config/defaults.rb
|
|
82
|
+
- lib/opentelemetry/config/env_substitution.rb
|
|
82
83
|
- lib/opentelemetry/config/generated_constants.rb
|
|
84
|
+
- lib/opentelemetry/config/logs.rb
|
|
83
85
|
- lib/opentelemetry/config/propagation.rb
|
|
84
86
|
- lib/opentelemetry/config/resource.rb
|
|
85
87
|
- lib/opentelemetry/config/trace.rb
|
|
@@ -88,10 +90,10 @@ homepage: https://github.com/open-telemetry/opentelemetry-ruby
|
|
|
88
90
|
licenses:
|
|
89
91
|
- Apache-2.0
|
|
90
92
|
metadata:
|
|
91
|
-
changelog_uri: https://rubydoc.info/gems/opentelemetry-config/0.
|
|
92
|
-
source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby/tree/opentelemetry-config/v0.
|
|
93
|
+
changelog_uri: https://rubydoc.info/gems/opentelemetry-config/0.2.0/file/CHANGELOG.md
|
|
94
|
+
source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby/tree/opentelemetry-config/v0.2.0/config
|
|
93
95
|
bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby/issues
|
|
94
|
-
documentation_uri: https://rubydoc.info/gems/opentelemetry-config/0.
|
|
96
|
+
documentation_uri: https://rubydoc.info/gems/opentelemetry-config/0.2.0
|
|
95
97
|
rdoc_options: []
|
|
96
98
|
require_paths:
|
|
97
99
|
- lib
|