DataDog / dogstatsd-ruby

A Ruby client for DogStatsd
https://www.datadoghq.com/
MIT License
179 stars 137 forks source link

What causes the "Start sender first" error? #263

Closed VTRyo closed 1 year ago

VTRyo commented 2 years ago

Hey all,

Thanks for the great software.

I have a problem now and have a question. Every time a job in Sidekiq Pro is executed, I am trying to send the number of jobs using the increment method.

def perform(arg)
   DatadogStatsd.instance.set_queue_count(metrics_name: 'xxx_csv_import_queue.count')

   # The process of importing CSV

   if job_success
      DatadogStatsd.instance.set_queue_count(metrics_name: 'xxx_csv_import_queue.success_count')
   else
      DatadogStatsd.instance.set_queue_count(metrics_name: 'xxx_csv_import_queue.error_count')
   end
rescue => e
   # Some kind of rescue process.
   DatadogStatsd.instance.set_queue_count(metrics_name: 'xxx_csv_import_queue.error_count')   
end
class DatadogStatsd
  include Singleton
  def set_queue_count(metrics_name:)
     if defined?(Datadog) && ENV["DD_APM_ENABLED"] == 'true'
        statsd.increment("xx_web.#{metrics_name}")
        statsd.close
    else
        Rails.logger.info("DatadogStatsd metrics_name: #{metrics_name}, increment")
     end

  def statsd
      @statsd ||= Datadog::Statsd.new(ENV.fetch('DD_AGENT_HOST', nil), 8125, tags: { service: 'xx_web', env: Rails.env })
   rescue => e
     Rollbar.error(e)
  end
end

The intent of my code is simply this

"message":"/app/.bundle/ruby/3.0.0/gems/dogstatsd-ruby-5.5.0/lib/datadog/statsd/sender.rb:64:in `add'\n/app/.bundle/ruby/3.0.0/gems/dogstatsd-ruby-5.5.0/lib/datadog/statsd/forwarder.rb:75:in `send_message'\n/app/.bundle/ruby/3.0.0/gems/dogstatsd-ruby-5.5.0/lib/datadog/statsd.rb:430:in `send_stats'\n/app/.bundle/ruby/3.0.0/gems/dogstatsd-ruby-5.5.0/lib/datadog/statsd.rb:190:in `count'\n/app/.bundle/ruby/3.0.0/gems/dogstatsd-ruby-5.5.0/lib/datadog/statsd.rb:162:in 

This line is the error text of Start sender first. (Some parts are omitted because of confidential information.)

/app/.bundle/ruby/3.0.0/gems/dogstatsd-ruby-5.5.0/lib/datadog/statsd/sender.rb:64

https://github.com/DataDog/dogstatsd-ruby/blob/5cb9a87154674f66ac740606d58315213ab7775b/lib/datadog/statsd/sender.rb#L64

Thanks.

VTRyo commented 2 years ago

An important oversight was made.

Even though I am CLOSING the instance, I am still using @statsd to note and reuse the instance.

class DatadogStatsd
  include Singleton
  def set_queue_count(metrics_name:)
     if defined?(Datadog) && ENV["DD_APM_ENABLED"] == 'true'
        statsd.increment("xx_web.#{metrics_name}")
        statsd.close
    else
        Rails.logger.info("DatadogStatsd metrics_name: #{metrics_name}, increment")
     end

  def statsd
      @statsd ||= Datadog::Statsd.new(ENV.fetch('DD_AGENT_HOST', nil), 8125, tags: { service: 'xx_web', env: Rails.env })
   rescue => e
     Rollbar.error(e)
  end

This may have caused the Start sender first to be output. I solved this problem by stopping @statsd memoization and creating an instance each time.

The problem of metrics not being transferred by Dogstatd remains, but the title error is no longer reproduced.

Thanks.

remeh commented 2 years ago

Hey @VTRyo, sorry for the late reply.

You may consider trying to use flush instead of close, it would avoid closing and re-opening a statsd client for every metric submission. For your use-case, I would even consider using single_thread: true, buffer_max_pool_size: 1 to init your statsd client.

HTH.