Module: HKeyPerfDataReader::RawReader

Includes:
Constants
Defined in:
lib/fluent/plugin/hkey_perf_data_reader.rb

Constant Summary collapse

BUFFER_SIZE =

128kb

128*1024*1024

Constants included from Constants

Constants::ERROR_MORE_DATA, Constants::ERROR_SUCCESS, Constants::HKEY_PERFORMANCE_DATA, Constants::HKEY_PERFORMANCE_TEXT, Constants::PERF_NO_INSTANCES

Class Method Summary collapse

Class Method Details

.read(logger = nil) ⇒ Object



336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
# File 'lib/fluent/plugin/hkey_perf_data_reader.rb', line 336

def self.read(logger = nil)
  # https://docs.microsoft.com/en-us/windows/win32/perfctrs/using-the-registry-functions-to-consume-counter-data
  # https://docs.microsoft.com/en-us/windows/win32/perfctrs/retrieving-counter-data

  hkey = convert_handle(HKEY_PERFORMANCE_DATA)
  type = packdw(0)
  source = make_wstr("Global")
  size = packdw(BUFFER_SIZE)

  # NOTE: By Stoping allocating every time and starting reusing, we might be able to speed up the process.
  data = "\0".force_encoding("ASCII-8BIT") * unpackdw(size)

  begin
    ret = API.RegQueryValueExW(hkey, source, 0, type, data, size)

    while ret == ERROR_MORE_DATA
      size = packdw(unpackdw(size) + BUFFER_SIZE)
      data = "\0".force_encoding("ASCII-8BIT") * unpackdw(size)
      ret = API.RegQueryValueExW(hkey, source, 0, type, data, size)
    end

    unless ret == ERROR_SUCCESS
      raise IOError, "RegQueryValueEx failed with #{ret}."
    end

    return data[0..unpackdw(size)]
  ensure
    ret = API.RegCloseKey(hkey)
    unless ret == ERROR_SUCCESS
      logger&.warn("RegCloseKey failed with #{ret}.")
    end
  end
end

.read_counter_name_tableObject



370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
# File 'lib/fluent/plugin/hkey_perf_data_reader.rb', line 370

def self.read_counter_name_table
  # This process can be replaced by:
  #  require "win32/registry"
  #  Win32::Registry::HKEY_PERFORMANCE_TEXT.read("Counter")

  # There is a problem with getting some name data in ruby.
  # This is caused by `SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS)` called from `rubygems\defaults\operating_system.rb`.
  # https://github.com/fluent-plugins-nursery/fluent-plugin-windows-exporter/issues/1#issuecomment-994168635

  # https://docs.microsoft.com/en-us/windows/win32/perfctrs/retrieving-counter-names-and-help-text
  hkey = convert_handle(HKEY_PERFORMANCE_TEXT)
  source = make_wstr("Counter")
  size = packdw(0)

  ret = API.RegQueryValueExW(hkey, source, nil, nil, nil, size)

  unless ret == ERROR_SUCCESS
    raise IOError, "RegQueryValueEx failed getting required buffer size. Error is #{ret}."
  end

  data = "\0".force_encoding("ASCII-8BIT") * unpackdw(size)

  ret = API.RegQueryValueExW(hkey, source, nil, nil, data, size)

  unless ret == ERROR_SUCCESS
    raise IOError, "RegQueryValueEx failed with #{ret}."
  end

  # NOTE: no need to call `RegCloseKey` when just taking counter table data

  data
end