fluent-plugin-prometheus 2.2.1 → 2.2.2

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: 98f287173d66fb76c109519b9b81e230e13a324dd1b1388b644b57d29aff872a
4
- data.tar.gz: 8bf951166f0a76ebaf12bc55e67c774ee8788f69fd74c60ae9168ab0729424ef
3
+ metadata.gz: a2c3701c496726e677bf8182e4b549d493648b1f639930a7508ead0a07611ed6
4
+ data.tar.gz: c7f62e9dfc1a37d8089e07b41a6704e92fc365c0811b960bb628ffafe01134eb
5
5
  SHA512:
6
- metadata.gz: 4e7f3fae38dd44efa082be764b65d610649aa6d6449d159fffb380bfe71464c79bd7764c492c2518ea6a100105910e9ae38b2e37b6327754b442fc780f81d975
7
- data.tar.gz: 7a5235458808bf4d9eb9b60994688171d45c455c703dcc55062432765b84d9e7e800043bde6e59d4507a45330461e2554b7631ca69fbaa4e2d8fd523ed664625
6
+ metadata.gz: 53f721520289f3ca5f8b7b47fe4c5daf7829fae4e22f4bd6145dffaa1d4d173fc81909576067136299b0e256a55d8b961d432ac15aa16074f73dfb6003b9fbfb
7
+ data.tar.gz: 5cdf65cb05bf988df0cfc255a2af2e0f5b8223e5b54c56d4bbabe081827c111e7e210d45d2256d6f3af9cf4dab9154d2b6aba85c7226a87ebb96b420e9230402
@@ -4,20 +4,30 @@ on:
4
4
  branches: [master]
5
5
  pull_request:
6
6
  branches: [master]
7
+ schedule:
8
+ - cron: '0 0 1 * *'
7
9
  jobs:
10
+ ruby-versions:
11
+ uses: ruby/actions/.github/workflows/ruby_versions.yml@master
12
+ with:
13
+ engine: cruby
14
+ min_version: 2.7
8
15
  build:
16
+ needs: ruby-versions
9
17
  runs-on: ${{ matrix.os }}
10
18
  continue-on-error: ${{ matrix.experimental }}
11
19
  strategy:
12
20
  fail-fast: false
13
21
  matrix:
14
- ruby: [ '3.4', '3.3', '3.2', '3.1', '3.0', '2.7' ]
22
+ ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
23
+ exclude:
24
+ - ruby: head
15
25
  os:
16
26
  - ubuntu-latest
17
27
  experimental: [false]
18
28
  name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
19
29
  steps:
20
- - uses: actions/checkout@v4
30
+ - uses: actions/checkout@v6
21
31
  - uses: ruby/setup-ruby@v1
22
32
  with:
23
33
  ruby-version: ${{ matrix.ruby }}
data/.gitignore CHANGED
@@ -14,3 +14,4 @@
14
14
  *.o
15
15
  *.a
16
16
  mkmf.log
