nexus_semantic_logger 1.11.6 → 1.12

Sign up to get free protection for your applications and to get access to all the features.
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