nexus_semantic_logger 1.11.6 → 1.12

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c3f367c4597a558ce34338e3378f03c014de4745b3fa3b107629eb28c4be03d0
4
- data.tar.gz: 06b199a9c633825110cefdc2bd10272dff2d6e88340b1fd91296994108236b6e
3
+ metadata.gz: 70e0537b45679788fc9dc6ce2c5e6ae6698e840735039bfc8d55ac324e03d062
4
+ data.tar.gz: 6a489153ff7db8a3d2bca5696a3ceec917014f9e10416f3a04f5446114a0514b
5
5
  SHA512:
6
- metadata.gz: a071e056de2fd4a4a86112b382b3de49a3d6b0d80beca2a430141fbef69aa3075a3082d9a59f211c10040c4999a4d7eca4c7e72470275ef1f229011842a794c3
7
- data.tar.gz: 2814af602f6693ab6076cbf2d1c922c5cbefb8b8ae5520bf03efc6860c8448fb95e7cee81325aae98d1bcf707ff8dc23ec4fc309ea77ab4ae7e41274501da7f3
6
+ metadata.gz: 25f789b5449465c5466d74c780cfb6401e4c5f4df493b40d616f55de5d986366d3d677b69ea1ce51f20e7c94ce71c7e896ec3c61470969db96c213a5c8ad26d8
7
+ data.tar.gz: a28d97cf7fa44c87511388145e38f2132e1787f711995523226ce388c5c4260ae59c5a975e52daa072bc11273f5fb6698b10ee5ebec3e21b43479b3f59bbfd33
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module NexusSemanticLogger
3
- # Leave this as 1.11.6 in order for CI process to replace with the tagged version.
4
- VERSION = '1.11.6'
3
+ # Leave this as 1.12 in order for CI process to replace with the tagged version.
4
+ VERSION = '1.12'
5
5
  end
@@ -0,0 +1 @@
1
+ Forked from https://github.com/yob/puma-plugin-statsd
@@ -0,0 +1,222 @@
1
+ # frozen_string_literal: true
2
+ require 'puma'
3
+ require 'puma/plugin'
4
+ require 'socket'
5
+ require 'nexus_semantic_logger/datadog_singleton'
6
+
7
+ # Forked from puma-plugin-statsd.
8
+ # Uses the same datadog settings as nexus_semantic_logger.
9
+ # To use, add to puma.rb:
10
+ # plugin :nexus_puma_statsd
11
+ class StatsdConnector
12
+ STATSD_TYPES = { count: 'c', gauge: 'g' }
13
+ METRIC_DELIMETER = "."
14
+
15
+ attr_reader :host, :port
16
+
17
+ def initialize
18
+ @host = ENV.fetch('DD_AGENT_HOST', '127.0.0.1')
19
+ @port = ENV.fetch('DD_STATSD_PORT', 8125)
20
+ @socket_path = ENV.fetch('DD_STATSD_SOCKET_PATH', '')
21
+ end
22
+
23
+ def send(metric_name:, value:, type:, tags: nil)
24
+ data = "#{metric_name}:#{value}|#{STATSD_TYPES.fetch(type)}"
25
+ data = "#{data}|##{tags}" unless tags.nil?
26
+
27
+ if @socket_path.to_s.strip.empty?
28
+ socket = UDPSocket.new
29
+ socket.send(data, 0, host, port)
30
+ else
31
+ socket = Socket.new(Socket::AF_UNIX, Socket::SOCK_DGRAM)
32
+ socket.connect(Socket.pack_sockaddr_un(@socket_path))
33
+ socket.sendmsg_nonblock(data)
34
+ end
35
+ ensure
36
+ socket.close
37
+ end
38
+ end
39
+
40
+ # Wrap puma's stats in a safe API
41
+ class PumaStats
42
+ def initialize(stats)
43
+ @stats = stats
44
+ end
45
+
46
+ def clustered?
47
+ @stats.key?(:workers)
48
+ end
49
+
50
+ def workers
51
+ @stats.fetch(:workers, 1)
52
+ end
53
+
54
+ def booted_workers
55
+ @stats.fetch(:booted_workers, 1)
56
+ end
57
+
58
+ def old_workers
59
+ @stats.fetch(:old_workers, 0)
60
+ end
61
+
62
+ def running
63
+ if clustered?
64
+ @stats[:worker_status].map { |s| s[:last_status].fetch(:running, 0) }.inject(0, &:+)
65
+ else
66
+ @stats.fetch(:running, 0)
67
+ end
68
+ end
69
+
70
+ def backlog
71
+ if clustered?
72
+ @stats[:worker_status].map { |s| s[:last_status].fetch(:backlog, 0) }.inject(0, &:+)
73
+ else
74
+ @stats.fetch(:backlog, 0)
75
+ end
76
+ end
77
+
78
+ def pool_capacity
79
+ if clustered?
80
+ @stats[:worker_status].map { |s| s[:last_status].fetch(:pool_capacity, 0) }.inject(0, &:+)
81
+ else
82
+ @stats.fetch(:pool_capacity, 0)
83
+ end
84
+ end
85
+
86
+ def max_threads
87
+ if clustered?
88
+ @stats[:worker_status].map { |s| s[:last_status].fetch(:max_threads, 0) }.inject(0, &:+)
89
+ else
90
+ @stats.fetch(:max_threads, 0)
91
+ end
92
+ end
93
+
94
+ def requests_count
95
+ if clustered?
96
+ @stats[:worker_status].map { |s| s[:last_status].fetch(:requests_count, 0) }.inject(0, &:+)
97
+ else
98
+ @stats.fetch(:requests_count, 0)
99
+ end
100
+ end
101
+ end
102
+
103
+ Puma::Plugin.create do
104
+ # We can start doing something when we have a launcher:
105
+ def start(launcher)
106
+ @launcher = launcher
107
+ @log_writer =
108
+ if Gem::Version.new(Puma::Const::PUMA_VERSION) >= Gem::Version.new(6)
109
+ @launcher.log_writer
110
+ else
111
+ @launcher.events
112
+ end
113
+
114
+ @statsd = ::StatsdConnector.new
115
+ @log_writer.debug("statsd: enabled (host: #{@statsd.host})")
116
+
117
+ # Fetch global metric prefix from env variable
118
+ @metric_prefix = ENV.fetch('DD_STATSD_METRIC_PREFIX', nil)
119
+ if @metric_prefix && !@metric_prefix.end_with?(::StatsdConnector::METRIC_DELIMETER)
120
+ @metric_prefix += ::StatsdConnector::METRIC_DELIMETER
121
+ end
122
+
123
+ register_hooks
124
+ end
125
+
126
+ private
127
+
128
+ def register_hooks
129
+ in_background(&method(:stats_loop))
130
+ end
131
+
132
+ def environment_variable_tags
133
+ # Tags are separated by spaces, and while they are normally a tag and
134
+ # value separated by a ':', they can also just be tagged without any
135
+ # associated value.
136
+ #
137
+ # Examples: simple-tag-0 tag-key-1:tag-value-1
138
+ #
139
+ tags = []
140
+ global_tags = NexusSemanticLogger::DatadogSingleton.instance.global_tags
141
+ tags += global_tags unless global_tags.nil?
142
+
143
+ if ENV.key?('HOSTNAME')
144
+ tags << "pod_name:#{ENV['HOSTNAME']}"
145
+ end
146
+
147
+ # Standardised datadog tag attributes, so that we can share the metric
148
+ # tags with the application running
149
+ #
150
+ # https://docs.datadoghq.com/agent/docker/?tab=standard#global-options
151
+ #
152
+ if ENV.key?("DD_TAGS")
153
+ ENV["DD_TAGS"].split(/\s+|,/).each do |t|
154
+ tags << t
155
+ end
156
+ end
157
+
158
+ # Support the Unified Service Tagging from Datadog, so that we can share
159
+ # the metric tags with the application running
160
+ #
161
+ # https://docs.datadoghq.com/getting_started/tagging/unified_service_tagging
162
+ if ENV.key?('DD_ENV')
163
+ tags << "env:#{ENV['DD_ENV']}"
164
+ end
165
+
166
+ if ENV.key?('DD_SERVICE')
167
+ tags << "service:#{ENV['DD_SERVICE']}"
168
+ end
169
+
170
+ if ENV.key?('DD_VERSION')
171
+ tags << "version:#{ENV['DD_VERSION']}"
172
+ end
173
+
174
+ # Support the origin detection over UDP from Datadog, it allows DogStatsD
175
+ # to detect where the container metrics come from, and tag metrics automatically.
176
+ #
177
+ # https://docs.datadoghq.com/developers/dogstatsd/?tab=kubernetes#origin-detection-over-udp
178
+ if ENV.key?('DD_ENTITY_ID')
179
+ tags << "dd.internal.entity_id:#{ENV['DD_ENTITY_ID']}"
180
+ end
181
+
182
+ # Return nil if we have no environment variable tags. This way we don't
183
+ # send an unnecessary '|' on the end of each stat
184
+ return nil if tags.empty?
185
+
186
+ tags.join(",")
187
+ end
188
+
189
+ def prefixed_metric_name(puma_metric)
190
+ "#{@metric_prefix}#{puma_metric}"
191
+ end
192
+
193
+ # Send data to statsd every few seconds
194
+ def stats_loop
195
+ tags = environment_variable_tags
196
+
197
+ sleep(5)
198
+ loop do
199
+ @log_writer.debug("statsd: notify statsd")
200
+ begin
201
+ stats = ::PumaStats.new(Puma.stats_hash)
202
+ @statsd.send(metric_name: prefixed_metric_name("puma.workers"), value: stats.workers, type: :gauge, tags: tags)
203
+ @statsd.send(metric_name: prefixed_metric_name("puma.booted_workers"), value: stats.booted_workers,
204
+ type: :gauge, tags: tags)
205
+ @statsd.send(metric_name: prefixed_metric_name("puma.old_workers"), value: stats.old_workers, type: :gauge,
206
+ tags: tags)
207
+ @statsd.send(metric_name: prefixed_metric_name("puma.running"), value: stats.running, type: :gauge, tags: tags)
208
+ @statsd.send(metric_name: prefixed_metric_name("puma.backlog"), value: stats.backlog, type: :gauge, tags: tags)
209
+ @statsd.send(metric_name: prefixed_metric_name("puma.pool_capacity"), value: stats.pool_capacity, type: :gauge,
210
+ tags: tags)
211
+ @statsd.send(metric_name: prefixed_metric_name("puma.max_threads"), value: stats.max_threads, type: :gauge,
212
+ tags: tags)
213
+ @statsd.send(metric_name: prefixed_metric_name("puma.requests_count"), value: stats.requests_count,
214
+ type: :gauge, tags: tags)
215
+ rescue StandardError => e
216
+ @log_writer.unknown_error(e, nil, "! statsd: notify stats failed")
217
+ ensure
218
+ sleep(2)
219
+ end
220
+ end
221
+ end
222
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nexus_semantic_logger
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.11.6
4
+ version: '1.12'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Johnathon Harris
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-01 00:00:00.000000000 Z
11
+ date: 2023-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: amazing_print
@@ -116,6 +116,8 @@ files:
116
116
  - lib/nexus_semantic_logger/logger_metrics_subscriber.rb
117
117
  - lib/nexus_semantic_logger/sneakers_metrics.rb
118
118
  - lib/nexus_semantic_logger/version.rb
119
+ - lib/puma/plugin/README.md
120
+ - lib/puma/plugin/nexus_puma_statsd.rb
119
121
  - nexus_semantic_logger.gemspec
120
122
  homepage:
121
123
  licenses: []
@@ -135,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
137
  - !ruby/object:Gem::Version
136
138
  version: '0'
137
139
  requirements: []
138
- rubygems_version: 3.4.7
140
+ rubygems_version: 3.4.13
139
141
  signing_key:
140
142
  specification_version: 4
141
143
  summary: semantic_logger usage for nexus