signalfx 0.1.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -2
- data/Gemfile.lock +17 -15
- data/README.md +74 -52
- data/examples/generic_usecase.rb +2 -2
- data/lib/proto/signal_fx_protocol_buffers.pb.rb +38 -0
- data/lib/signalfx.rb +5 -8
- data/lib/signalfx/conf.rb +4 -6
- data/lib/signalfx/json_signal_fx_client.rb +8 -2
- data/lib/signalfx/protobuf_signal_fx_client.rb +53 -2
- data/lib/signalfx/signal_fx_client.rb +45 -16
- data/lib/signalfx/version.rb +2 -2
- data/signalfx.gemspec +5 -3
- metadata +26 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c73cef3310b0afe73db2d5eaad2815e3f2f6fe7b
|
4
|
+
data.tar.gz: 2af5242a79e3334b09cd357bd59b34349fa93480
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca5b43a50c065795ad6b1fa7c3683f43eb2bab8d8963f351d949e327b2f701bcd484ed74aef60a6c1056bffd4fd26ee170eca6d59701ec23e1b2213bf737c501
|
7
|
+
data.tar.gz: da0c71273f90a0c20a1aa8b7d6175739dfb2df1a592601fbd3a9b18bc67c70dea84f80fd5f42ca960c163679cf1dfddd7b99c0055d31b59daa87f3e68da64582
|
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,35 +1,36 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
signalfx (0.1
|
4
|
+
signalfx (1.0.1)
|
5
5
|
protobuf (~> 3.5.1, >= 3.5.1)
|
6
6
|
rest-client (~> 1.8)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
activesupport (
|
11
|
+
activesupport (5.0.0.1)
|
12
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
12
13
|
i18n (~> 0.7)
|
13
|
-
json (~> 1.7, >= 1.7.7)
|
14
14
|
minitest (~> 5.1)
|
15
|
-
thread_safe (~> 0.3, >= 0.3.4)
|
16
15
|
tzinfo (~> 1.1)
|
17
|
-
addressable (2.
|
18
|
-
|
16
|
+
addressable (2.4.0)
|
17
|
+
concurrent-ruby (1.0.2)
|
18
|
+
crack (0.4.3)
|
19
19
|
safe_yaml (~> 1.0.0)
|
20
20
|
diff-lcs (1.2.5)
|
21
21
|
docile (1.1.5)
|
22
|
-
domain_name (0.5.
|
22
|
+
domain_name (0.5.20160826)
|
23
23
|
unf (>= 0.0.5, < 1.0.0)
|
24
|
+
hashdiff (0.3.0)
|
24
25
|
http-cookie (1.0.2)
|
25
26
|
domain_name (~> 0.5)
|
26
27
|
i18n (0.7.0)
|
27
28
|
json (1.8.3)
|
28
29
|
middleware (0.1.0)
|
29
|
-
mime-types (2.
|
30
|
-
minitest (5.
|
31
|
-
netrc (0.
|
32
|
-
protobuf (3.5.
|
30
|
+
mime-types (2.99.3)
|
31
|
+
minitest (5.9.0)
|
32
|
+
netrc (0.11.0)
|
33
|
+
protobuf (3.5.5)
|
33
34
|
activesupport (>= 3.2)
|
34
35
|
middleware
|
35
36
|
thor
|
@@ -64,10 +65,11 @@ GEM
|
|
64
65
|
thread_safe (~> 0.1)
|
65
66
|
unf (0.1.4)
|
66
67
|
unf_ext
|
67
|
-
unf_ext (0.0.7.
|
68
|
-
webmock (1.
|
68
|
+
unf_ext (0.0.7.2)
|
69
|
+
webmock (2.1.0)
|
69
70
|
addressable (>= 2.3.6)
|
70
71
|
crack (>= 0.3.2)
|
72
|
+
hashdiff
|
71
73
|
|
72
74
|
PLATFORMS
|
73
75
|
ruby
|
@@ -75,10 +77,10 @@ PLATFORMS
|
|
75
77
|
DEPENDENCIES
|
76
78
|
bundler (~> 1.10)
|
77
79
|
rake (~> 10.0)
|
78
|
-
rspec
|
80
|
+
rspec (~> 3.3)
|
79
81
|
signalfx!
|
80
82
|
simplecov
|
81
|
-
webmock (~> 1
|
83
|
+
webmock (~> 2.1)
|
82
84
|
|
83
85
|
BUNDLED WITH
|
84
86
|
1.10.6
|
data/README.md
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
# Ruby client library for SignalFx
|
2
2
|
|
3
|
-
This is a programmatic interface in Ruby for SignalFx's metadata and
|
4
|
-
|
3
|
+
This is a programmatic interface in Ruby for SignalFx's metadata and
|
4
|
+
ingest APIs. It is meant to provide a base for communicating with
|
5
|
+
SignalFx APIs that can be easily leveraged by scripts and applications
|
6
|
+
to interact with SignalFx or report metric and event data to SignalFx.
|
7
|
+
|
8
|
+
This library supports Ruby versions 2.2.x and above.
|
5
9
|
|
6
10
|
## Installation
|
7
11
|
|
@@ -28,112 +32,130 @@ To use this library, you need a SignalFx API access token, which can be obtained
|
|
28
32
|
The default constructor `SignalFx` uses Protobuf to send data to SignalFx. If it cannot send Protobuf, it falls back to sending JSON.
|
29
33
|
|
30
34
|
```ruby
|
31
|
-
require('signalfx')
|
35
|
+
require('signalfx')
|
32
36
|
|
33
37
|
// Create client
|
34
|
-
client = SignalFx.new 'MY_SIGNALFX_TOKEN'
|
38
|
+
client = SignalFx.new 'MY_SIGNALFX_TOKEN'
|
35
39
|
```
|
36
40
|
|
37
41
|
Optional constructor parameters:
|
38
|
-
+ **api_token**
|
39
|
-
+ **enable_aws_unique_id**
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
+ **
|
45
|
-
|
46
|
-
+ **
|
47
|
-
+ **
|
42
|
+
+ **api_token** (string): your private SignalFx token.
|
43
|
+
+ **enable_aws_unique_id** (boolean): `false` by default.
|
44
|
+
If `true`, the library will retrieve the Amazon instance unique
|
45
|
+
identifier and set it as `AWSUniqueId` dimension for each
|
46
|
+
datapoint and event. Use this option only if your application is
|
47
|
+
deployed on Amazon AWS.
|
48
|
+
+ **ingest_endpoint** (string): to override the target ingest API
|
49
|
+
endpoint.
|
50
|
+
+ **api_endpoint** (string): to override the target REST API endpoint.
|
51
|
+
+ **timeout** (number): timeout, in seconds, for requests to SignalFx.
|
52
|
+
+ **batch_size** (number): size of datapoint batches to send to
|
53
|
+
SignalFx.
|
54
|
+
+ **user_agents** (array of strings): an array of additional User-Agent
|
55
|
+
strings to use when making requests to SignalFx.
|
48
56
|
|
49
57
|
### Reporting data
|
50
58
|
|
51
|
-
This example shows how to report metrics to SignalFx, as gauges, counters, or cumulative counters.
|
59
|
+
This example shows how to report metrics to SignalFx, as gauges, counters, or cumulative counters.
|
52
60
|
|
53
61
|
```ruby
|
54
|
-
require('signalfx')
|
62
|
+
require('signalfx')
|
55
63
|
|
56
|
-
client = SignalFx.new 'MY_SIGNALFX_TOKEN'
|
64
|
+
client = SignalFx.new 'MY_SIGNALFX_TOKEN'
|
57
65
|
|
58
66
|
client.send(
|
59
67
|
cumulative_counters:[
|
60
|
-
{ :metric => 'myfunc.calls_cumulative',
|
61
|
-
:value => 10,
|
68
|
+
{ :metric => 'myfunc.calls_cumulative',
|
69
|
+
:value => 10,
|
62
70
|
:timestamp => 1442960607000 },
|
63
71
|
...
|
64
72
|
],
|
65
73
|
gauges:[
|
66
|
-
{ :metric => 'myfunc.time',
|
67
|
-
:value => 532,
|
74
|
+
{ :metric => 'myfunc.time',
|
75
|
+
:value => 532,
|
68
76
|
:timestamp => 1442960607000},
|
69
77
|
...
|
70
78
|
],
|
71
79
|
counters:[
|
72
|
-
{ :metric => 'myfunc.calls',
|
73
|
-
:value => 42,
|
80
|
+
{ :metric => 'myfunc.calls',
|
81
|
+
:value => 42,
|
74
82
|
:timestamp => 1442960607000},
|
75
83
|
...
|
76
|
-
])
|
84
|
+
])
|
77
85
|
```
|
78
|
-
The `timestamp` must be a millisecond precision timestamp; the number of milliseconds elapsed since Epoch. The `timestamp` field is optional, but strongly recommended. If not specified, it will be set by SignalFx's ingest servers automatically; in this situation, the timestamp of your datapoints will not accurately represent the time of their measurement (network latency, batching, etc. will all impact when those datapoints actually make it to SignalFx).
|
79
86
|
|
80
|
-
|
87
|
+
The `timestamp` must be a millisecond precision timestamp; the number of
|
88
|
+
milliseconds elapsed since Epoch. The `timestamp` field is optional, but
|
89
|
+
strongly recommended. If not specified, it will be set by SignalFx's
|
90
|
+
ingest servers automatically; in this situation, the timestamp of your
|
91
|
+
datapoints will not accurately represent the time of their measurement
|
92
|
+
(network latency, batching, etc. will all impact when those datapoints
|
93
|
+
actually make it to SignalFx).
|
81
94
|
|
82
|
-
|
95
|
+
### Sending multi-dimensional data
|
83
96
|
|
97
|
+
Reporting dimensions for the data is also optional, and can be
|
98
|
+
accomplished by specifying a `dimensions` parameter on each datapoint
|
99
|
+
containing a dictionary of string to string key/value pairs representing
|
100
|
+
the dimensions:
|
84
101
|
|
85
102
|
```ruby
|
86
|
-
require('signalfx')
|
103
|
+
require('signalfx')
|
87
104
|
|
88
|
-
client = SignalFx.new 'MY_SIGNALFX_TOKEN'
|
105
|
+
client = SignalFx.new 'MY_SIGNALFX_TOKEN'
|
89
106
|
|
90
107
|
client.send(
|
91
108
|
cumulative_counters:[
|
92
|
-
{ :metric => 'myfunc.calls_cumulative',
|
93
|
-
:value => 10,
|
109
|
+
{ :metric => 'myfunc.calls_cumulative',
|
110
|
+
:value => 10,
|
94
111
|
:dimensions => [{:key => 'host', :value => 'server1'}]},
|
95
112
|
...
|
96
113
|
],
|
97
114
|
gauges:[
|
98
|
-
{ :metric => 'myfunc.time',
|
99
|
-
:value=> 532,
|
115
|
+
{ :metric => 'myfunc.time',
|
116
|
+
:value=> 532,
|
100
117
|
:dimensions=> [{:key => 'host', :value => 'server1'}]},
|
101
118
|
...
|
102
119
|
],
|
103
120
|
counters:[
|
104
|
-
{ :metric=> 'myfunc.calls',
|
105
|
-
:value=> 42,
|
121
|
+
{ :metric=> 'myfunc.calls',
|
122
|
+
:value=> 42,
|
106
123
|
:dimensions=> [{:key => 'host', :value => 'server1'}]},
|
107
124
|
...
|
108
|
-
])
|
125
|
+
])
|
109
126
|
```
|
110
|
-
|
127
|
+
|
128
|
+
See `examples/generic_usecase.rb` for a complete code example for
|
129
|
+
reporting data.
|
111
130
|
|
112
131
|
### Sending events
|
113
132
|
|
114
|
-
Events can be sent to SignalFx via the `send_event` function. The
|
133
|
+
Events can be sent to SignalFx via the `send_event()` function. The
|
115
134
|
event type must be specified, and dimensions and extra event properties
|
116
|
-
can be supplied as well.
|
117
|
-
|
135
|
+
can be supplied as well. Also please specify event category: for that
|
136
|
+
get option from dictionary `EVENT_CATEGORIES`. Different categories of
|
137
|
+
events are supported. Available categories of events are `USER_DEFINED`,
|
138
|
+
`ALERT`, `AUDIT`, `JOB`, `COLLECTD`, `SERVICE_DISCOVERY`, `EXCEPTION`.
|
118
139
|
|
119
140
|
```ruby
|
120
|
-
require('signalfx')
|
141
|
+
require('signalfx')
|
121
142
|
|
122
|
-
client = SignalFx.new 'MY_SIGNALFX_TOKEN'
|
143
|
+
client = SignalFx.new 'MY_SIGNALFX_TOKEN'
|
123
144
|
|
124
145
|
client.send_event(
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
version: 'event_version'})
|
146
|
+
'[event_type]',
|
147
|
+
'[event_category]',
|
148
|
+
{ host: 'myhost',
|
149
|
+
service: 'myservice',
|
150
|
+
instance: 'myinstance' },
|
151
|
+
properties={ version: 'event_version' },
|
152
|
+
timestamp)
|
133
153
|
```
|
134
154
|
|
135
|
-
See `examples/generic_usecase.
|
155
|
+
See `examples/generic_usecase.rb` for a complete code example for
|
156
|
+
sending events.
|
136
157
|
|
137
158
|
## License
|
138
159
|
|
139
|
-
Apache Software License v2 ©
|
160
|
+
Apache Software License v2. Copyright © 2015-2016
|
161
|
+
[SignalFx](https://signalfx.com)
|
data/examples/generic_usecase.rb
CHANGED
@@ -36,8 +36,8 @@ while true do
|
|
36
36
|
instance: 'myinstance'}
|
37
37
|
properties = {version: version}
|
38
38
|
|
39
|
-
|
40
|
-
client.send_event(event_type, dimensions: dimensions, properties: properties)
|
39
|
+
event_category = SignalFxClient::EVENT_CATEGORIES[:ALERT]
|
40
|
+
client.send_event(event_type, event_category: event_category, dimensions: dimensions, properties: properties)
|
41
41
|
end
|
42
42
|
|
43
43
|
counter +=1
|
@@ -20,6 +20,16 @@ module Com
|
|
20
20
|
define :CUMULATIVE_COUNTER, 3
|
21
21
|
end
|
22
22
|
|
23
|
+
class EventCategory < ::Protobuf::Enum
|
24
|
+
define :USER_DEFINED, 1000000
|
25
|
+
define :ALERT, 100000
|
26
|
+
define :AUDIT, 200000
|
27
|
+
define :JOB, 300000
|
28
|
+
define :COLLECTD, 400000
|
29
|
+
define :SERVICE_DISCOVERY, 500000
|
30
|
+
define :EXCEPTION, 700000
|
31
|
+
end
|
32
|
+
|
23
33
|
|
24
34
|
##
|
25
35
|
# Message Classes
|
@@ -29,6 +39,10 @@ module Com
|
|
29
39
|
class DataPoint < ::Protobuf::Message; end
|
30
40
|
class DataPointUploadMessage < ::Protobuf::Message; end
|
31
41
|
class PointValue < ::Protobuf::Message; end
|
42
|
+
class Property < ::Protobuf::Message; end
|
43
|
+
class PropertyValue < ::Protobuf::Message; end
|
44
|
+
class Event < ::Protobuf::Message; end
|
45
|
+
class EventUploadMessage < ::Protobuf::Message; end
|
32
46
|
|
33
47
|
|
34
48
|
##
|
@@ -63,6 +77,30 @@ module Com
|
|
63
77
|
optional ::Com::Signalfx::Metrics::Protobuf::Datum, :value, 4
|
64
78
|
end
|
65
79
|
|
80
|
+
class Property
|
81
|
+
optional :string, :key, 1
|
82
|
+
optional ::Com::Signalfx::Metrics::Protobuf::PropertyValue, :value, 2
|
83
|
+
end
|
84
|
+
|
85
|
+
class PropertyValue
|
86
|
+
optional :string, :strValue, 1
|
87
|
+
optional :double, :doubleValue, 2
|
88
|
+
optional :int64, :intValue, 3
|
89
|
+
optional :bool, :boolValue, 4
|
90
|
+
end
|
91
|
+
|
92
|
+
class Event
|
93
|
+
required :string, :eventType, 1
|
94
|
+
repeated ::Com::Signalfx::Metrics::Protobuf::Dimension, :dimensions, 2
|
95
|
+
repeated ::Com::Signalfx::Metrics::Protobuf::Property, :properties, 3
|
96
|
+
optional ::Com::Signalfx::Metrics::Protobuf::EventCategory, :category, 4
|
97
|
+
optional :int64, :timestamp, 5
|
98
|
+
end
|
99
|
+
|
100
|
+
class EventUploadMessage
|
101
|
+
repeated ::Com::Signalfx::Metrics::Protobuf::Event, :events, 1
|
102
|
+
end
|
103
|
+
|
66
104
|
end
|
67
105
|
|
68
106
|
end
|
data/lib/signalfx.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
|
-
# Copyright (C) 2015 SignalFx, Inc. All rights reserved.
|
1
|
+
# Copyright (C) 2015-2016 SignalFx, Inc. All rights reserved.
|
2
2
|
|
3
3
|
require_relative 'signalfx/conf'
|
4
4
|
require_relative 'signalfx/protobuf_signal_fx_client'
|
5
5
|
require_relative 'signalfx/json_signal_fx_client'
|
6
6
|
|
7
7
|
module SignalFx
|
8
|
-
|
9
8
|
# SignalFx API client.
|
10
9
|
# This class presents a programmatic interface to SignalFx's metadata and
|
11
10
|
# ingest APIs. At the time being, only ingest is supported; more will come
|
@@ -22,22 +21,20 @@ module SignalFx
|
|
22
21
|
# @param batch_size - number
|
23
22
|
# @param user_agents - array
|
24
23
|
def self.new(api_token, enable_aws_unique_id: false, ingest_endpoint: Config::DEFAULT_INGEST_ENDPOINT,
|
25
|
-
|
24
|
+
timeout: Config::DEFAULT_TIMEOUT,
|
26
25
|
batch_size: Config::DEFAULT_BATCH_SIZE, user_agents: [])
|
27
26
|
begin
|
28
27
|
require_relative './proto/signal_fx_protocol_buffers.pb'
|
29
28
|
ProtoBufSignalFx.new(api_token, enable_aws_unique_id: enable_aws_unique_id, ingest_endpoint: ingest_endpoint,
|
30
|
-
|
29
|
+
timeout: timeout,
|
31
30
|
batch_size: batch_size, user_agents: user_agents)
|
32
31
|
|
33
32
|
rescue Exception => e
|
34
33
|
puts "Protocol Buffers not installed properly. Switch to JSON.
|
35
34
|
#{e}"
|
36
35
|
JsonSignalFx.new(api_token, enable_aws_unique_id: enable_aws_unique_id, ingest_endpoint: ingest_endpoint,
|
37
|
-
|
36
|
+
timeout: timeout,
|
38
37
|
batch_size: batch_size, user_agents: user_agents)
|
39
38
|
end
|
40
|
-
|
41
|
-
|
42
39
|
end
|
43
|
-
end
|
40
|
+
end
|
data/lib/signalfx/conf.rb
CHANGED
@@ -1,17 +1,15 @@
|
|
1
|
-
# Copyright (C) 2015 SignalFx, Inc. All rights reserved.
|
1
|
+
# Copyright (C) 2015-2016 SignalFx, Inc. All rights reserved.
|
2
2
|
|
3
3
|
module Config
|
4
|
-
# Default Parameters
|
4
|
+
# Default Parameters
|
5
5
|
DEFAULT_INGEST_ENDPOINT = 'https://ingest.signalfx.com'
|
6
|
-
DEFAULT_API_ENDPOINT = 'https://api.signalfx.com'
|
7
6
|
DEFAULT_BATCH_SIZE = 300 # Will wait for this many requests before posting
|
8
7
|
DEFAULT_TIMEOUT = 1
|
9
8
|
|
10
|
-
# Global Parameters
|
9
|
+
# Global Parameters
|
11
10
|
PROTOBUF_HEADER_CONTENT_TYPE = 'application/x-protobuf'
|
12
11
|
JSON_HEADER_CONTENT_TYPE = 'application/json'
|
13
12
|
|
14
13
|
AWS_UNIQUE_ID_URL = 'http://169.254.169.254/2014-11-05/dynamic/instance-identity/document'
|
15
|
-
|
16
14
|
AWS_UNIQUE_ID_DIMENSION_NAME = :AWSUniqueId
|
17
|
-
end
|
15
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2015 SignalFx, Inc. All rights reserved.
|
1
|
+
# Copyright (C) 2015-2016 SignalFx, Inc. All rights reserved.
|
2
2
|
|
3
3
|
require_relative './signal_fx_client'
|
4
4
|
require_relative './conf'
|
@@ -37,4 +37,10 @@ class JsonSignalFx < SignalFxClient
|
|
37
37
|
|
38
38
|
data.to_json
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
|
+
def build_event(event)
|
42
|
+
event_list = []
|
43
|
+
event_list << event
|
44
|
+
event_list.to_json
|
45
|
+
end
|
46
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2015 SignalFx, Inc. All rights reserved.
|
1
|
+
# Copyright (C) 2015-2016 SignalFx, Inc. All rights reserved.
|
2
2
|
|
3
3
|
require 'thread'
|
4
4
|
require_relative './conf'
|
@@ -60,4 +60,55 @@ class ProtoBufSignalFx < SignalFxClient
|
|
60
60
|
data_point_list.each { |datapoint| dpum.datapoints << datapoint }
|
61
61
|
dpum.to_s
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
|
+
def build_event(event)
|
65
|
+
protobuf_event = Com::Signalfx::Metrics::Protobuf::Event.new
|
66
|
+
if event[:eventType]
|
67
|
+
protobuf_event.eventType = event[:eventType]
|
68
|
+
end
|
69
|
+
|
70
|
+
if event[:category]
|
71
|
+
protobuf_event.category = Com::Signalfx::Metrics::Protobuf::EventCategory.const_get(event[:category].upcase)
|
72
|
+
end
|
73
|
+
|
74
|
+
if event[:timestamp]
|
75
|
+
protobuf_event.timestamp = event[:timestamp];
|
76
|
+
end
|
77
|
+
|
78
|
+
#set datapoint dimensions
|
79
|
+
dimensions = Array.new
|
80
|
+
if event[:dimensions] != nil
|
81
|
+
event[:dimensions].each {
|
82
|
+
|key, value| dimensions.push(
|
83
|
+
Com::Signalfx::Metrics::Protobuf::Dimension.new :key => key, :value => value)
|
84
|
+
}
|
85
|
+
end
|
86
|
+
protobuf_event.dimensions = dimensions
|
87
|
+
|
88
|
+
# assign value type
|
89
|
+
protobuf_event.properties = []
|
90
|
+
event[:properties].each { |prop_key, prop_value |
|
91
|
+
property = Com::Signalfx::Metrics::Protobuf::Property.new
|
92
|
+
property.key = prop_key
|
93
|
+
if prop_value.kind_of?(String)
|
94
|
+
property.value = Com::Signalfx::Metrics::Protobuf::PropertyValue.new :strValue => prop_value
|
95
|
+
else
|
96
|
+
if prop_value.kind_of?(Float)
|
97
|
+
property.value = Com::Signalfx::Metrics::Protobuf::PropertyValue.new :doubleValue => prop_value
|
98
|
+
else
|
99
|
+
if prop_value.kind_of?(Fixnum)
|
100
|
+
property.value = Com::Signalfx::Metrics::Protobuf::PropertyValue.new :intValue => prop_value
|
101
|
+
else
|
102
|
+
throw TypeError('Invalid Value ' + prop_value);
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
protobuf_event.properties << property
|
107
|
+
}
|
108
|
+
|
109
|
+
event_msg = Com::Signalfx::Metrics::Protobuf::EventUploadMessage.new
|
110
|
+
event_msg[:events] = Array.new
|
111
|
+
event_msg[:events] << protobuf_event
|
112
|
+
event_msg.to_s
|
113
|
+
end
|
114
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2015 SignalFx, Inc. All rights reserved.
|
1
|
+
# Copyright (C) 2015-2016 SignalFx, Inc. All rights reserved.
|
2
2
|
|
3
3
|
require_relative './version'
|
4
4
|
require_relative './conf'
|
@@ -13,15 +13,26 @@ class SignalFxClient
|
|
13
13
|
HEADER_USER_AGENT_KEY = 'User-Agent'
|
14
14
|
HEADER_CONTENT_TYPE = 'Content-Type'
|
15
15
|
INGEST_ENDPOINT_SUFFIX = 'v2/datapoint'
|
16
|
-
|
16
|
+
EVENT_ENDPOINT_SUFFIX = 'v2/event'
|
17
|
+
|
18
|
+
EVENT_CATEGORIES = {
|
19
|
+
USER_DEFINED: 'USER_DEFINED',
|
20
|
+
ALERT: 'ALERT',
|
21
|
+
AUDIT: 'AUDIT',
|
22
|
+
JOB: 'JOB',
|
23
|
+
COLLECTD: 'COLLECTD',
|
24
|
+
SERVICE_DISCOVERY: 'SERVICE_DISCOVERY',
|
25
|
+
EXCEPTION: 'EXCEPTION'
|
26
|
+
}
|
27
|
+
|
28
|
+
$event_categories = EVENT_CATEGORIES
|
17
29
|
|
18
30
|
def initialize(api_token, enable_aws_unique_id: false, ingest_endpoint: Config::DEFAULT_INGEST_ENDPOINT,
|
19
|
-
|
31
|
+
timeout: Config::DEFAULT_TIMEOUT,
|
20
32
|
batch_size: Config::DEFAULT_BATCH_SIZE, user_agents: [])
|
21
33
|
|
22
34
|
@api_token = api_token
|
23
35
|
@ingest_endpoint = ingest_endpoint
|
24
|
-
@api_endpoint = api_endpoint
|
25
36
|
@timeout = timeout
|
26
37
|
@batch_size = batch_size
|
27
38
|
@user_agents = user_agents
|
@@ -42,7 +53,6 @@ class SignalFxClient
|
|
42
53
|
end
|
43
54
|
}
|
44
55
|
end
|
45
|
-
puts('initialize end')
|
46
56
|
end
|
47
57
|
|
48
58
|
#Send the given metrics to SignalFx synchronously.
|
@@ -100,8 +110,7 @@ class SignalFxClient
|
|
100
110
|
Thread.abort_on_exception = true
|
101
111
|
Thread.start {
|
102
112
|
begin
|
103
|
-
|
104
|
-
post(data_to_send, @ingest_endpoint, INGEST_ENDPOINT_SUFFIX){
|
113
|
+
post(data_to_send, @ingest_endpoint, INGEST_ENDPOINT_SUFFIX) {
|
105
114
|
@async_running = false
|
106
115
|
}
|
107
116
|
ensure
|
@@ -115,22 +124,38 @@ class SignalFxClient
|
|
115
124
|
#
|
116
125
|
#Args:
|
117
126
|
# event_type (string): the event type (name of the event time series).
|
127
|
+
# event_category (string): the category of event. Choose one from EVENT_CATEGORIES list
|
118
128
|
# dimensions (dict): a map of event dimensions.
|
119
129
|
# properties (dict): a map of extra properties on that event.
|
120
|
-
|
130
|
+
# timestamp (int64): a timestamp, by default is current time
|
131
|
+
def send_event(event_type, event_category: EVENT_CATEGORIES[:USER_DEFINED],
|
132
|
+
dimensions: {}, properties: {}, timestamp: (Time.now.to_i * 1000).to_i)
|
133
|
+
if event_type.blank?
|
134
|
+
raise 'Type of event should not be empty!'
|
135
|
+
end
|
136
|
+
|
137
|
+
event_cat = event_category
|
138
|
+
if event_category.blank?
|
139
|
+
event_cat = EVENT_CATEGORIES[:USER_DEFINED]
|
140
|
+
end
|
141
|
+
|
142
|
+
if !event_cat.blank? and !EVENT_CATEGORIES.has_value?(event_cat)
|
143
|
+
raise 'Unsupported event category: ' + event_cat
|
144
|
+
end
|
145
|
+
|
121
146
|
data = {
|
147
|
+
category: event_cat,
|
122
148
|
eventType: event_type,
|
123
149
|
dimensions: dimensions,
|
124
|
-
properties: properties
|
150
|
+
properties: properties,
|
151
|
+
timestamp: timestamp
|
125
152
|
}
|
126
153
|
|
127
154
|
if @aws_unique_id
|
128
155
|
data[:dimensions][Config::AWS_UNIQUE_ID_DIMENSION_NAME] = @aws_unique_id
|
129
156
|
end
|
130
157
|
|
131
|
-
|
132
|
-
|
133
|
-
post(data.to_json, @api_endpoint, API_ENDPOINT_SUFFIX, Config::JSON_HEADER_CONTENT_TYPE)
|
158
|
+
post(build_event(data), @ingest_endpoint, EVENT_ENDPOINT_SUFFIX)
|
134
159
|
end
|
135
160
|
|
136
161
|
protected
|
@@ -151,16 +176,20 @@ class SignalFxClient
|
|
151
176
|
raise 'Subclasses should implement this!'
|
152
177
|
end
|
153
178
|
|
179
|
+
def build_event(event)
|
180
|
+
raise 'Subclasses should implement this!'
|
181
|
+
end
|
182
|
+
|
154
183
|
private
|
155
184
|
|
156
|
-
def post(data_to_send, url, suffix,
|
185
|
+
def post(data_to_send, url, suffix, &block)
|
157
186
|
begin
|
158
187
|
http_user_agents = ''
|
159
188
|
if @user_agents != nil && @user_agents.length > 0
|
160
189
|
http_user_agents = ', ' + @user_agents.join(', ')
|
161
190
|
end
|
162
191
|
|
163
|
-
headers = {HEADER_CONTENT_TYPE =>
|
192
|
+
headers = {HEADER_CONTENT_TYPE => header_content_type,
|
164
193
|
HEADER_API_TOKEN_KEY => @api_token,
|
165
194
|
HEADER_USER_AGENT_KEY => Version::NAME + '/' + Version::VERSION + http_user_agents}
|
166
195
|
|
@@ -169,7 +198,7 @@ class SignalFxClient
|
|
169
198
|
url: url + '/' + suffix,
|
170
199
|
headers: headers,
|
171
200
|
payload: data_to_send,
|
172
|
-
verify_ssl: OpenSSL::SSL::
|
201
|
+
verify_ssl: OpenSSL::SSL::VERIFY_PEER,
|
173
202
|
timeout: @timeout) { |response|
|
174
203
|
case response.code
|
175
204
|
when 200
|
@@ -223,4 +252,4 @@ class SignalFxClient
|
|
223
252
|
}
|
224
253
|
end
|
225
254
|
end
|
226
|
-
end
|
255
|
+
end
|
data/lib/signalfx/version.rb
CHANGED
data/signalfx.gemspec
CHANGED
@@ -27,10 +27,12 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
28
|
spec.require_paths = ["lib"]
|
29
29
|
|
30
|
+
spec.required_ruby_version = '>= 2.2.0'
|
31
|
+
|
30
32
|
spec.add_development_dependency "bundler", "~> 1.10"
|
31
33
|
spec.add_development_dependency "rake", "~> 10.0"
|
32
|
-
spec.add_development_dependency "rspec"
|
33
|
-
spec.add_development_dependency "webmock", "~> 1
|
34
|
+
spec.add_development_dependency "rspec", "~> 3.3"
|
35
|
+
spec.add_development_dependency "webmock", "~> 2.1"
|
34
36
|
spec.add_dependency "protobuf", "~> 3.5.1", ">= 3.5.1"
|
35
37
|
spec.add_dependency "rest-client", "~> 1.8"
|
36
|
-
end
|
38
|
+
end
|
metadata
CHANGED
@@ -1,103 +1,103 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: signalfx
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SignalFx, Inc
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.10'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.10'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '10.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '3.3'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '3.3'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: webmock
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '1
|
61
|
+
version: '2.1'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '1
|
68
|
+
version: '2.1'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: protobuf
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - ~>
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: 3.5.1
|
76
|
-
- -
|
76
|
+
- - ">="
|
77
77
|
- !ruby/object:Gem::Version
|
78
78
|
version: 3.5.1
|
79
79
|
type: :runtime
|
80
80
|
prerelease: false
|
81
81
|
version_requirements: !ruby/object:Gem::Requirement
|
82
82
|
requirements:
|
83
|
-
- - ~>
|
83
|
+
- - "~>"
|
84
84
|
- !ruby/object:Gem::Version
|
85
85
|
version: 3.5.1
|
86
|
-
- -
|
86
|
+
- - ">="
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: 3.5.1
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
90
|
name: rest-client
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
92
92
|
requirements:
|
93
|
-
- - ~>
|
93
|
+
- - "~>"
|
94
94
|
- !ruby/object:Gem::Version
|
95
95
|
version: '1.8'
|
96
96
|
type: :runtime
|
97
97
|
prerelease: false
|
98
98
|
version_requirements: !ruby/object:Gem::Requirement
|
99
99
|
requirements:
|
100
|
-
- - ~>
|
100
|
+
- - "~>"
|
101
101
|
- !ruby/object:Gem::Version
|
102
102
|
version: '1.8'
|
103
103
|
description: This is a programmatic interface in Ruby for SignalFx's metadata and
|
@@ -110,8 +110,8 @@ executables: []
|
|
110
110
|
extensions: []
|
111
111
|
extra_rdoc_files: []
|
112
112
|
files:
|
113
|
-
- .gitignore
|
114
|
-
- .travis.yml
|
113
|
+
- ".gitignore"
|
114
|
+
- ".travis.yml"
|
115
115
|
- Gemfile
|
116
116
|
- Gemfile.lock
|
117
117
|
- README.md
|
@@ -137,17 +137,17 @@ require_paths:
|
|
137
137
|
- lib
|
138
138
|
required_ruby_version: !ruby/object:Gem::Requirement
|
139
139
|
requirements:
|
140
|
-
- -
|
140
|
+
- - ">="
|
141
141
|
- !ruby/object:Gem::Version
|
142
|
-
version:
|
142
|
+
version: 2.2.0
|
143
143
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
144
144
|
requirements:
|
145
|
-
- -
|
145
|
+
- - ">="
|
146
146
|
- !ruby/object:Gem::Version
|
147
147
|
version: '0'
|
148
148
|
requirements: []
|
149
149
|
rubyforge_project:
|
150
|
-
rubygems_version: 2.
|
150
|
+
rubygems_version: 2.4.5.1
|
151
151
|
signing_key:
|
152
152
|
specification_version: 4
|
153
153
|
summary: Ruby client library for SignalFx
|