dalli 4.2.0 → 4.2.1
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 +15 -0
- data/lib/dalli/client.rb +35 -16
- data/lib/dalli/instrumentation.rb +23 -11
- data/lib/dalli/socket.rb +1 -1
- data/lib/dalli/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 533bed149f02ca2960fa436d776b920cce0c95b841296c678a247141f8f7f239
|
|
4
|
+
data.tar.gz: cd3ca6a066d005fd177726b3c29ab460cba9d8ddc9937c1809053bf22b20e387
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cc927b7e0f8906d326ede287b9d0fb9b3c1fb216b271350bc1e02cd4531b86d365e286da73cb8be9082646d747a494ccc0cdd81d0f9f053cf2439dd58bc40157
|
|
7
|
+
data.tar.gz: ce17e49264f9cf1550f709eb6d67a3f0f2f7fefaecfab04bf2c3f4356b7636ff95e2d6f76a44abcd8f0efae79ab8bbf21c5ba7d59a802735626af73e7bf0d777
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
Dalli Changelog
|
|
2
2
|
=====================
|
|
3
3
|
|
|
4
|
+
4.2.1
|
|
5
|
+
==========
|
|
6
|
+
|
|
7
|
+
OpenTelemetry:
|
|
8
|
+
|
|
9
|
+
- Migrate to stable OTel semantic conventions
|
|
10
|
+
- `db.system` renamed to `db.system.name`
|
|
11
|
+
- `db.operation` renamed to `db.operation.name`
|
|
12
|
+
- `server.address` now contains hostname only; `server.port` is a separate integer attribute
|
|
13
|
+
- `get_with_metadata` and `fetch_with_lock` now include `server.address`/`server.port`
|
|
14
|
+
- Add `db.query.text` span attribute with configurable modes
|
|
15
|
+
- `:otel_db_statement` option: `:include`, `:obfuscate`, or `nil` (default: omitted)
|
|
16
|
+
- Add `peer.service` span attribute
|
|
17
|
+
- `:otel_peer_service` option for logical service naming
|
|
18
|
+
|
|
4
19
|
4.2.0
|
|
5
20
|
==========
|
|
6
21
|
|
data/lib/dalli/client.rb
CHANGED
|
@@ -50,6 +50,10 @@ module Dalli
|
|
|
50
50
|
# useful for injecting a FIPS compliant hash object.
|
|
51
51
|
# - :protocol - one of either :binary or :meta, defaulting to :binary. This sets the protocol that Dalli uses
|
|
52
52
|
# to communicate with memcached.
|
|
53
|
+
# - :otel_db_statement - controls the +db.query.text+ span attribute when OpenTelemetry is loaded.
|
|
54
|
+
# +:include+ logs the full operation and key(s), +:obfuscate+ replaces keys with "?",
|
|
55
|
+
# +nil+ (default) omits the attribute entirely.
|
|
56
|
+
# - :otel_peer_service - when set, adds a +peer.service+ span attribute with this value for logical service naming.
|
|
53
57
|
#
|
|
54
58
|
def initialize(servers = nil, options = {})
|
|
55
59
|
@normalized_servers = ::Dalli::ServersArgNormalizer.normalize_servers(servers)
|
|
@@ -134,8 +138,8 @@ module Dalli
|
|
|
134
138
|
key = key.to_s
|
|
135
139
|
key = @key_manager.validate_key(key)
|
|
136
140
|
|
|
137
|
-
|
|
138
|
-
|
|
141
|
+
server = ring.server_for_key(key)
|
|
142
|
+
Instrumentation.trace('get_with_metadata', trace_attrs('get_with_metadata', key, server)) do
|
|
139
143
|
server.request(:meta_get, key, options)
|
|
140
144
|
end
|
|
141
145
|
rescue NetworkError => e
|
|
@@ -237,7 +241,8 @@ module Dalli
|
|
|
237
241
|
key = key.to_s
|
|
238
242
|
key = @key_manager.validate_key(key)
|
|
239
243
|
|
|
240
|
-
|
|
244
|
+
server = ring.server_for_key(key)
|
|
245
|
+
Instrumentation.trace('fetch_with_lock', trace_attrs('fetch_with_lock', key, server)) do
|
|
241
246
|
fetch_with_lock_request(key, ttl, lock_ttl, recache_threshold, req_options, &block)
|
|
242
247
|
end
|
|
243
248
|
rescue NetworkError => e
|
|
@@ -318,10 +323,7 @@ module Dalli
|
|
|
318
323
|
def set_multi(hash, ttl = nil, req_options = nil)
|
|
319
324
|
return if hash.empty?
|
|
320
325
|
|
|
321
|
-
Instrumentation.trace('set_multi',
|
|
322
|
-
'db.operation' => 'set_multi',
|
|
323
|
-
'db.memcached.key_count' => hash.size
|
|
324
|
-
}) do
|
|
326
|
+
Instrumentation.trace('set_multi', multi_trace_attrs('set_multi', hash.size, hash.keys)) do
|
|
325
327
|
pipelined_setter.process(hash, ttl_or_default(ttl), req_options)
|
|
326
328
|
end
|
|
327
329
|
end
|
|
@@ -378,10 +380,7 @@ module Dalli
|
|
|
378
380
|
def delete_multi(keys)
|
|
379
381
|
return if keys.empty?
|
|
380
382
|
|
|
381
|
-
Instrumentation.trace('delete_multi',
|
|
382
|
-
'db.operation' => 'delete_multi',
|
|
383
|
-
'db.memcached.key_count' => keys.size
|
|
384
|
-
}) do
|
|
383
|
+
Instrumentation.trace('delete_multi', multi_trace_attrs('delete_multi', keys.size, keys)) do
|
|
385
384
|
pipelined_deleter.process(keys)
|
|
386
385
|
end
|
|
387
386
|
end
|
|
@@ -548,7 +547,30 @@ module Dalli
|
|
|
548
547
|
end
|
|
549
548
|
|
|
550
549
|
def get_multi_attributes(keys)
|
|
551
|
-
|
|
550
|
+
multi_trace_attrs('get_multi', keys.size, keys)
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
def trace_attrs(operation, key, server)
|
|
554
|
+
attrs = { 'db.operation.name' => operation, 'server.address' => server.hostname }
|
|
555
|
+
attrs['server.port'] = server.port if server.socket_type == :tcp
|
|
556
|
+
attrs['peer.service'] = @options[:otel_peer_service] if @options[:otel_peer_service]
|
|
557
|
+
add_query_text(attrs, operation, key)
|
|
558
|
+
end
|
|
559
|
+
|
|
560
|
+
def multi_trace_attrs(operation, key_count, keys)
|
|
561
|
+
attrs = { 'db.operation.name' => operation, 'db.memcached.key_count' => key_count }
|
|
562
|
+
attrs['peer.service'] = @options[:otel_peer_service] if @options[:otel_peer_service]
|
|
563
|
+
add_query_text(attrs, operation, keys)
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
def add_query_text(attrs, operation, key_or_keys)
|
|
567
|
+
case @options[:otel_db_statement]
|
|
568
|
+
when :include
|
|
569
|
+
attrs['db.query.text'] = "#{operation} #{Array(key_or_keys).join(' ')}"
|
|
570
|
+
when :obfuscate
|
|
571
|
+
attrs['db.query.text'] = "#{operation} ?"
|
|
572
|
+
end
|
|
573
|
+
attrs
|
|
552
574
|
end
|
|
553
575
|
|
|
554
576
|
def check_positive!(amt)
|
|
@@ -616,10 +638,7 @@ module Dalli
|
|
|
616
638
|
key = @key_manager.validate_key(key)
|
|
617
639
|
|
|
618
640
|
server = ring.server_for_key(key)
|
|
619
|
-
Instrumentation.trace(op.to_s,
|
|
620
|
-
'db.operation' => op.to_s,
|
|
621
|
-
'server.address' => server.name
|
|
622
|
-
}) do
|
|
641
|
+
Instrumentation.trace(op.to_s, trace_attrs(op.to_s, key, server)) do
|
|
623
642
|
server.request(op, key, *args)
|
|
624
643
|
end
|
|
625
644
|
rescue NetworkError => e
|
|
@@ -8,25 +8,36 @@ module Dalli
|
|
|
8
8
|
# When OpenTelemetry is loaded, Dalli automatically creates spans for cache operations.
|
|
9
9
|
# When OpenTelemetry is not available, all tracing methods are no-ops with zero overhead.
|
|
10
10
|
#
|
|
11
|
+
# Dalli 4.2.1 uses the stable OTel semantic conventions for database spans.
|
|
12
|
+
#
|
|
11
13
|
# == Span Attributes
|
|
12
14
|
#
|
|
13
15
|
# All spans include the following default attributes:
|
|
14
|
-
# - +db.system+ - Always "memcached"
|
|
16
|
+
# - +db.system.name+ - Always "memcached"
|
|
15
17
|
#
|
|
16
18
|
# Single-key operations (+get+, +set+, +delete+, +incr+, +decr+, etc.) add:
|
|
17
|
-
# - +db.operation+ - The operation name (e.g., "get", "set")
|
|
18
|
-
# - +server.address+ - The
|
|
19
|
+
# - +db.operation.name+ - The operation name (e.g., "get", "set")
|
|
20
|
+
# - +server.address+ - The server hostname (e.g., "localhost")
|
|
21
|
+
# - +server.port+ - The server port as an integer (e.g., 11211); omitted for Unix sockets
|
|
19
22
|
#
|
|
20
23
|
# Multi-key operations (+get_multi+) add:
|
|
21
|
-
# - +db.operation+ - "get_multi"
|
|
24
|
+
# - +db.operation.name+ - "get_multi"
|
|
22
25
|
# - +db.memcached.key_count+ - Number of keys requested
|
|
23
26
|
# - +db.memcached.hit_count+ - Number of keys found in cache
|
|
24
27
|
# - +db.memcached.miss_count+ - Number of keys not found
|
|
25
28
|
#
|
|
26
29
|
# Bulk write operations (+set_multi+, +delete_multi+) add:
|
|
27
|
-
# - +db.operation+ - The operation name
|
|
30
|
+
# - +db.operation.name+ - The operation name
|
|
28
31
|
# - +db.memcached.key_count+ - Number of keys in the operation
|
|
29
32
|
#
|
|
33
|
+
# == Optional Attributes
|
|
34
|
+
#
|
|
35
|
+
# - +db.query.text+ - The operation and key(s), controlled by the +:otel_db_statement+ client option:
|
|
36
|
+
# - +:include+ - Full text (e.g., "get mykey")
|
|
37
|
+
# - +:obfuscate+ - Obfuscated (e.g., "get ?")
|
|
38
|
+
# - +nil+ (default) - Attribute omitted
|
|
39
|
+
# - +peer.service+ - Logical service name, set via the +:otel_peer_service+ client option
|
|
40
|
+
#
|
|
30
41
|
# == Error Handling
|
|
31
42
|
#
|
|
32
43
|
# When an exception occurs during a traced operation:
|
|
@@ -40,8 +51,8 @@ module Dalli
|
|
|
40
51
|
##
|
|
41
52
|
module Instrumentation
|
|
42
53
|
# Default attributes included on all memcached spans.
|
|
43
|
-
# @return [Hash] frozen hash with 'db.system' => 'memcached'
|
|
44
|
-
DEFAULT_ATTRIBUTES = { 'db.system' => 'memcached' }.freeze
|
|
54
|
+
# @return [Hash] frozen hash with 'db.system.name' => 'memcached'
|
|
55
|
+
DEFAULT_ATTRIBUTES = { 'db.system.name' => 'memcached' }.freeze
|
|
45
56
|
|
|
46
57
|
class << self
|
|
47
58
|
# Returns the OpenTelemetry tracer if available, nil otherwise.
|
|
@@ -75,15 +86,16 @@ module Dalli
|
|
|
75
86
|
# @param name [String] the span name (e.g., 'get', 'set', 'delete')
|
|
76
87
|
# @param attributes [Hash] span attributes to merge with defaults.
|
|
77
88
|
# Common attributes include:
|
|
78
|
-
# - 'db.operation' - the operation name
|
|
79
|
-
# - 'server.address' - the
|
|
89
|
+
# - 'db.operation.name' - the operation name
|
|
90
|
+
# - 'server.address' - the server hostname
|
|
91
|
+
# - 'server.port' - the server port (integer)
|
|
80
92
|
# - 'db.memcached.key_count' - number of keys (for multi operations)
|
|
81
93
|
# @yield the cache operation to trace
|
|
82
94
|
# @return [Object] the result of the block
|
|
83
95
|
# @raise [StandardError] re-raises any exception from the block
|
|
84
96
|
#
|
|
85
97
|
# @example Tracing a set operation
|
|
86
|
-
# trace('set', { 'db.operation' => 'set', 'server.address' => 'localhost
|
|
98
|
+
# trace('set', { 'db.operation.name' => 'set', 'server.address' => 'localhost', 'server.port' => 11211 }) do
|
|
87
99
|
# server.set(key, value, ttl)
|
|
88
100
|
# end
|
|
89
101
|
#
|
|
@@ -114,7 +126,7 @@ module Dalli
|
|
|
114
126
|
# @raise [StandardError] re-raises any exception from the block
|
|
115
127
|
#
|
|
116
128
|
# @example Recording hit/miss metrics after get_multi
|
|
117
|
-
# trace_with_result('get_multi', { 'db.operation' => 'get_multi' }) do |span|
|
|
129
|
+
# trace_with_result('get_multi', { 'db.operation.name' => 'get_multi' }) do |span|
|
|
118
130
|
# results = fetch_from_cache(keys)
|
|
119
131
|
# if span
|
|
120
132
|
# span.set_attribute('db.memcached.hit_count', results.size)
|
data/lib/dalli/socket.rb
CHANGED
|
@@ -107,7 +107,7 @@ module Dalli
|
|
|
107
107
|
# aliases TCPSocket#initialize method to #original_resolv_initialize.
|
|
108
108
|
# https://github.com/ruby/resolv-replace/blob/v0.1.1/lib/resolv-replace.rb#L21
|
|
109
109
|
if RUBY_VERSION >= '3.0' &&
|
|
110
|
-
!::TCPSocket.
|
|
110
|
+
!::TCPSocket.private_method_defined?(:original_resolv_initialize)
|
|
111
111
|
sock = new(host, port, connect_timeout: options[:socket_timeout])
|
|
112
112
|
yield(sock)
|
|
113
113
|
else
|
data/lib/dalli/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dalli
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.2.
|
|
4
|
+
version: 4.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter M. Goldstein
|
|
@@ -93,7 +93,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
93
93
|
- !ruby/object:Gem::Version
|
|
94
94
|
version: '0'
|
|
95
95
|
requirements: []
|
|
96
|
-
rubygems_version: 4.0.
|
|
96
|
+
rubygems_version: 4.0.6
|
|
97
97
|
specification_version: 4
|
|
98
98
|
summary: High performance memcached client for Ruby
|
|
99
99
|
test_files: []
|