dogapi 1.9.1 → 1.9.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +5 -0
- data/examples/Capfile +19 -0
- data/lib/capistrano/README.md +1 -1
- data/lib/capistrano/datadog.rb +49 -90
- data/lib/capistrano/datadog/v2.rb +74 -0
- data/lib/capistrano/datadog/v3.rb +57 -0
- data/lib/dogapi/version.rb +1 -1
- metadata +14 -21
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b1d89a7b1f101bd015d08252906c3bbc690f1ef5
|
4
|
+
data.tar.gz: c108087574027947b02bdfe0e1850bc4cc3179ab
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7a661aca185e7f6f9ff326248a824cbdb0202841c198510d2d2930d92df33225ef9ee76fd84c678f8407c9b1b79d68f23ebb49c28188785e683f1d7c68afeebd
|
7
|
+
data.tar.gz: bbe88338592821d6daf84036e7353d8ec50ffe3b867be7d87b070fd98acc2e03da222bbde08b6414c77432dbe3b5f276a7983ac06a4d8d89e56df14974efb75c
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
Changes
|
2
2
|
=======
|
3
3
|
|
4
|
+
# 1.9.2 / 2014-02-13
|
5
|
+
* Fully support for capistrano v3 ([#43](https://github.com/DataDog/dogapi-rb/pull/43))
|
6
|
+
* Strip control characters from capistrano messages ([#36](https://github.com/DataDog/dogapi-rb/issues/36))
|
7
|
+
* Tag capistrano events by stage (thanks [@arielo][] [#25](https://github.com/DataDog/dogapi-rb/pull/25))
|
8
|
+
|
4
9
|
# 1.9.1 / 2014-01-06
|
5
10
|
* Log a warning instead of crashing when trying to integration with capistrano v3
|
6
11
|
|
data/examples/Capfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'capistrano/setup'
|
2
|
+
require 'capistrano/datadog'
|
3
|
+
|
4
|
+
set :datadog_api_key, 'my_api_key'
|
5
|
+
set :stage, :test
|
6
|
+
# set :format, :pretty
|
7
|
+
# set :log_level, :info
|
8
|
+
# set :pty, true
|
9
|
+
|
10
|
+
server "host0", roles: ["thing"]
|
11
|
+
server "host1", roles: ["other_thing"]
|
12
|
+
|
13
|
+
desc "Hello world"
|
14
|
+
task :hello do
|
15
|
+
on roles(:all) do |host|
|
16
|
+
info capture('echo "$(date): Hello from $(whoami)@$(hostname) !"')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
data/lib/capistrano/README.md
CHANGED
@@ -7,7 +7,7 @@ To set up your Capfile:
|
|
7
7
|
require "capistrano/datadog"
|
8
8
|
set :datadog_api_key, "my_api_key"
|
9
9
|
|
10
|
-
You can find your Datadog API key [here](https://app.
|
10
|
+
You can find your Datadog API key [here](https://app.datadoghq.com/account/settings#api). If you don't have a Datadog account, you can sign up for one [here](http://www.datadoghq.com/).
|
11
11
|
|
12
12
|
`capistrano/datadog` will capture each Capistrano task that that Capfile runs, including the roles that the task applies to and any logging output that it emits and submits them as events to Datadog at the end of the execution of all the tasks. If sending to Datadog fails for any reason, your scripts will still succeed.
|
13
13
|
|
data/lib/capistrano/datadog.rb
CHANGED
@@ -1,50 +1,9 @@
|
|
1
|
-
require "benchmark"
|
2
1
|
require "etc"
|
3
2
|
require "digest/md5"
|
4
|
-
require "socket"
|
5
|
-
require "time"
|
6
3
|
require "timeout"
|
7
|
-
require "delegate"
|
8
4
|
|
9
5
|
require "dogapi"
|
10
6
|
|
11
|
-
# Monkeypatch capistrano to collect data about the tasks that it's running
|
12
|
-
module Capistrano
|
13
|
-
class Configuration
|
14
|
-
module Execution
|
15
|
-
# Attempts to locate the task at the given fully-qualified path, and
|
16
|
-
# execute it. If no such task exists, a Capistrano::NoSuchTaskError
|
17
|
-
# will be raised.
|
18
|
-
# Also, capture the time the task took to execute, and the logs it
|
19
|
-
# outputted for submission to Datadog
|
20
|
-
def find_and_execute_task(path, hooks = {})
|
21
|
-
task = find_task(path) or raise NoSuchTaskError, "the task `#{path}' does not exist"
|
22
|
-
result = nil
|
23
|
-
reporter = Capistrano::Datadog.reporter
|
24
|
-
timing = Benchmark.measure(task.fully_qualified_name) do
|
25
|
-
# Set the current task so that the logger knows which task to
|
26
|
-
# associate the logs with
|
27
|
-
reporter.current_task = task.fully_qualified_name
|
28
|
-
trigger(hooks[:before], task) if hooks[:before]
|
29
|
-
result = execute_task(task)
|
30
|
-
trigger(hooks[:after], task) if hooks[:after]
|
31
|
-
reporter.current_task = nil
|
32
|
-
end
|
33
|
-
# Collect the timing in a list for later reporting
|
34
|
-
reporter.record_task task, timing
|
35
|
-
result
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
class Logger
|
41
|
-
# Make the device attribute writeable so we can swap it out
|
42
|
-
# with something that captures logging out by task
|
43
|
-
attr_accessor :device
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
|
48
7
|
module Capistrano
|
49
8
|
module Datadog
|
50
9
|
# Singleton method for Reporter
|
@@ -52,6 +11,34 @@ module Capistrano
|
|
52
11
|
@reporter || @reporter = Reporter.new
|
53
12
|
end
|
54
13
|
|
14
|
+
def self.cap_version()
|
15
|
+
if @cap_version.nil? then
|
16
|
+
if Configuration.respond_to? :instance then
|
17
|
+
@cap_version = :v2
|
18
|
+
else
|
19
|
+
@cap_version = :v3
|
20
|
+
end
|
21
|
+
end
|
22
|
+
@cap_version
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.submit(api_key)
|
26
|
+
begin
|
27
|
+
if api_key
|
28
|
+
dog = Dogapi::Client.new(api_key)
|
29
|
+
reporter.report.each do |event|
|
30
|
+
dog.emit_event event
|
31
|
+
end
|
32
|
+
else
|
33
|
+
puts "No api key set, not submitting to Datadog"
|
34
|
+
end
|
35
|
+
rescue Timeout::Error => e
|
36
|
+
puts "Could not submit to Datadog, request timed out."
|
37
|
+
rescue => e
|
38
|
+
puts "Could not submit to Datadog: #{e.inspect}\n#{e.backtrace.join("\n")}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
55
42
|
# Collects info about the tasks that ran in order to submit to Datadog
|
56
43
|
class Reporter
|
57
44
|
attr_accessor :current_task
|
@@ -62,15 +49,12 @@ module Capistrano
|
|
62
49
|
@logging_output = {}
|
63
50
|
end
|
64
51
|
|
65
|
-
def record_task(
|
66
|
-
roles = task.options[:roles]
|
67
|
-
if roles.is_a? Proc
|
68
|
-
roles = roles.call
|
69
|
-
end
|
52
|
+
def record_task(task_name, timing, roles, stage=nil)
|
70
53
|
@tasks << {
|
71
|
-
:name =>
|
72
|
-
:timing => timing
|
73
|
-
:roles => roles
|
54
|
+
:name => task_name,
|
55
|
+
:timing => timing,
|
56
|
+
:roles => roles,
|
57
|
+
:stage => stage
|
74
58
|
}
|
75
59
|
end
|
76
60
|
|
@@ -93,11 +77,18 @@ module Capistrano
|
|
93
77
|
name = task[:name]
|
94
78
|
roles = Array(task[:roles]).map(&:to_s).sort
|
95
79
|
tags = ["#capistrano"] + (roles.map { |t| '#role:' + t })
|
80
|
+
if !task[:stage].nil? and !task[:stage].empty? then
|
81
|
+
tags << "#stage:#{task[:stage]}"
|
82
|
+
end
|
96
83
|
title = "%s@%s ran %s on %s with capistrano in %.2f secs" % [user, hostname, name, roles.join(', '), task[:timing]]
|
97
84
|
type = "deploy"
|
98
85
|
alert_type = "success"
|
99
86
|
source_type = "capistrano"
|
100
|
-
|
87
|
+
message_content = (@logging_output[name] || []).join('')
|
88
|
+
message = if !message_content.empty? then
|
89
|
+
# Strip out color control characters
|
90
|
+
message_content = message_content.gsub(/\e\[(\d+)m/, '')
|
91
|
+
"@@@\n#{message_content}@@@" else "" end
|
101
92
|
|
102
93
|
Dogapi::Event.new(message,
|
103
94
|
:msg_title => title,
|
@@ -111,46 +102,14 @@ module Capistrano
|
|
111
102
|
end
|
112
103
|
end
|
113
104
|
|
114
|
-
class LogCapture < SimpleDelegator
|
115
|
-
def puts(message)
|
116
|
-
Capistrano::Datadog::reporter.record_log message
|
117
|
-
__getobj__.puts message
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
if Configuration.respond_to? :instance then
|
123
|
-
# Capistrano v2
|
124
|
-
Configuration.instance(:must_exist).load do
|
125
|
-
# Wrap the existing logging target with the Datadog capture class
|
126
|
-
logger.device = Datadog::LogCapture.new logger.device
|
127
|
-
|
128
|
-
# Trigger the Datadog submission once all the tasks have run
|
129
|
-
on :exit, "datadog:submit"
|
130
|
-
namespace :datadog do
|
131
|
-
desc "Submit the tasks that have run to Datadog as events"
|
132
|
-
task :submit do |ns|
|
133
|
-
begin
|
134
|
-
api_key = variables[:datadog_api_key]
|
135
|
-
if api_key
|
136
|
-
dog = Dogapi::Client.new(api_key)
|
137
|
-
Datadog::reporter.report.each do |event|
|
138
|
-
dog.emit_event event
|
139
|
-
end
|
140
|
-
else
|
141
|
-
puts "No api key set, not submitting to Datadog"
|
142
|
-
end
|
143
|
-
rescue Timeout::Error => e
|
144
|
-
puts "Could not submit to Datadog, request timed out."
|
145
|
-
rescue => e
|
146
|
-
puts "Could not submit to Datadog: #{e.inspect}\n#{e.backtrace.join("\n")}"
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
else
|
152
|
-
# No support yet for Capistrano v3
|
153
|
-
puts "No Datadog events will be sent since Datadog currently only supports Capistrano v2. For more info, see https://github.com/DataDog/dogapi-rb/issues/40."
|
154
105
|
end
|
106
|
+
end
|
155
107
|
|
108
|
+
case Capistrano::Datadog::cap_version
|
109
|
+
when :v2
|
110
|
+
require 'capistrano/datadog/v2'
|
111
|
+
when :v3
|
112
|
+
require 'capistrano/datadog/v3'
|
113
|
+
else
|
114
|
+
puts "Unknown version: #{Capistrano::Datadog::cap_version.inspect}"
|
156
115
|
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require "benchmark"
|
2
|
+
require "delegate"
|
3
|
+
|
4
|
+
# Capistrano v2
|
5
|
+
|
6
|
+
# Monkeypatch capistrano to collect data about the tasks that it's running
|
7
|
+
module Capistrano
|
8
|
+
class Configuration
|
9
|
+
module Execution
|
10
|
+
# Attempts to locate the task at the given fully-qualified path, and
|
11
|
+
# execute it. If no such task exists, a Capistrano::NoSuchTaskError
|
12
|
+
# will be raised.
|
13
|
+
# Also, capture the time the task took to execute, and the logs it
|
14
|
+
# outputted for submission to Datadog
|
15
|
+
def find_and_execute_task(path, hooks = {})
|
16
|
+
task = find_task(path) or raise NoSuchTaskError, "the task `#{path}' does not exist"
|
17
|
+
result = nil
|
18
|
+
reporter = Capistrano::Datadog.reporter
|
19
|
+
task_name = task.fully_qualified_name
|
20
|
+
timing = Benchmark.measure(task_name) do
|
21
|
+
# Set the current task so that the logger knows which task to
|
22
|
+
# associate the logs with
|
23
|
+
reporter.current_task = task_name
|
24
|
+
trigger(hooks[:before], task) if hooks[:before]
|
25
|
+
result = execute_task(task)
|
26
|
+
trigger(hooks[:after], task) if hooks[:after]
|
27
|
+
reporter.current_task = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
# Record the task name, its timing and roles
|
31
|
+
roles = task.options[:roles]
|
32
|
+
if roles.is_a? Proc
|
33
|
+
roles = roles.call
|
34
|
+
end
|
35
|
+
reporter.record_task(task_name, timing.real, roles, task.namespace.variables[:stage])
|
36
|
+
|
37
|
+
# Return the original result
|
38
|
+
result
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class Logger
|
44
|
+
# Make the device attribute writeable so we can swap it out
|
45
|
+
# with something that captures logging out by task
|
46
|
+
attr_accessor :device
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
module Capistrano
|
52
|
+
module Datadog
|
53
|
+
class LogCapture < SimpleDelegator
|
54
|
+
def puts(message)
|
55
|
+
Capistrano::Datadog::reporter.record_log message
|
56
|
+
__getobj__.puts message
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
Configuration.instance(:must_exist).load do
|
61
|
+
# Wrap the existing logging target with the Datadog capture class
|
62
|
+
logger.device = Datadog::LogCapture.new logger.device
|
63
|
+
|
64
|
+
# Trigger the Datadog submission once all the tasks have run
|
65
|
+
on :exit, "datadog:submit"
|
66
|
+
namespace :datadog do
|
67
|
+
desc "Submit the tasks that have run to Datadog as events"
|
68
|
+
task :submit do |ns|
|
69
|
+
Capistrano::Datadog.submit variables[:datadog_api_key]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "benchmark"
|
2
|
+
require "sshkit/formatters/pretty"
|
3
|
+
|
4
|
+
# Capistrano v3 uses Rake's DSL instead of its own
|
5
|
+
|
6
|
+
module Rake
|
7
|
+
class Task
|
8
|
+
alias old_invoke invoke
|
9
|
+
def invoke(*args)
|
10
|
+
result = nil
|
11
|
+
reporter = Capistrano::Datadog.reporter
|
12
|
+
task_name = name
|
13
|
+
reporter.current_task = task_name
|
14
|
+
timing = Benchmark.measure(task_name) do
|
15
|
+
result = old_invoke(*args)
|
16
|
+
end
|
17
|
+
reporter.record_task(task_name, timing.real, roles,
|
18
|
+
Capistrano::Configuration.env.fetch(:stage))
|
19
|
+
result
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module Capistrano
|
25
|
+
module Datadog
|
26
|
+
class CaptureIO
|
27
|
+
def initialize(wrapped)
|
28
|
+
@wrapped = wrapped
|
29
|
+
end
|
30
|
+
|
31
|
+
def write(*args)
|
32
|
+
@wrapped.write(*args)
|
33
|
+
args.each { |arg| Capistrano::Datadog.reporter.record_log(arg) }
|
34
|
+
end
|
35
|
+
alias :<< :write
|
36
|
+
|
37
|
+
def close
|
38
|
+
@wrapped.close
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
module SSHKit
|
45
|
+
module Formatter
|
46
|
+
class Pretty
|
47
|
+
def initialize(oio)
|
48
|
+
super(Capistrano::Datadog::CaptureIO.new(oio))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
at_exit do
|
55
|
+
api_key = Capistrano::Configuration.env.fetch :datadog_api_key
|
56
|
+
Capistrano::Datadog.submit api_key
|
57
|
+
end
|
data/lib/dogapi/version.rb
CHANGED
metadata
CHANGED
@@ -1,36 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dogapi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.9.
|
5
|
-
prerelease:
|
4
|
+
version: 1.9.2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Datadog, Inc.
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2014-
|
11
|
+
date: 2014-02-13 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: json
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: 1.5.1
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: 1.5.1
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: bundler
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - ~>
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - ~>
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -46,7 +41,6 @@ dependencies:
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: rake
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
45
|
- - ~>
|
52
46
|
- !ruby/object:Gem::Version
|
@@ -54,7 +48,6 @@ dependencies:
|
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
52
|
- - ~>
|
60
53
|
- !ruby/object:Gem::Version
|
@@ -62,17 +55,15 @@ dependencies:
|
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: rdoc
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - '>='
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: '0'
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - '>='
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: '0'
|
78
69
|
description: Ruby bindings for Datadog's API
|
@@ -93,10 +84,13 @@ files:
|
|
93
84
|
- README.rdoc
|
94
85
|
- Rakefile
|
95
86
|
- dogapi.gemspec
|
87
|
+
- examples/Capfile
|
96
88
|
- examples/custom_event.rb
|
97
89
|
- examples/custom_metric.rb
|
98
90
|
- lib/capistrano/README.md
|
99
91
|
- lib/capistrano/datadog.rb
|
92
|
+
- lib/capistrano/datadog/v2.rb
|
93
|
+
- lib/capistrano/datadog/v3.rb
|
100
94
|
- lib/dogapi.rb
|
101
95
|
- lib/dogapi/common.rb
|
102
96
|
- lib/dogapi/event.rb
|
@@ -141,6 +135,7 @@ files:
|
|
141
135
|
homepage: http://datadoghq.com/
|
142
136
|
licenses:
|
143
137
|
- BSD
|
138
|
+
metadata: {}
|
144
139
|
post_install_message:
|
145
140
|
rdoc_options:
|
146
141
|
- --title
|
@@ -152,22 +147,20 @@ rdoc_options:
|
|
152
147
|
require_paths:
|
153
148
|
- lib
|
154
149
|
required_ruby_version: !ruby/object:Gem::Requirement
|
155
|
-
none: false
|
156
150
|
requirements:
|
157
|
-
- -
|
151
|
+
- - '>='
|
158
152
|
- !ruby/object:Gem::Version
|
159
153
|
version: '0'
|
160
154
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
|
-
none: false
|
162
155
|
requirements:
|
163
|
-
- -
|
156
|
+
- - '>='
|
164
157
|
- !ruby/object:Gem::Version
|
165
158
|
version: '0'
|
166
159
|
requirements: []
|
167
160
|
rubyforge_project:
|
168
|
-
rubygems_version: 1.
|
161
|
+
rubygems_version: 2.1.11
|
169
162
|
signing_key:
|
170
|
-
specification_version:
|
163
|
+
specification_version: 4
|
171
164
|
summary: Ruby bindings for Datadog's API
|
172
165
|
test_files:
|
173
166
|
- spec/alerts_spec.rb
|