Skip to content

Commit

Permalink
Add standalone Rails ActiveJob integration
Browse files Browse the repository at this point in the history
  • Loading branch information
bensheldon committed Aug 13, 2021
1 parent bad39d4 commit 599ecc7
Show file tree
Hide file tree
Showing 20 changed files with 848 additions and 46 deletions.
23 changes: 23 additions & 0 deletions docs/GettingStarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ To contribute, check out the [contribution guidelines][contribution docs] and [d
- [Action View](#action-view)
- [Active Model Serializers](#active-model-serializers)
- [Action Pack](#action-pack)
- [Active Job](#active-job)
- [Active Record](#active-record)
- [Active Support](#active-support)
- [AWS](#aws)
Expand Down Expand Up @@ -391,6 +392,7 @@ For a list of available integrations, and their configuration options, please re
| Action View | `action_view` | `>= 3.0` | `>= 3.0` | *[Link](#action-view)* | *[Link](https://github.com/rails/rails/tree/master/actionview)* |
| Active Model Serializers | `active_model_serializers` | `>= 0.9` | `>= 0.9` | *[Link](#active-model-serializers)* | *[Link](https://github.com/rails-api/active_model_serializers)* |
| Action Pack | `action_pack` | `>= 3.0` | `>= 3.0` | *[Link](#action-pack)* | *[Link](https://github.com/rails/rails/tree/master/actionpack)* |
| Active Job | `active_job` | `>= 4.2` | `>= 4.2` | *[Link](#active-job)* | *[Link](https://github.com/rails/rails/tree/master/activejob)* |
| Active Record | `active_record` | `>= 3.0` | `>= 3.0` | *[Link](#active-record)* | *[Link](https://github.com/rails/rails/tree/master/activerecord)* |
| Active Support | `active_support` | `>= 3.0` | `>= 3.0` | *[Link](#active-support)* | *[Link](https://github.com/rails/rails/tree/master/activesupport)* |
| AWS | `aws` | `>= 2.0` | `>= 2.0` | *[Link](#aws)* | *[Link](https://github.com/aws/aws-sdk-ruby)* |
Expand Down Expand Up @@ -510,6 +512,27 @@ Where `options` is an optional `Hash` that accepts the following parameters:
| ---| --- | --- |
| `service_name` | Service name used for rendering instrumentation. | `action_pack` |

### Active Job

Most of the time, Active Job is set up as part of Rails, but it can be activated separately:

```ruby
require 'activejob'
require 'ddtrace'
Datadog.configure do |c|
c.use :active_job, options
end
ExampleJob.perform_later
```

Where `options` is an optional `Hash` that accepts the following parameters:

| Key | Description | Default |
| --- | ----------- | ------- |
| `service_name` | Service name used for `active_job` instrumentation | `'active_job'` |

### Active Record

Most of the time, Active Record is set up as part of a web framework (Rails, Sinatra...) however, it can be set up alone:
Expand Down
1 change: 1 addition & 0 deletions lib/datadog/contrib.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ module Contrib
require 'ddtrace/contrib/action_pack/integration'
require 'ddtrace/contrib/action_view/integration'
require 'ddtrace/contrib/active_model_serializers/integration'
require 'ddtrace/contrib/active_job/integration'
require 'ddtrace/contrib/active_record/integration'
require 'ddtrace/contrib/active_support/integration'
require 'ddtrace/contrib/aws/integration'
Expand Down
32 changes: 32 additions & 0 deletions lib/ddtrace/contrib/active_job/configuration/settings.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# typed: false
require 'ddtrace/contrib/configuration/settings'
require 'ddtrace/contrib/active_job/ext'

module Datadog
module Contrib
module ActiveJob
module Configuration
# Custom settings for the DelayedJob integration
class Settings < Contrib::Configuration::Settings
option :enabled do |o|
o.default { env_to_bool(Ext::ENV_ENABLED, true) }
o.lazy
end

option :analytics_enabled do |o|
o.default { env_to_bool([Ext::ENV_ANALYTICS_ENABLED, Ext::ENV_ANALYTICS_ENABLED_OLD], false) }
o.lazy
end

option :analytics_sample_rate do |o|
o.default { env_to_float([Ext::ENV_ANALYTICS_SAMPLE_RATE, Ext::ENV_ANALYTICS_SAMPLE_RATE_OLD], 1.0) }
o.lazy
end

option :service_name, default: Ext::SERVICE_NAME
option :error_handler, default: Datadog::Tracer::DEFAULT_ON_ERROR
end
end
end
end
end
54 changes: 54 additions & 0 deletions lib/ddtrace/contrib/active_job/event.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# typed: true
require 'ddtrace/contrib/active_support/notifications/event'
require 'ddtrace/contrib/active_job/ext'

module Datadog
module Contrib
module ActiveJob
# Defines basic behaviors for an ActiveJob event.
module Event
def self.included(base)
base.include(ActiveSupport::Notifications::Event)
base.extend(ClassMethods)
end

# Class methods for ActiveJob events.
module ClassMethods
def span_options
{ service: configuration[:service_name] }
end

def tracer
-> { configuration[:tracer] }
end

def configuration
Datadog.configuration[:active_job]
end

def set_common_tags(span, payload)
adapter_name = if payload[:adapter].is_a?(Class)
payload[:adapter].name
else
payload[:adapter].class.name
end
span.set_tag(Ext::TAG_ADAPTER, adapter_name)

job = payload[:job]
span.set_tag(Ext::TAG_JOB_ID, job.job_id)
span.set_tag(Ext::TAG_JOB_QUEUE, job.queue_name)
span.set_tag(Ext::TAG_JOB_PRIORITY, job.priority) if job.respond_to?(:priority)
span.set_tag(Ext::TAG_JOB_EXECUTIONS, job.executions) if job.respond_to?(:executions)

job_scheduled_at = if job.respond_to?(:scheduled_at)
job.scheduled_at
elsif job.respond_to?(:enqueued_at)
job.enqueued_at
end
span.set_tag(Ext::TAG_JOB_SCHEDULED_AT, Time.at(job_scheduled_at)) if job_scheduled_at
end
end
end
end
end
end
39 changes: 39 additions & 0 deletions lib/ddtrace/contrib/active_job/events.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# typed: false
require 'ddtrace/contrib/active_job/events/discard'
require 'ddtrace/contrib/active_job/events/enqueue'
require 'ddtrace/contrib/active_job/events/enqueue_at'
require 'ddtrace/contrib/active_job/events/enqueue_retry'
require 'ddtrace/contrib/active_job/events/perform'
require 'ddtrace/contrib/active_job/events/retry_stopped'

module Datadog
module Contrib
module ActiveJob
# Defines collection of instrumented ActiveJob events
module Events
ALL = [
Events::Discard,
Events::Enqueue,
Events::EnqueueAt,
Events::EnqueueRetry,
Events::Perform,
Events::RetryStopped,
].freeze

module_function

def all
self::ALL
end

def subscriptions
all.collect(&:subscriptions).collect(&:to_a).flatten
end

def subscribe!
all.each(&:subscribe!)
end
end
end
end
end
46 changes: 46 additions & 0 deletions lib/ddtrace/contrib/active_job/events/discard.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# typed: false
require 'ddtrace/ext/integration'
require 'ddtrace/contrib/analytics'
require 'ddtrace/contrib/active_job/ext'
require 'ddtrace/contrib/active_job/event'

module Datadog
module Contrib
module ActiveJob
module Events
# Defines instrumentation for enqueue.active_job event
module Discard
include ActiveJob::Event

EVENT_NAME = 'discard.active_job'.freeze

module_function

def event_name
self::EVENT_NAME
end

def span_name
Ext::SPAN_DISCARD
end

def process(span, event, _id, payload)
span.name = span_name
span.service = configuration[:service_name]
span.resource = payload[:job].class.name

# Set analytics sample rate
if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
end

set_common_tags(span, payload)
span.set_tag(Ext::TAG_JOB_ERROR, payload[:error])
rescue StandardError => e
Datadog.logger.debug(e.message)
end
end
end
end
end
end
45 changes: 45 additions & 0 deletions lib/ddtrace/contrib/active_job/events/enqueue.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# typed: false
require 'ddtrace/ext/integration'
require 'ddtrace/contrib/analytics'
require 'ddtrace/contrib/active_job/ext'
require 'ddtrace/contrib/active_job/event'

module Datadog
module Contrib
module ActiveJob
module Events
# Defines instrumentation for enqueue.active_job event
module Enqueue
include ActiveJob::Event

EVENT_NAME = 'enqueue.active_job'.freeze

module_function

def event_name
self::EVENT_NAME
end

def span_name
Ext::SPAN_ENQUEUE
end

def process(span, event, _id, payload)
span.name = span_name
span.service = configuration[:service_name]
span.resource = payload[:job].class.name

# Set analytics sample rate
if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
end

set_common_tags(span, payload)
rescue StandardError => e
Datadog.logger.debug(e.message)
end
end
end
end
end
end
45 changes: 45 additions & 0 deletions lib/ddtrace/contrib/active_job/events/enqueue_at.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# typed: false
require 'ddtrace/ext/integration'
require 'ddtrace/contrib/analytics'
require 'ddtrace/contrib/active_job/ext'
require 'ddtrace/contrib/active_job/event'

module Datadog
module Contrib
module ActiveJob
module Events
# Defines instrumentation for enqueue.active_job event
module EnqueueAt
include ActiveJob::Event

EVENT_NAME = 'enqueue_at.active_job'.freeze

module_function

def event_name
self::EVENT_NAME
end

def span_name
Ext::SPAN_ENQUEUE
end

def process(span, event, _id, payload)
span.name = span_name
span.service = configuration[:service_name]
span.resource = payload[:job].class.name

# Set analytics sample rate
if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
end

set_common_tags(span, payload)
rescue StandardError => e
Datadog.logger.debug(e.message)
end
end
end
end
end
end
47 changes: 47 additions & 0 deletions lib/ddtrace/contrib/active_job/events/enqueue_retry.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# typed: false
require 'ddtrace/ext/integration'
require 'ddtrace/contrib/analytics'
require 'ddtrace/contrib/active_job/ext'
require 'ddtrace/contrib/active_job/event'

module Datadog
module Contrib
module ActiveJob
module Events
# Defines instrumentation for enqueue.active_job event
module EnqueueRetry
include ActiveJob::Event

EVENT_NAME = 'enqueue_retry.active_job'.freeze

module_function

def event_name
self::EVENT_NAME
end

def span_name
Ext::SPAN_ENQUEUE_RETRY
end

def process(span, event, _id, payload)
span.name = span_name
span.service = configuration[:service_name]
span.resource = payload[:job].class.name

# Set analytics sample rate
if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
end

set_common_tags(span, payload)
span.set_tag(Ext::TAG_JOB_ERROR, payload[:error])
span.set_tag(Ext::TAG_JOB_RETRY_WAIT, payload[:wait])
rescue StandardError => e
Datadog.logger.debug(e.message)
end
end
end
end
end
end
Loading

0 comments on commit 599ecc7

Please sign in to comment.