Sha256: ff6990a35e3d9bd1e5016de71e4acc2d4aa30a7573c26b690cbe52c9a895c09b

Contents?: true

Size: 1.52 KB

Versions: 1

Compression:

Stored size: 1.52 KB

Contents

# frozen_string_literal: true

require "fileutils"
require "forwardable"

module MemprofilerPprof
  class FileFlusher
    extend Forwardable

    def initialize(
      collector, pattern: "tmp/profiles/mem-%{pid}-%{isotime}.pprof", interval: 30, logger: nil, priority: nil,
      yield_gvl: false, proactively_yield_gvl: false
    )
      @logger = logger
      @pattern = pattern
      @profile_counter = 0
      @block_flusher = BlockFlusher.new(
        collector, interval: interval, logger: logger, priority: priority,
        yield_gvl: yield_gvl, proactively_yield_gvl: proactively_yield_gvl,
        on_flush: method(:on_flush)
      )
    end

    def_delegators :@block_flusher, :start!, :stop!, :run
    attr_accessor :pattern

    private

    def on_flush(profile_data)
      fname = template_string(@pattern)
      dirname = File.dirname(fname)
      FileUtils.mkdir_p dirname
      # Need to explicitly specify the encoding, because some applications might do exotic
      # things to File#default_external/#default_internal that would attempt to convert
      # our protobuf to UTF-8.
      File.write(template_string(@pattern), profile_data.pprof_data, encoding: "ASCII-8BIT")
      @profile_counter += 1
    rescue => e
      @logger&.error("FileFlusher: failed to flush profiling data: #{e.inspect}")
    end

    def template_string(tmpl)
      vars = {
        pid: Process.pid,
        isotime: Time.now.iso8601,
        unixtime: Time.now.to_i,
        index: @profile_counter
      }
      sprintf(tmpl, vars)
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
ruby_memprofiler_pprof-0.0.4 lib/ruby_memprofiler_pprof/file_flusher.rb