17
+ /vendor/
data/ChangeLog CHANGED
@@ -1,3 +1,7 @@
1
+ Release 2.2.2 - 2026/03/27
2
+
3
+ * in_prometheus: fix: Add IPv6 support for bind parameter (#240)
4
+
1
5
  Release 2.2.1 - 2025/03/24
2
6
 
3
7
  * in_prometheus_tail_monitor: Add throttling metrics as `fluentd_tail_file_throttled`. (GitHub#227)
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # fluent-plugin-prometheus, a plugin for [Fluentd](https://www.fluentd.org)
2
2
 
3
- [![Build Status](https://travis-ci.org/fluent/fluent-plugin-prometheus.svg?branch=master)](https://travis-ci.org/fluent/fluent-plugin-prometheus)
3
+ [![linux](https://github.com/fluent/fluent-plugin-prometheus/actions/workflows/linux.yml/badge.svg)](https://github.com/fluent/fluent-plugin-prometheus/actions/workflows/linux.yml)
4
4
 
5
5
  A fluent plugin that instruments metrics from records and exposes them via web interface. Intended to be used together with a [Prometheus server](https://github.com/prometheus/prometheus).
6
6
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "fluent-plugin-prometheus"
3
- spec.version = "2.2.1"
3
+ spec.version = "2.2.2"
4
4
  spec.authors = ["Masahiro Sano"]
5
5
  spec.email = ["sabottenda@gmail.com"]
6
6
  spec.summary = %q{A fluent plugin that collects metrics and exposes for Prometheus.}
@@ -4,13 +4,20 @@ module Fluent::Plugin
4
4
  class PrometheusInput
5
5
  module AsyncWrapper
6
6
  def do_request(host:, port:, secure:)
7
+ # Format host for URI - bracket IPv6 addresses if not already bracketed
8
+ uri_host = if host.include?(':') && !host.start_with?('[')
9
+ "[#{host}]"
10
+ else
11
+ host
12
+ end
13
+
7
14
  endpoint =
8
15
  if secure
9
16
  context = OpenSSL::SSL::SSLContext.new
10
17
  context.verify_mode = OpenSSL::SSL::VERIFY_NONE
11
- Async::HTTP::Endpoint.parse("https://#{host}:#{port}", ssl_context: context)
18
+ Async::HTTP::Endpoint.parse("https://#{uri_host}:#{port}", ssl_context: context)
12
19
  else
13
- Async::HTTP::Endpoint.parse("http://#{host}:#{port}")
20
+ Async::HTTP::Endpoint.parse("http://#{uri_host}:#{port}")
14
21
  end
15
22
 
16
23
  Async::HTTP::Client.open(endpoint) do |client|
@@ -67,12 +67,25 @@ module Fluent::Plugin
67
67
  def start
68
68
  super
69
69
 
70
+ # Normalize bind address: strip brackets if present (for consistency)
71
+ # Brackets are only for URI formatting, not for socket binding
72
+ @bind = @bind[1..-2] if @bind.start_with?('[') && @bind.end_with?(']')
73
+
70
74
  scheme = @secure ? 'https' : 'http'
71
- log.debug "listening prometheus http server on #{scheme}:://#{@bind}:#{@port}/#{@metrics_path} for worker#{fluentd_worker_id}"
75
+ # Format bind address properly for URLs (add brackets for IPv6)
76
+ bind_display = @bind.include?(':') ? "[#{@bind}]" : @bind
77
+ log.debug "listening prometheus http server on #{scheme}://#{bind_display}:#{@port}/#{@metrics_path} for worker#{fluentd_worker_id}"
72
78
 
73
79
  proto = @secure ? :tls : :tcp
74
80
 
75
- if @ssl && @ssl['enable'] && @ssl['extra_conf']
81
+ # IPv6 + TLS combination is not currently supported
82
+ if @bind.include?(':') && @secure
83
+ raise Fluent::ConfigError, 'IPv6 with <transport tls> is not currently supported. Use bind 0.0.0.0 with TLS, or bind ::1 without TLS.'
84
+ end
85
+
86
+ # Use webrick for IPv6 or SSL extra_conf
87
+ # The http_server helper has issues with IPv6 URI construction
88
+ if (@ssl && @ssl['enable'] && @ssl['extra_conf']) || @bind.include?(':')
76
89
  start_webrick
77
90
  return
78
91
  end
@@ -110,6 +123,8 @@ module Fluent::Plugin
110
123
  ssl_config
111
124
  end
112
125
 
126
+ # Use raw bind address for socket binding (no brackets)
127
+ # Brackets are only for URL/URI formatting, not for bind()
113
128
  http_server_create_http_server(:in_prometheus_server, addr: @bind, port: @port, logger: log, proto: proto, tls_opts: tls_opt) do |server|
114
129
  server.get(@metrics_path) { |_req| all_metrics }
115
130
  server.get(@aggregated_metrics_path) { |_req| all_workers_metrics }
@@ -127,6 +142,7 @@ module Fluent::Plugin
127
142
  private
128
143
 
129
144
  # For compatiblity because http helper can't support extra_conf option
145
+ # Also used for IPv6 addresses since http helper has IPv6 URI issues
130
146
  def start_webrick
131
147
  require 'webrick/https'
132
148
  require 'webrick'
@@ -138,28 +154,32 @@ module Fluent::Plugin
138
154
  Logger: WEBrick::Log.new(STDERR, WEBrick::Log::FATAL),
139
155
  AccessLog: [],
140
156
  }
141
- if (@ssl['certificate_path'] && @ssl['private_key_path'].nil?) || (@ssl['certificate_path'].nil? && @ssl['private_key_path'])
142
- raise RuntimeError.new("certificate_path and private_key_path most both be defined")
143
- end
157
+
158
+ # Configure SSL if enabled
159
+ if @ssl && @ssl['enable']
160
+ if (@ssl['certificate_path'] && @ssl['private_key_path'].nil?) || (@ssl['certificate_path'].nil? && @ssl['private_key_path'])
161
+ raise RuntimeError.new("certificate_path and private_key_path most both be defined")
162
+ end
144
163
 
145
- ssl_config = {
146
- SSLEnable: true,
147
- SSLCertName: [['CN', 'nobody'], ['DC', 'example']]
148
- }
164
+ ssl_config = {
165
+ SSLEnable: true,
166
+ SSLCertName: [['CN', 'nobody'], ['DC', 'example']]
167
+ }
149
168
 
150
- if @ssl['certificate_path']
151
- cert = OpenSSL::X509::Certificate.new(File.read(@ssl['certificate_path']))
152
- ssl_config[:SSLCertificate] = cert
153
- end
169
+ if @ssl['certificate_path']
170
+ cert = OpenSSL::X509::Certificate.new(File.read(@ssl['certificate_path']))
171
+ ssl_config[:SSLCertificate] = cert
172
+ end
154
173
 
155
- if @ssl['private_key_path']
156
- key = OpenSSL::PKey.read(@ssl['private_key_path'])
157
- ssl_config[:SSLPrivateKey] = key
158
- end
174
+ if @ssl['private_key_path']
175
+ key = OpenSSL::PKey.read(@ssl['private_key_path'])
176
+ ssl_config[:SSLPrivateKey] = key
177
+ end
159
178
 
160
- ssl_config[:SSLCACertificateFile] = @ssl['ca_path'] if @ssl['ca_path']
161
- ssl_config = ssl_config.merge(@ssl['extra_conf']) if @ssl['extra_conf']
162
- config = ssl_config.merge(config)
179
+ ssl_config[:SSLCACertificateFile] = @ssl['ca_path'] if @ssl['ca_path']
180
+ ssl_config = ssl_config.merge(@ssl['extra_conf']) if @ssl['extra_conf']
181
+ config = ssl_config.merge(config)
182
+ end
163
183
 
164
184
  @log.on_debug do
165
185
  @log.debug("WEBrick conf: #{config}")
@@ -207,7 +227,16 @@ module Fluent::Plugin
207
227
  end
208
228
 
209
229
  def send_request_to_each_worker
210
- bind = (@bind == '0.0.0.0') ? '127.0.0.1' : @bind
230
+ # Convert bind address to localhost for inter-worker communication
231
+ # 0.0.0.0 and :: are not connectable, use localhost instead
232
+ bind = case @bind
233
+ when '0.0.0.0'
234
+ '127.0.0.1'
235
+ when '::'
236
+ '::1' # IPv6 localhost
237
+ else
238
+ @bind
239
+ end
211
240
  [*(@base_port...(@base_port + @num_workers))].each do |worker_port|
212
241
  do_request(host: bind, port: worker_port, secure: @secure) do |http|
213
242
  yield(http.get(@metrics_path))
@@ -89,6 +89,22 @@ describe Fluent::Plugin::PrometheusInput do
89
89
  end
90
90
  end
91
91
 
92
+ context 'IPv6 with TLS' do
93
+ let(:config) do
94
+ %[
95
+ @type prometheus
96
+ bind ::1
97
+ <transport tls>
98
+ insecure true
99
+ </transport>
100
+ ]
101
+ end
102
+
103
+ it 'raises ConfigError for unsupported combination' do
104
+ expect { driver.run(timeout: 1) }.to raise_error(Fluent::ConfigError, /IPv6 with <transport tls> is not currently supported/)
105
+ end
106
+ end
107
+
92
108
  context 'old parameters are given' do
93
109
  context 'when extra_conf is used' do
94
110
  let(:config) do
@@ -278,4 +294,41 @@ describe Fluent::Plugin::PrometheusInput do
278
294
  end
279
295
  end
280
296
  end
297
+
298
+ describe '#run with IPv6' do
299
+ shared_examples 'IPv6 server binding' do |bind_addr, connect_addr, description|
300
+ let(:config) do
301
+ # Quote the bind address if it contains brackets
302
+ bind_value = bind_addr.include?('[') ? "\"#{bind_addr}\"" : bind_addr
303
+ %[
304
+ @type prometheus
305
+ bind #{bind_value}
306
+ ]
307
+ end
308
+
309
+ it description do
310
+ skip 'IPv6 not available on this system' unless ipv6_enabled?
311
+
312
+ driver.run(timeout: 3) do
313
+ Net::HTTP.start(connect_addr, port) do |http|
314
+ req = Net::HTTP::Get.new('/metrics')
315
+ res = http.request(req)
316
+ expect(res.code).to eq('200')
317
+ end
318
+ end
319
+ end
320
+ end
321
+
322
+ context 'IPv6 loopback address ::1' do
323
+ include_examples 'IPv6 server binding', '::1', '::1', 'binds and serves on IPv6 loopback address'
324
+ end
325
+
326
+ context 'IPv6 any address ::' do
327
+ include_examples 'IPv6 server binding', '::', '::1', 'binds on :: and connects via ::1'
328
+ end
329
+
330
+ context 'pre-bracketed IPv6 address [::1]' do
331
+ include_examples 'IPv6 server binding', '[::1]', '::1', 'handles pre-bracketed address correctly'
332
+ end
333
+ end
281
334
  end
@@ -289,7 +289,12 @@ end
289
289
 
290
290
  shared_examples_for 'instruments record' do
291
291
  before do
292
- driver.run(default_tag: tag) { driver.feed(event_time, message) }
292
+ # Should not shut down driver because it will be used in subsequent tests.
293
+ driver.run(default_tag: tag, shutdown: false) { driver.feed(event_time, message) }
294
+ end
295
+
296
+ after do
297
+ driver.instance_shutdown
293
298
  end
294
299
 
295
300
  context 'full config' do
data/spec/spec_helper.rb CHANGED
@@ -8,3 +8,21 @@ Test::Unit::AutoRunner.need_auto_run = false
8
8
 
9
9
  Fluent::Test.setup
10
10
  include Fluent::Test::Helpers
11
+
12
+ def ipv6_enabled?
13
+ require 'socket'
14
+
15
+ begin
16
+ # Try to actually bind to an IPv6 address to verify it works
17
+ sock = Socket.new(Socket::AF_INET6, Socket::SOCK_STREAM, 0)
18
+ sock.bind(Socket.sockaddr_in(0, '::1'))
19
+ sock.close
20
+
21
+ # Also test that we can resolve IPv6 addresses
22
+ # This is needed because some systems can bind but can't connect
23
+ Socket.getaddrinfo('::1', nil, Socket::AF_INET6)
24
+ true
25
+ rescue Errno::EADDRNOTAVAIL, Errno::EAFNOSUPPORT, SocketError
26
+ false
27
+ end
28
+ end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-prometheus
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masahiro Sano
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-03-25 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: fluentd
@@ -144,7 +143,6 @@ homepage: https://github.com/fluent/fluent-plugin-prometheus
144
143
  licenses:
145
144
  - Apache-2.0
146
145
  metadata: {}
147
- post_install_message:
148
146
  rdoc_options: []
149
147
  require_paths:
150
148
  - lib
@@ -159,8 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
157
  - !ruby/object:Gem::Version
160
158
  version: '0'
161
159
  requirements: []
162
- rubygems_version: 3.5.22
163
- signing_key:
160
+ rubygems_version: 4.0.8
164
161
  specification_version: 4
165
162
  summary: A fluent plugin that collects metrics and exposes for Prometheus.
166
163
  test_files: