fluent-plugin-pagerduty 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 96e70bdf4f296d3d857f89dbd2bb8938cb8b859e
4
- data.tar.gz: 1aee8fba1aca9fc563c819c7e262623fe4366acc
3
+ metadata.gz: 3e1ab17de590fac6a23aca6395aaacbad6e895a6
4
+ data.tar.gz: 4c57cc67becf6ca2fd81dcf7ab99b3a3987eb48b
5
5
  SHA512:
6
- metadata.gz: 8787ed0e0f46fc14f5aaf7efbf2b1662cb439e9bf68ced78b65de5b507e2d2d2e46a22ebd25ef232040c1e4181ac7217e04ec53d0f56f6e7107237898c2e7f8e
7
- data.tar.gz: 26c760145fa0902f8856bf2ebf23e24e54136c813a9de17ca61270956e083b62c12c9ac8580d951a4b3c973055b535e7d90333b9f478220724870a767604094c
6
+ metadata.gz: 3d4c97238f8765492974989bc7fbe6149434a6855769123879c1a8ad0010d6fd1d5f484100174319bfed8d138d3da7a3e29f4ed0c78046509d258be5396a92de
7
+ data.tar.gz: cf500b232f2f5807d9515125f0b7c36df8b95b0ec4c8251b2afe0c0bfc7cd545de6e9bdb5dbc102494e6f3e355c7598222d85f034a5e3ca6aa74189bbe7c0a55
data/.gitignore CHANGED
@@ -16,3 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  vendor/*
19
+ *.DS_Store
data/README.md CHANGED
@@ -1,24 +1,26 @@
1
- # fluent-plugin-pagerduty does not work
1
+ # fluent-plugin-pagerduty
2
2
 
3
3
  Fluentd Output plugin to relay alert notification from application to [PagerDuty](http://www.pagerduty.com/).
4
4
 
5
5
  ## Installation
6
6
 
7
- install with `gem` or `fluent-gem` command as:
7
+ install with `td-agnet-gem` or `fluent-gem`, `gem` command as:
8
8
 
9
9
  ```
10
- # for fluentd
11
- $ gem install fluent-plugin-pagerduty
10
+ # for td-agent2 (recommend)
11
+ $ sudo td-agent-gem install fluent-plugin-pagerduty -v 0.0.1
12
12
 
13
13
  # for td-agent
14
14
  $ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-pagerduty -v 0.0.1
15
15
 
16
- # for td-agent2
17
- $ sudo td-agent-gem install fluent-plugin-pagerduty -v 0.0.1
16
+ # for system installed fluentd
17
+ $ gem install fluent-plugin-pagerduty
18
18
  ```
19
19
 
20
20
  ## Usage
21
21
 
22
+ <img width="1025" alt="screenshot 2017-03-18 18 20 43" src="https://cloud.githubusercontent.com/assets/1428486/24077350/ab9f9dd4-0c07-11e7-9f9f-8cd27a451b6e.png">
23
+
22
24
  1. add service selecting `Service Type : Generic API system` on PagerDuty websites
23
25
  2. copy API Key from the `Services` page.
24
26
  3. install fluent-plugin-pagerduty with gem or fluent-gem command.
@@ -26,15 +28,19 @@ $ sudo td-agent-gem install fluent-plugin-pagerduty -v 0.0.1
26
28
  5. restart fluentd process.
27
29
  6. send test message for fluent-plugin-pagerduty
28
30
 
29
- #### configuration example
31
+ ### Examples
32
+
33
+ #### Simple alert (JSON pass-thru)
34
+
35
+ In this example, a JSON record already conforming to the PagerDuty API is processed by Fluentd and passed through to PagerDuty as-is, triggering a simple alert.
30
36
 
31
37
  ```
32
38
  <source>
33
- type forward
39
+ @type forward
34
40
  </source>
35
41
 
36
42
  <source>
37
- type http
43
+ @type http
38
44
  port 8888
39
45
  </source>
40
46
 
@@ -44,8 +50,6 @@ $ sudo td-agent-gem install fluent-plugin-pagerduty -v 0.0.1
44
50
  </match>
45
51
  ```
46
52
 
47
- #### notify example
48
-
49
53
  ```
50
54
  # via forward
51
55
  $ echo '{"description":"Form validation has failed","details":{"name":"success","mail":"failed"}}' | fluent-cat notify.pagerduty
@@ -54,6 +58,70 @@ $ echo '{"description":"Form validation has failed","details":{"name":"success",
54
58
  $ curl http://localhost:8888/notify.pagerduty -F 'json={"description":"Form validation has failed","details":{"name":"success","mail":"failed"}}'
55
59
  ```
56
60
 
61
+ #### Advanced alert (transformed JSON)
62
+
63
+ In this example, a JSON record is referenced to build a PagerDuty event with an incident key for managing [de-duplication](https://v2.developer.pagerduty.com/docs/events-api#incident-de-duplication-and-incident_key).
64
+
65
+ ```
66
+ <source>
67
+ @type forward
68
+ </source>
69
+
70
+ <source>
71
+ @type http
72
+ port 8888
73
+ </source>
74
+
75
+ <match notify.pagerduty>
76
+ type pagerduty
77
+ service_key ******************
78
+ description Alarm@${Node["Location"]}:: ${Log["Message"]}
79
+ incident_key [${tag_parts[-1]}] ${Log["File"]}:${Log["Line"]}
80
+ </match>
81
+ ```
82
+
83
+ ```
84
+ # via forward
85
+ $ echo '{"Node":{"Location":"Somewhere","IP Address":"10.0.0.1"},"Log":{"Level": "ERROR","File":"FooBar.cpp","Line":42,"Message":"A very important logging message"}}' | fluent-cat notify.pagerduty
86
+
87
+ # via http
88
+ $ curl http://localhost:8888/notify.pagerduty -F 'json={"Node":{"Location":"Somewhere","IP Address":"10.0.0.1"},"Log":{"Level": "ERROR","File":"FooBar.cpp","Line":42,"Message":"A very important logging message"}}'
89
+ ```
90
+
91
+
92
+ ### Option Parameters
93
+
94
+ - `service_key` (required)
95
+
96
+ The unique API identifier generated for each PagerDuty service belonging to a PagerDuty account. Must be present for any PagerDuty events.
97
+
98
+ - `event_type` (optional)
99
+
100
+ The PagerDuty event type: `trigger`, `acknowledge`, or `resolve`. If unspecified, the default is `trigger`.
101
+
102
+ - `description` (conditionally required)
103
+
104
+ The message content of a PagerDuty event. PagerDuty event types of `trigger` must contain a description. The content of the description may be built using Placeholders (see next section).
105
+
106
+ - `incident_key` (optional)
107
+
108
+ The identifier used for PagerDuty's [de-duplication of events](https://v2.developer.pagerduty.com/docs/events-api#incident-de-duplication-and-incident_key). The content of the incident key may be built using Placeholders (see next section).
109
+
110
+ ### Placeholders
111
+
112
+ These placeholders are available:
113
+
114
+ * ${…}
115
+ * `hashName["key"]` Value of `key` in named hash
116
+ * `arrayName[N]` Value at index _N_ in named array
117
+ * `primitive` Value of named primitive
118
+
119
+ Placeholders are built recursively and concatenated. For example, a specific value within a hash containing an array of hashes could be referenced as: `${foo["bar"][2]["baz"]}`.
120
+ * ${tag} Input tag
121
+ * ${tag\_parts[N]} Input tag splitted by '.' indexed with _N_ such as `${tag_parts[0]}`, `${tag_parts[-1]}`.
122
+
123
+ Placeholder functionality is derived from features of [fluent-plugin-record-reformer](https://github.com/sonots/fluent-plugin-record-reformer).
124
+
57
125
  ## Contributing
58
126
 
59
127
  1. Fork it
@@ -72,5 +140,5 @@ Copyright (c) 2013- Kentaro Yoshida (@yoshi_ken)
72
140
 
73
141
  ## License
74
142
 
75
- Apache License, Version 2.0
143
+ [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
76
144
 
@@ -4,10 +4,9 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "fluent-plugin-pagerduty"
7
- spec.version = "0.0.1"
7
+ spec.version = "0.1.0"
8
8
  spec.authors = ["Kentaro Yoshida"]
9
9
  spec.email = ["y.ken.studio@gmail.com"]
10
- spec.description = %q{Fluentd Input plugin to replay alert notification for PagerDuty API.}
11
10
  spec.summary = %q{Fluentd Input plugin to replay alert notification for PagerDuty API.}
12
11
  spec.homepage = "https://github.com/y-ken/fluent-plugin-pagerduty"
13
12
  spec.license = "Apache License, Version 2.0"
@@ -9,34 +9,137 @@ class Fluent::PagerdutyOutput < Fluent::Output
9
9
  config_param :service_key, :string, :default => nil
10
10
  config_param :event_type, :string, :default => 'trigger'
11
11
  config_param :description, :string, :default => nil
12
+ config_param :incident_key, :string, :default => nil
12
13
 
13
14
  def configure(conf)
14
15
  super
15
16
 
17
+ # API requires service key
16
18
  if @service_key.nil?
17
19
  $log.warn "pagerduty: service_key required."
18
20
  end
21
+
22
+ # PagerDuty trigger event type requires description, other event types do not
23
+ if @event_type == 'trigger' && @description.nil?
24
+ $log.warn "pagerduty: description required for trigger event_type."
25
+ end
19
26
  end
20
27
 
21
28
  def emit(tag, es, chain)
22
29
  es.each do |time,record|
23
- call_pagerduty(record)
30
+ call_pagerduty(tag, record)
24
31
  end
25
32
 
26
33
  chain.next
27
34
  end
28
35
 
29
- def call_pagerduty(record)
36
+ def call_pagerduty(tag, record)
30
37
  begin
38
+ expander = PlaceholderExpander.new({:log => log})
39
+ tag_parts = tag.split('.')
40
+ placeholder_values = {
41
+ 'tag' => tag,
42
+ 'tag_parts' => tag_parts,
43
+ 'record' => record,
44
+ }
45
+
46
+ placeholders = expander.prepare_placeholders(placeholder_values)
47
+
31
48
  service_key = record['service_key'] || @service_key
32
49
  event_type = record['event_type'] || @event_type
33
50
  description = record['description'] || record['message'] || @description
51
+ incident_key = record['incident_key'] || @incident_key
34
52
  details = record['details'] || record
35
53
  options = {"details" => details}
36
- api = Pagerduty.new(service_key)
54
+
55
+ description = expander.expand(description, placeholders)
56
+
57
+ if !@incident_key.nil?
58
+ incident_key = expander.expand(incident_key, placeholders)
59
+ api = PagerdutyIncident.new(service_key, incident_key)
60
+ else
61
+ api = Pagerduty.new(service_key)
62
+ end
63
+
37
64
  incident = api.trigger description, options
38
65
  rescue => e
39
66
  $log.error "pagerduty: request failed. ", :error_class=>e.class, :error=>e.message
40
67
  end
41
68
  end
42
69
  end
70
+
71
+
72
+ # Modified PlaceholderExpander borrowed from fluent-plugin-record-reformer
73
+ # https://github.com/sonots/fluent-plugin-record-reformer
74
+ # Original author: Naotoshi Seo
75
+ # MIT License: https://github.com/sonots/fluent-plugin-record-reformer/blob/master/LICENSE
76
+ # Modifications: Michael Karlesky
77
+ # Changes:
78
+ # - Stripped down to limited use case
79
+ # - Building of placeholders is now recursive to handle any depth of hash, array, and primitive
80
+ class PlaceholderExpander
81
+ attr_reader :placeholders, :log
82
+
83
+ def initialize(params)
84
+ @log = params[:log]
85
+ end
86
+
87
+ def prepare_placeholders(placeholder_values)
88
+ placeholders = {}
89
+
90
+ placeholder_values.each do |key, value|
91
+ # For any entry in `placeholder_values` that is a hash, we effectively ignore its internal name.
92
+ # For example, `record` is an important hash, but referencing it at the top-level is superfluous namespacing.
93
+ # Instead of '${record["Node"]["Location"]}',
94
+ # '${Node["Location"]}' more closely maps to a user's knowledge of a data to be processed.
95
+ if value.kind_of?(Hash)
96
+ value.each do |key, value|
97
+ build_placeholders(placeholders, key, value)
98
+ end
99
+ else
100
+ build_placeholders(placeholders, key, value)
101
+ end
102
+ end
103
+
104
+ placeholders
105
+ end
106
+
107
+ # Expand string (`${foo["bar"]}`) with placeholders
108
+ def expand(str, placeholders)
109
+ single_placeholder_matched = str.match(/\A(\${[^}]+}|__[A-Z_]+__)\z/)
110
+ if single_placeholder_matched
111
+ log_if_unknown_placeholder($1, placeholders)
112
+ return placeholders[single_placeholder_matched[1]]
113
+ end
114
+ str.gsub(/(\${[^}]+}|__[A-Z_]+__)/) {
115
+ log_if_unknown_placeholder($1, placeholders)
116
+ placeholders[$1]
117
+ }
118
+ end
119
+
120
+ private
121
+
122
+ # Recurses to build any depth of hash, arrays, and primitives
123
+ def build_placeholders(placeholders, key, value)
124
+ if value.kind_of?(Array) # tag_parts, etc
125
+ size = value.size
126
+ value.each_with_index do |v, idx|
127
+ build_placeholders(placeholders, "#{key}[#{idx}]", v)
128
+ build_placeholders(placeholders, "#{key}[#{idx-size}]", v) # support [-1]
129
+ end
130
+ elsif value.kind_of?(Hash) # record, etc
131
+ value.each do |k, v|
132
+ build_placeholders(placeholders, %Q[#{key}["#{k}"]], v) # record["foo"]
133
+ end
134
+ else
135
+ placeholders.store("${#{key}}", value)
136
+ end
137
+ end
138
+
139
+ def log_if_unknown_placeholder(placeholder, placeholders)
140
+ unless placeholders.include?(placeholder)
141
+ log.warn "pagerduty: unknown placeholder `#{placeholder}` found"
142
+ end
143
+ end
144
+ end
145
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-pagerduty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kentaro Yoshida
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-19 00:00:00.000000000 Z
11
+ date: 2018-03-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,7 +66,7 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- description: Fluentd Input plugin to replay alert notification for PagerDuty API.
69
+ description:
70
70
  email:
71
71
  - y.ken.studio@gmail.com
72
72
  executables: []