fluent-plugin-slack 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +7 -0
- data/CHANGELOG.md +13 -0
- data/README.md +8 -3
- data/Rakefile +6 -1
- data/VERSION +1 -1
- data/example.conf +17 -0
- data/fluent-plugin-slack.gemspec +2 -2
- data/lib/fluent/plugin/out_buffered_slack.rb +24 -16
- data/lib/fluent/plugin/out_slack.rb +24 -16
- data/lib/fluent/plugin/slack_client.rb +86 -48
- data/lib/fluent/plugin/slack_client/error.rb +24 -0
- data/test.sh +2 -0
- data/test/plugin/test_out_slack.rb +27 -12
- data/test/plugin/test_slack_client.rb +37 -2
- metadata +11 -4
- data/AUTHORS +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63fd1c619f76e7bb3df9b2ff11e69af43e23f810
|
4
|
+
data.tar.gz: 8fd2eb0e8790c71c8689ae88e42f8a4bae3f1d3b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf331ec94a09e572f2aa1c958842634195dad9078cc7fbf86813c121d88ddeb69568617663cf2012151646c52c6ec64203f95b3738348937bc0b8a417c6da976
|
7
|
+
data.tar.gz: c16e8a479300bc03539232a4d76d172d7eaa8c0d0e640612424fa483f2b7abd4510de6a3fee5b55d0eb2b70a395cc1a65d2425e3eb62c0e7a1058d9be3418d66
|
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
## 0.5.1 (2015/03/27)
|
2
|
+
|
3
|
+
Enhancements:
|
4
|
+
|
5
|
+
* Support `auto_channels_create` option to automatically create channels.
|
6
|
+
|
7
|
+
## 0.5.0 (2015/03/22)
|
8
|
+
|
9
|
+
Enhancements:
|
10
|
+
|
11
|
+
* Support `message` and `message_keys` options
|
12
|
+
* Support `title` and `title_keys` options
|
13
|
+
* Support `channel_keys` options to dynamically change channels
|
data/README.md
CHANGED
@@ -26,7 +26,7 @@ fluent_logger.post('slack', {
|
|
26
26
|
})
|
27
27
|
```
|
28
28
|
|
29
|
-
# Usage (
|
29
|
+
# Usage (Web API)
|
30
30
|
|
31
31
|
```apache
|
32
32
|
<match slack>
|
@@ -50,8 +50,8 @@ fluent_logger.post('slack', {
|
|
50
50
|
|
51
51
|
|parameter|description|default|
|
52
52
|
|---|---|---|
|
53
|
-
|
|
54
|
-
|token|Token for
|
53
|
+
|webhook_url|Incoming Webhook URI (Required for Incoming Webhook mode)||
|
54
|
+
|token|Token for Web API (Required for Web API mode)||
|
55
55
|
|username|name of bot|fluentd|
|
56
56
|
|color|color to use|good|
|
57
57
|
|icon_emoji|emoji to use as the icon|`:question:`|
|
@@ -61,6 +61,7 @@ fluent_logger.post('slack', {
|
|
61
61
|
|title_keys|keys used to format the title|nil|
|
62
62
|
|message|message format. %s will be replaced with value specified by message_keys|%s|
|
63
63
|
|message_keys|keys used to format messages|message|
|
64
|
+
|auto_channels_create|Create channels if not exist. Available only with Web API mode, and a token for Normal User is required (Bot User can not create channels. See https://api.slack.com/bot-users)|false|
|
64
65
|
|
65
66
|
`fluent-plugin-slack` uses `SetTimeKeyMixin` and `SetTagKeyMixin`, so you can also use:
|
66
67
|
|
@@ -75,6 +76,10 @@ fluent_logger.post('slack', {
|
|
75
76
|
|
76
77
|
`fluent-plugin-slack` is a kind of BufferedOutput plugin, so you can also use [Buffer Parameters](http://docs.fluentd.org/articles/out_exec#buffer-parameters).
|
77
78
|
|
79
|
+
## ChangeLog
|
80
|
+
|
81
|
+
See [CHANGELOG.md](CHANGELOG.md) for details.
|
82
|
+
|
78
83
|
# Contributors
|
79
84
|
|
80
85
|
- [@sonots](https://github.com/sonots)
|
data/Rakefile
CHANGED
@@ -7,5 +7,10 @@ Rake::TestTask.new(:test) do |test|
|
|
7
7
|
test.pattern = 'test/**/test_*.rb'
|
8
8
|
test.verbose = true
|
9
9
|
end
|
10
|
-
|
11
10
|
task :default => :test
|
11
|
+
|
12
|
+
desc 'Open an irb session preloaded with the gem library'
|
13
|
+
task :console do
|
14
|
+
sh 'irb -rubygems -I lib'
|
15
|
+
end
|
16
|
+
task :c => :console
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.1
|
data/example.conf
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
<source>
|
2
|
+
type forward
|
3
|
+
</source>
|
4
|
+
|
5
|
+
<match tag>
|
6
|
+
type slack
|
7
|
+
token "#{ENV['TOKEN']}"
|
8
|
+
username fluentd
|
9
|
+
color good
|
10
|
+
icon_emoji :ghost:
|
11
|
+
channel general
|
12
|
+
message %s %s
|
13
|
+
message_keys tag,message
|
14
|
+
title %s %s
|
15
|
+
title_keys tag,message
|
16
|
+
flush_interval 1s # slack API has limit as a post / sec
|
17
|
+
</match>
|
data/fluent-plugin-slack.gemspec
CHANGED
@@ -7,8 +7,8 @@ Gem::Specification.new do |gem|
|
|
7
7
|
gem.homepage = "https://github.com/sowawa/fluent-plugin-slack"
|
8
8
|
gem.summary = gem.description
|
9
9
|
gem.version = File.read("VERSION").strip
|
10
|
-
gem.authors = ["Keisuke SOGAWA"]
|
11
|
-
gem.email = "keisuke.sogawa@gmail.com"
|
10
|
+
gem.authors = ["Keisuke SOGAWA", "Naotoshi Seo"]
|
11
|
+
gem.email = ["keisuke.sogawa@gmail.com", "sonots@gmail.com"]
|
12
12
|
gem.has_rdoc = false
|
13
13
|
gem.files = `git ls-files`.split("\n")
|
14
14
|
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -11,22 +11,23 @@ module Fluent
|
|
11
11
|
config_set_default :include_time_key, true
|
12
12
|
config_set_default :include_tag_key, true
|
13
13
|
|
14
|
-
config_param :webhook_url,
|
15
|
-
config_param :token,
|
16
|
-
config_param :username,
|
17
|
-
config_param :color,
|
18
|
-
config_param :icon_emoji,
|
19
|
-
|
20
|
-
|
21
|
-
config_param :
|
14
|
+
config_param :webhook_url, :string, default: nil # incoming webhook
|
15
|
+
config_param :token, :string, default: nil # api token
|
16
|
+
config_param :username, :string, default: 'fluentd'
|
17
|
+
config_param :color, :string, default: 'good'
|
18
|
+
config_param :icon_emoji, :string, default: ':question:'
|
19
|
+
config_param :auto_channels_create, :bool, default: false
|
20
|
+
|
21
|
+
config_param :channel, :string
|
22
|
+
config_param :channel_keys, default: nil do |val|
|
22
23
|
val.split(',')
|
23
24
|
end
|
24
|
-
config_param :title,
|
25
|
-
config_param :title_keys,
|
25
|
+
config_param :title, :string, default: nil
|
26
|
+
config_param :title_keys, default: nil do |val|
|
26
27
|
val.split(',')
|
27
28
|
end
|
28
|
-
config_param :message,
|
29
|
-
config_param :message_keys,
|
29
|
+
config_param :message, :string, default: nil
|
30
|
+
config_param :message_keys, default: nil do |val|
|
30
31
|
val.split(',')
|
31
32
|
end
|
32
33
|
|
@@ -48,19 +49,24 @@ module Fluent
|
|
48
49
|
@channel = '#' + @channel unless @channel.start_with?('#')
|
49
50
|
|
50
51
|
if @webhook_url
|
52
|
+
if @webhook_url.empty?
|
53
|
+
raise Fluent::ConfigError.new("`webhook_url` is an empty string")
|
54
|
+
end
|
51
55
|
# following default values are for old version compatibility
|
52
56
|
@title ||= '%s'
|
53
57
|
@title_keys ||= %w[tag]
|
54
58
|
@message ||= '[%s] %s'
|
55
59
|
@message_keys ||= %w[time message]
|
56
60
|
@slack = Fluent::SlackClient::IncomingWebhook.new(@webhook_url)
|
57
|
-
|
58
|
-
|
59
|
-
raise Fluent::ConfigError.new("`token` is
|
61
|
+
elsif @token
|
62
|
+
if @token.empty?
|
63
|
+
raise Fluent::ConfigError.new("`token` is an empty string")
|
60
64
|
end
|
61
65
|
@message ||= '%s'
|
62
66
|
@message_keys ||= %w[message]
|
63
67
|
@slack = Fluent::SlackClient::WebApi.new
|
68
|
+
else
|
69
|
+
raise Fluent::ConfigError.new("Either of `webhook_url` or `token` is required")
|
64
70
|
end
|
65
71
|
@slack.log = log
|
66
72
|
@slack.debug_dev = log.out if log.level <= Fluent::Log::LEVEL_TRACE
|
@@ -84,6 +90,8 @@ module Fluent
|
|
84
90
|
raise Fluent::ConfigError, "string specifier '%s' for `channel` and `channel_keys` specification mismatch"
|
85
91
|
end
|
86
92
|
end
|
93
|
+
|
94
|
+
@post_message_opts = @auto_channels_create ? {auto_channels_create: true} : {}
|
87
95
|
end
|
88
96
|
|
89
97
|
def format(tag, time, record)
|
@@ -93,7 +101,7 @@ module Fluent
|
|
93
101
|
def write(chunk)
|
94
102
|
begin
|
95
103
|
payloads = build_payloads(chunk)
|
96
|
-
payloads.each {|payload| @slack.post_message(payload) }
|
104
|
+
payloads.each {|payload| @slack.post_message(payload, @post_message_opts) }
|
97
105
|
rescue Net::OpenTimeout, Net::ReadTimeout => e
|
98
106
|
log.warn "out_slack:", :error => e.to_s, :error_class => e.class.to_s
|
99
107
|
raise e # let Fluentd retry
|
@@ -11,22 +11,23 @@ module Fluent
|
|
11
11
|
config_set_default :include_time_key, true
|
12
12
|
config_set_default :include_tag_key, true
|
13
13
|
|
14
|
-
config_param :webhook_url,
|
15
|
-
config_param :token,
|
16
|
-
config_param :username,
|
17
|
-
config_param :color,
|
18
|
-
config_param :icon_emoji,
|
19
|
-
|
20
|
-
|
21
|
-
config_param :
|
14
|
+
config_param :webhook_url, :string, default: nil # incoming webhook
|
15
|
+
config_param :token, :string, default: nil # api token
|
16
|
+
config_param :username, :string, default: 'fluentd'
|
17
|
+
config_param :color, :string, default: 'good'
|
18
|
+
config_param :icon_emoji, :string, default: ':question:'
|
19
|
+
config_param :auto_channels_create, :bool, default: false
|
20
|
+
|
21
|
+
config_param :channel, :string
|
22
|
+
config_param :channel_keys, default: nil do |val|
|
22
23
|
val.split(',')
|
23
24
|
end
|
24
|
-
config_param :title,
|
25
|
-
config_param :title_keys,
|
25
|
+
config_param :title, :string, default: nil
|
26
|
+
config_param :title_keys, default: nil do |val|
|
26
27
|
val.split(',')
|
27
28
|
end
|
28
|
-
config_param :message,
|
29
|
-
config_param :message_keys,
|
29
|
+
config_param :message, :string, default: nil
|
30
|
+
config_param :message_keys, default: nil do |val|
|
30
31
|
val.split(',')
|
31
32
|
end
|
32
33
|
|
@@ -48,19 +49,24 @@ module Fluent
|
|
48
49
|
@channel = '#' + @channel unless @channel.start_with?('#')
|
49
50
|
|
50
51
|
if @webhook_url
|
52
|
+
if @webhook_url.empty?
|
53
|
+
raise Fluent::ConfigError.new("`webhook_url` is an empty string")
|
54
|
+
end
|
51
55
|
# following default values are for old version compatibility
|
52
56
|
@title ||= '%s'
|
53
57
|
@title_keys ||= %w[tag]
|
54
58
|
@message ||= '[%s] %s'
|
55
59
|
@message_keys ||= %w[time message]
|
56
60
|
@slack = Fluent::SlackClient::IncomingWebhook.new(@webhook_url)
|
57
|
-
|
58
|
-
|
59
|
-
raise Fluent::ConfigError.new("`token` is
|
61
|
+
elsif @token
|
62
|
+
if @token.empty?
|
63
|
+
raise Fluent::ConfigError.new("`token` is an empty string")
|
60
64
|
end
|
61
65
|
@message ||= '%s'
|
62
66
|
@message_keys ||= %w[message]
|
63
67
|
@slack = Fluent::SlackClient::WebApi.new
|
68
|
+
else
|
69
|
+
raise Fluent::ConfigError.new("Either of `webhook_url` or `token` is required")
|
64
70
|
end
|
65
71
|
@slack.log = log
|
66
72
|
@slack.debug_dev = log.out if log.level <= Fluent::Log::LEVEL_TRACE
|
@@ -84,6 +90,8 @@ module Fluent
|
|
84
90
|
raise Fluent::ConfigError, "string specifier '%s' for `channel` and `channel_keys` specification mismatch"
|
85
91
|
end
|
86
92
|
end
|
93
|
+
|
94
|
+
@post_message_opts = @auto_channels_create ? {auto_channels_create: true} : {}
|
87
95
|
end
|
88
96
|
|
89
97
|
def format(tag, time, record)
|
@@ -93,7 +101,7 @@ module Fluent
|
|
93
101
|
def write(chunk)
|
94
102
|
begin
|
95
103
|
payloads = build_payloads(chunk)
|
96
|
-
payloads.each {|payload| @slack.post_message(payload) }
|
104
|
+
payloads.each {|payload| @slack.post_message(payload, @post_message_opts) }
|
97
105
|
rescue Net::OpenTimeout, Net::ReadTimeout => e
|
98
106
|
log.warn "out_slack:", :error => e.to_s, :error_class => e.class.to_s
|
99
107
|
raise e # let Fluentd retry
|
@@ -1,51 +1,19 @@
|
|
1
1
|
require 'uri'
|
2
2
|
require 'net/http'
|
3
|
+
require 'logger'
|
4
|
+
require_relative 'slack_client/error'
|
3
5
|
|
4
6
|
module Fluent
|
5
7
|
module SlackClient
|
6
|
-
|
7
|
-
|
8
|
-
# This slack client only supports posting message
|
8
|
+
# The base framework of slack client
|
9
9
|
class Base
|
10
10
|
attr_accessor :log, :debug_dev
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
def initialize(endpoint = nil)
|
15
|
-
# Configure Incoming Webhook endpoint instead of chat.postMessage API
|
16
|
-
@endpoint = URI.parse(endpoint) if endpoint
|
12
|
+
def initialize
|
13
|
+
@log = Logger.new('/dev/null')
|
17
14
|
end
|
18
15
|
|
19
|
-
def endpoint
|
20
|
-
@endpoint ||= URI.parse(DEFAULT_ENDPOINT)
|
21
|
-
end
|
22
|
-
|
23
|
-
# Sends a message to a channel.
|
24
|
-
#
|
25
|
-
# @option params [channel] :channel
|
26
|
-
# Channel to send message to. Can be a public channel, private group or IM channel. Can be an encoded ID, or a name.
|
27
|
-
# @option params [Object] :text
|
28
|
-
# Text of the message to send. See below for an explanation of formatting.
|
29
|
-
# @option params [Object] :username
|
30
|
-
# Name of bot.
|
31
|
-
# @option params [Object] :parse
|
32
|
-
# Change how messages are treated. See below.
|
33
|
-
# @option params [Object] :link_names
|
34
|
-
# Find and link channel names and usernames.
|
35
|
-
# @option params [Object] :attachments
|
36
|
-
# Structured message attachments.
|
37
|
-
# @option params [Object] :unfurl_links
|
38
|
-
# Pass true to enable unfurling of primarily text-based content.
|
39
|
-
# @option params [Object] :unfurl_media
|
40
|
-
# Pass false to disable unfurling of media content.
|
41
|
-
# @option params [Object] :icon_url
|
42
|
-
# URL to an image to use as the icon for this message
|
43
|
-
# @option params [Object] :icon_emoji
|
44
|
-
# emoji to use as the icon for this message. Overrides `icon_url`.
|
45
|
-
# @see https://api.slack.com/methods/chat.postMessage
|
46
|
-
# @see https://github.com/slackhq/slack-api-docs/blob/master/methods/chat.postMessage.md
|
47
|
-
# @see https://github.com/slackhq/slack-api-docs/blob/master/methods/chat.postMessage.json
|
48
|
-
def post_message(params = {})
|
16
|
+
def post(endpoint, params)
|
49
17
|
http = Net::HTTP.new(endpoint.host, endpoint.port)
|
50
18
|
http.use_ssl = (endpoint.scheme == 'https')
|
51
19
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
@@ -57,36 +25,100 @@ module Fluent
|
|
57
25
|
req['User-Agent'] = 'fluent-plugin-slack'
|
58
26
|
req.body = encode_body(params)
|
59
27
|
|
60
|
-
log.info { "out_slack: post #{params.dup.tap {|p| p[:token] = '[FILTERED]' if p[:token] }}" } if log
|
61
28
|
res = http.request(req)
|
62
|
-
response_check(res)
|
29
|
+
response_check(res, params)
|
63
30
|
end
|
64
31
|
|
32
|
+
private
|
33
|
+
|
65
34
|
def encode_body(params)
|
66
35
|
raise NotImplementedError
|
67
36
|
end
|
68
37
|
|
69
|
-
def response_check(res)
|
38
|
+
def response_check(res, params)
|
70
39
|
if res.code != "200"
|
71
|
-
raise Error
|
40
|
+
raise Error.new(res, params)
|
72
41
|
end
|
73
42
|
end
|
74
43
|
end
|
75
44
|
|
45
|
+
# Slack client for Incoming Webhook
|
76
46
|
class IncomingWebhook < Base
|
47
|
+
attr_accessor :endpoint
|
48
|
+
|
49
|
+
# @param [String] endpoint Configure Incoming Webhook endpoint
|
50
|
+
def initialize(endpoint)
|
51
|
+
super()
|
52
|
+
@endpoint = URI.parse(endpoint)
|
53
|
+
end
|
54
|
+
|
55
|
+
def post_message(params = {}, opts = {})
|
56
|
+
log.info { "out_slack: post_message #{params}" }
|
57
|
+
post(endpoint, params)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
77
62
|
def encode_body(params = {})
|
78
63
|
params.to_json
|
79
64
|
end
|
80
65
|
|
81
|
-
def response_check(res)
|
66
|
+
def response_check(res, params)
|
82
67
|
super
|
83
68
|
unless res.body == 'ok'
|
84
|
-
raise Error
|
69
|
+
raise Error.new(res, params)
|
85
70
|
end
|
86
71
|
end
|
87
72
|
end
|
88
73
|
|
74
|
+
# Slack client for Web API
|
89
75
|
class WebApi < Base
|
76
|
+
DEFAULT_ENDPOINT = "https://slack.com/api/".freeze
|
77
|
+
|
78
|
+
def post_message_endpoint
|
79
|
+
@post_message_endpoint ||= URI.join(DEFAULT_ENDPOINT, "chat.postMessage")
|
80
|
+
end
|
81
|
+
|
82
|
+
def channels_create_endpoint
|
83
|
+
@channels_create_endpoint ||= URI.join(DEFAULT_ENDPOINT, "channels.create")
|
84
|
+
end
|
85
|
+
|
86
|
+
# Sends a message to a channel.
|
87
|
+
#
|
88
|
+
# @see https://api.slack.com/methods/chat.postMessage
|
89
|
+
# @see https://github.com/slackhq/slack-api-docs/blob/master/methods/chat.postMessage.md
|
90
|
+
# @see https://github.com/slackhq/slack-api-docs/blob/master/methods/chat.postMessage.json
|
91
|
+
def post_message(params = {}, opts = {})
|
92
|
+
retries = 1
|
93
|
+
begin
|
94
|
+
log.info { "out_slack: post_message #{params.dup.tap {|p| p[:token] = '[FILTERED]' if p[:token] }}" }
|
95
|
+
post(post_message_endpoint, params)
|
96
|
+
rescue ChannelNotFoundError => e
|
97
|
+
if opts[:auto_channels_create]
|
98
|
+
log.warn "out_slack: channel \"#{params[:channel]}\" is not found. try to create the channel, and then retry to post the message."
|
99
|
+
channels_create({name: params[:channel], token: params[:token]})
|
100
|
+
retry if (retries -= 1) >= 0 # one time retry
|
101
|
+
else
|
102
|
+
raise e
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Creates a channel.
|
108
|
+
#
|
109
|
+
# NOTE: Bot user can not create a channel. Token must be issued by Normal User Account
|
110
|
+
# @see https://api.slack.com/bot-users
|
111
|
+
#
|
112
|
+
# @see https://api.slack.com/methods/channels.create
|
113
|
+
# @see https://github.com/slackhq/slack-api-docs/blob/master/methods/channels.create.md
|
114
|
+
# @see https://github.com/slackhq/slack-api-docs/blob/master/methods/channels.create.json
|
115
|
+
def channels_create(params = {}, opts = {})
|
116
|
+
log.info { "out_slack: channels_create #{params.dup.tap {|p| p[:token] = '[FILTERED]' if p[:token] }}" }
|
117
|
+
post(channels_create_endpoint, params)
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
90
122
|
def encode_body(params = {})
|
91
123
|
body = params.dup
|
92
124
|
if params[:attachments]
|
@@ -95,11 +127,17 @@ module Fluent
|
|
95
127
|
URI.encode_www_form(body)
|
96
128
|
end
|
97
129
|
|
98
|
-
def response_check(res)
|
130
|
+
def response_check(res, params)
|
99
131
|
super
|
100
|
-
|
101
|
-
|
102
|
-
|
132
|
+
res_params = JSON.parse(res.body)
|
133
|
+
return if res_params['ok']
|
134
|
+
case res_params['error']
|
135
|
+
when 'channel_not_found'
|
136
|
+
raise ChannelNotFoundError.new(res, params)
|
137
|
+
when 'name_taken'
|
138
|
+
raise NameTakenError.new(res, params)
|
139
|
+
else
|
140
|
+
raise Error.new(res, params)
|
103
141
|
end
|
104
142
|
end
|
105
143
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
module Fluent
|
4
|
+
module SlackClient
|
5
|
+
class Error < StandardError
|
6
|
+
attr_reader :res, :req_params
|
7
|
+
|
8
|
+
def initialize(res, req_params = {})
|
9
|
+
@res = res
|
10
|
+
@req_params = req_params.dup
|
11
|
+
end
|
12
|
+
|
13
|
+
def message
|
14
|
+
@req_params[:token] = '[FILTERED]' if @req_params[:token]
|
15
|
+
"res.code:#{@res.code}, res.body:#{@res.body}, req_params:#{@req_params}"
|
16
|
+
end
|
17
|
+
|
18
|
+
alias :to_s :message
|
19
|
+
end
|
20
|
+
|
21
|
+
class ChannelNotFoundError < Error; end
|
22
|
+
class NameTakenError < Error; end
|
23
|
+
end
|
24
|
+
end
|
data/test.sh
ADDED
@@ -83,6 +83,21 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
83
83
|
assert_raise(Fluent::ConfigError) do
|
84
84
|
create_driver(CONFIG + %[channel %s %s\nchannel_keys foo])
|
85
85
|
end
|
86
|
+
|
87
|
+
# Either of webhook_url or token is required
|
88
|
+
assert_raise(Fluent::ConfigError) do
|
89
|
+
create_driver(%[channel foo])
|
90
|
+
end
|
91
|
+
|
92
|
+
# webhook_url is an empty string
|
93
|
+
assert_raise(Fluent::ConfigError) do
|
94
|
+
create_driver(%[channel foo\nwebhook_url])
|
95
|
+
end
|
96
|
+
|
97
|
+
# token is an empty string
|
98
|
+
assert_raise(Fluent::ConfigError) do
|
99
|
+
create_driver(%[channel foo\ntoken])
|
100
|
+
end
|
86
101
|
end
|
87
102
|
|
88
103
|
def test_timezone_configure
|
@@ -129,7 +144,7 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
129
144
|
])
|
130
145
|
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
131
146
|
d.tag = 'test'
|
132
|
-
mock(d.instance.slack).post_message(
|
147
|
+
mock(d.instance.slack).post_message({
|
133
148
|
channel: '#channel',
|
134
149
|
username: 'fluentd',
|
135
150
|
icon_emoji: ':question:',
|
@@ -141,7 +156,7 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
141
156
|
value: "[07:00:00] sowawa1\n[07:00:00] sowawa2\n",
|
142
157
|
}],
|
143
158
|
}]
|
144
|
-
)
|
159
|
+
}, {})
|
145
160
|
with_timezone('Asia/Tokyo') do
|
146
161
|
d.emit({message: 'sowawa1'}, time)
|
147
162
|
d.emit({message: 'sowawa2'}, time)
|
@@ -156,7 +171,7 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
156
171
|
])
|
157
172
|
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
158
173
|
d.tag = 'test'
|
159
|
-
mock(d.instance.slack).post_message(
|
174
|
+
mock(d.instance.slack).post_message({
|
160
175
|
token: 'XX-XX-XX',
|
161
176
|
channel: '#channel',
|
162
177
|
username: 'fluentd',
|
@@ -166,7 +181,7 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
166
181
|
fallback: "sowawa1\nsowawa2\n",
|
167
182
|
text: "sowawa1\nsowawa2\n",
|
168
183
|
}]
|
169
|
-
)
|
184
|
+
}, {})
|
170
185
|
with_timezone('Asia/Tokyo') do
|
171
186
|
d.emit({message: 'sowawa1'}, time)
|
172
187
|
d.emit({message: 'sowawa2'}, time)
|
@@ -179,7 +194,7 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
179
194
|
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
180
195
|
d.tag = 'test'
|
181
196
|
# attachments field should be changed to show the title
|
182
|
-
mock(d.instance.slack).post_message(
|
197
|
+
mock(d.instance.slack).post_message({
|
183
198
|
token: 'XXX-XXX-XXX',
|
184
199
|
channel: '#channel',
|
185
200
|
username: 'fluentd',
|
@@ -194,7 +209,7 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
194
209
|
}
|
195
210
|
]
|
196
211
|
}]
|
197
|
-
)
|
212
|
+
}, {})
|
198
213
|
with_timezone('Asia/Tokyo') do
|
199
214
|
d.emit({message: 'sowawa1'}, time)
|
200
215
|
d.emit({message: 'sowawa2'}, time)
|
@@ -206,7 +221,7 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
206
221
|
d = create_driver(CONFIG + %[message %s %s\nmessage_keys tag,message])
|
207
222
|
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
208
223
|
d.tag = 'test'
|
209
|
-
mock(d.instance.slack).post_message(
|
224
|
+
mock(d.instance.slack).post_message({
|
210
225
|
token: 'XXX-XXX-XXX',
|
211
226
|
channel: '#channel',
|
212
227
|
username: 'fluentd',
|
@@ -216,7 +231,7 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
216
231
|
fallback: "test sowawa1\ntest sowawa2\n",
|
217
232
|
text: "test sowawa1\ntest sowawa2\n",
|
218
233
|
}]
|
219
|
-
)
|
234
|
+
}, {})
|
220
235
|
with_timezone('Asia/Tokyo') do
|
221
236
|
d.emit({message: 'sowawa1'}, time)
|
222
237
|
d.emit({message: 'sowawa2'}, time)
|
@@ -228,7 +243,7 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
228
243
|
d = create_driver(CONFIG + %[channel %s\nchannel_keys channel])
|
229
244
|
time = Time.parse("2014-01-01 22:00:00 UTC").to_i
|
230
245
|
d.tag = 'test'
|
231
|
-
mock(d.instance.slack).post_message(
|
246
|
+
mock(d.instance.slack).post_message({
|
232
247
|
token: 'XXX-XXX-XXX',
|
233
248
|
channel: '#channel1',
|
234
249
|
username: 'fluentd',
|
@@ -238,8 +253,8 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
238
253
|
fallback: "sowawa1\n",
|
239
254
|
text: "sowawa1\n",
|
240
255
|
}]
|
241
|
-
)
|
242
|
-
mock(d.instance.slack).post_message(
|
256
|
+
}, {})
|
257
|
+
mock(d.instance.slack).post_message({
|
243
258
|
token: 'XXX-XXX-XXX',
|
244
259
|
channel: '#channel2',
|
245
260
|
username: 'fluentd',
|
@@ -249,7 +264,7 @@ class SlackOutputTest < Test::Unit::TestCase
|
|
249
264
|
fallback: "sowawa2\n",
|
250
265
|
text: "sowawa2\n",
|
251
266
|
}]
|
252
|
-
)
|
267
|
+
}, {})
|
253
268
|
with_timezone('Asia/Tokyo') do
|
254
269
|
d.emit({message: 'sowawa1', channel: 'channel1'}, time)
|
255
270
|
d.emit({message: 'sowawa2', channel: 'channel2'}, time)
|
@@ -23,7 +23,7 @@ if ENV['WEBHOOK_URL'] and ENV['TOKEN']
|
|
23
23
|
client == @api ? {token: ENV['TOKEN']} : {}
|
24
24
|
end
|
25
25
|
|
26
|
-
def
|
26
|
+
def test_post_message_text
|
27
27
|
[@incoming_webhook, @api].each do |slack|
|
28
28
|
assert_nothing_raised do
|
29
29
|
slack.post_message(
|
@@ -42,7 +42,7 @@ if ENV['WEBHOOK_URL'] and ENV['TOKEN']
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
def
|
45
|
+
def test_post_message_fields
|
46
46
|
[@incoming_webhook, @api].each do |slack|
|
47
47
|
assert_nothing_raised do
|
48
48
|
slack.post_message(
|
@@ -69,5 +69,40 @@ if ENV['WEBHOOK_URL'] and ENV['TOKEN']
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
end
|
72
|
+
|
73
|
+
# Hmm, I need to delete channels to test repeatedly,
|
74
|
+
# but slack does not provide channels.delete API
|
75
|
+
def test_channels_create
|
76
|
+
begin
|
77
|
+
@api.channels_create(
|
78
|
+
{
|
79
|
+
name: '#foo',
|
80
|
+
}.merge(token(@api))
|
81
|
+
)
|
82
|
+
rescue Fluent::SlackClient::NameTakenError
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Hmm, I need to delete channels to test repeatedly,
|
87
|
+
# but slack does not provide channels.delete API
|
88
|
+
def test_auto_channels_create
|
89
|
+
assert_nothing_raised do
|
90
|
+
@api.post_message(
|
91
|
+
{
|
92
|
+
channel: '#bar',
|
93
|
+
username: 'fluentd',
|
94
|
+
icon_emoji: ':question:',
|
95
|
+
attachments: [{
|
96
|
+
color: 'good',
|
97
|
+
fallback: "bar\n",
|
98
|
+
text: "bar\n",
|
99
|
+
}]
|
100
|
+
}.merge(token(@api)),
|
101
|
+
{
|
102
|
+
auto_channels_create: true,
|
103
|
+
}
|
104
|
+
)
|
105
|
+
end
|
106
|
+
end
|
72
107
|
end
|
73
108
|
end
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-slack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Keisuke SOGAWA
|
8
|
+
- Naotoshi Seo
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
12
|
+
date: 2015-03-27 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: fluentd
|
@@ -123,21 +124,27 @@ dependencies:
|
|
123
124
|
- !ruby/object:Gem::Version
|
124
125
|
version: '0'
|
125
126
|
description: fluent Slack plugin
|
126
|
-
email:
|
127
|
+
email:
|
128
|
+
- keisuke.sogawa@gmail.com
|
129
|
+
- sonots@gmail.com
|
127
130
|
executables: []
|
128
131
|
extensions: []
|
129
132
|
extra_rdoc_files: []
|
130
133
|
files:
|
131
134
|
- ".gitignore"
|
132
|
-
-
|
135
|
+
- ".travis.yml"
|
136
|
+
- CHANGELOG.md
|
133
137
|
- Gemfile
|
134
138
|
- README.md
|
135
139
|
- Rakefile
|
136
140
|
- VERSION
|
141
|
+
- example.conf
|
137
142
|
- fluent-plugin-slack.gemspec
|
138
143
|
- lib/fluent/plugin/out_buffered_slack.rb
|
139
144
|
- lib/fluent/plugin/out_slack.rb
|
140
145
|
- lib/fluent/plugin/slack_client.rb
|
146
|
+
- lib/fluent/plugin/slack_client/error.rb
|
147
|
+
- test.sh
|
141
148
|
- test/plugin/test_out_slack.rb
|
142
149
|
- test/plugin/test_slack_client.rb
|
143
150
|
- test/test_helper.rb
|
data/AUTHORS
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
Keisuke SOGAWA <keisuke.sogawa _at_ gmail.com>
|