Class: Capistrano::Datadog::Reporter

Inherits:
Object
  • Object
show all
Defined in:
lib/capistrano/datadog.rb

Overview

Collects info about the tasks that ran in order to submit to Datadog

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeReporter

Returns a new instance of Reporter.



58
59
60
61
# File 'lib/capistrano/datadog.rb', line 58

def initialize()
  @tasks = []
  @task_stack = []
end

Instance Attribute Details

#event_filterObject

Returns the value of attribute event_filter.



56
57
58
# File 'lib/capistrano/datadog.rb', line 56

def event_filter
  @event_filter
end

Instance Method Details

#record_hostname(hostname) ⇒ Object



90
91
92
93
94
# File 'lib/capistrano/datadog.rb', line 90

def record_hostname(hostname)
  @task_stack.each do |task|
    task[:hosts] << hostname
  end
end

#record_log(message) ⇒ Object



83
84
85
86
87
88
# File 'lib/capistrano/datadog.rb', line 83

def record_log(message)
  current_task = @task_stack.last
  if current_task
    current_task[:logs] << message
  end
end

#record_task(task_name, roles, stage = nil, application_name = nil) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/capistrano/datadog.rb', line 63

def record_task(task_name, roles, stage=nil, application_name=nil)
  task = {
    :name   => task_name,
    :roles  => roles,
    :stage  => stage,
    :application => application_name,
    :logs => [],
    :hosts => []
  }
  @tasks << task
  @task_stack << task
  result = nil
  timing = Benchmark.measure(task_name) do
    result = yield
  end
  task[:timing] = timing.real
  @task_stack.pop
  result
end

#report(use_getlogin = true) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/capistrano/datadog.rb', line 96

def report(use_getlogin=true)
  hostname = Dogapi.find_localhost
  user = use_getlogin ? Etc.getlogin : Etc.getpwuid.name

  # Lazy randomness
  aggregation_key = Digest::MD5.hexdigest "#{Time.new}|#{rand}"

  filter = event_filter || proc { |x| x }

  # Convert the tasks into Datadog events
  @tasks.map do |task|
    name  = task[:name]
    roles = Array(task[:roles]).map(&:to_s).sort
    tags  = ['#capistrano'] + (roles.map { |t| '#role:' + t })
    if !task[:stage].nil? and !task[:stage].empty? then
      tags << "#stage:#{task[:stage]}"
    end
    application = ''
    if !task[:application].nil? and !task[:application].empty? then
      application = ' for ' + task[:application]
    end
    timing = Float(task[:timing]).round(2) rescue 'n/a'
    title = "#{user}@#{hostname} ran #{name}#{application} on #{roles.join(', ')} "\
            "with capistrano in #{timing} secs"
    type  = 'deploy'
    alert_type = 'success'
    source_type = 'capistrano'
    message_content = task[:logs].join('')
    message = if !message_content.empty? then
      # Strip out color control characters
      message_content = sanitize_encoding(message_content).gsub(/\e\[(\d+)m/, '')
      "@@@\n#{message_content}@@@" else '' end

    [Dogapi::Event.new(message,
      :msg_title        => title,
      :event_type       => type,
      :event_object     => aggregation_key,
      :alert_type       => alert_type,
      :source_type_name => source_type,
      :tags             => tags
    ), task[:hosts]]
  end.map(&event_filter).reject(&:nil?)
end

#sanitize_encoding(string) ⇒ Object



140
141
142
143
# File 'lib/capistrano/datadog.rb', line 140

def sanitize_encoding(string)
  return string unless defined?(::Encoding) && string.encoding == Encoding::BINARY
  string.encode(Encoding::UTF_8, Encoding::BINARY, invalid: :replace, undef: :replace, replace: '')
end