logstash-output-monasca_log_api 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +2 -0
- data/LICENSE +11 -0
- data/README.md +167 -0
- data/lib/logstash/outputs/helper/url_helper.rb +28 -0
- data/lib/logstash/outputs/keystone/keystone_client.rb +69 -0
- data/lib/logstash/outputs/keystone/token.rb +31 -0
- data/lib/logstash/outputs/monasca/monasca_log_api_client.rb +78 -0
- data/lib/logstash/outputs/monasca_log_api.rb +134 -0
- data/logstash-output-monasca_log_api.gemspec +29 -0
- data/spec/outputs/helper/url_helper_spec.rb +34 -0
- data/spec/outputs/keystone/keystone_client_spec.rb +81 -0
- data/spec/outputs/keystone/token_spec.rb +38 -0
- data/spec/outputs/monasca/monasca_api_client_spec.rb +105 -0
- data/spec/outputs/monasca_api_spec.rb +131 -0
- data/spec/outputs/spec_helper.rb +32 -0
- metadata +164 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8a31e2b41940d7b7dec5eb88250d4bc27ce01e54
|
4
|
+
data.tar.gz: 71eecb218d00a0b32f762202d34d52f7bfc93a89
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 95ec1d08625205ed811036c5b7eb142d3970901a693dc5c8455a1e41a7a1c799e4eefdb602a91e73fdbedf1864514229a040361156431f01d088254f5eaa07ce
|
7
|
+
data.tar.gz: ab6ab077a31d5587cf8eae2063f1a05a6d7349d3ed179a912879119407947c6c94cba9827ba38a09f189f78065f043d60750ab48dc4a11d925fb45d801f2d28d
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
Copyright 2015 FUJITSU LIMITED
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
4
|
+
in compliance with the License. You may obtain a copy of the License at
|
5
|
+
|
6
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
|
8
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License
|
9
|
+
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
10
|
+
or implied. See the License for the specific language governing permissions and limitations under
|
11
|
+
the License.
|
data/README.md
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
# Logstash Output Monasca-Log-Api Plugin
|
2
|
+
|
3
|
+
## Build from source
|
4
|
+
|
5
|
+
### Requirements
|
6
|
+
|
7
|
+
* JRuby (I recommend to use Ruby Version Manager (RVM) How to install? -> https://rvm.io/rvm/install)
|
8
|
+
* JDK
|
9
|
+
* Git
|
10
|
+
* bundler
|
11
|
+
|
12
|
+
### How to install the requirements
|
13
|
+
|
14
|
+
#### Ubuntu 14.04
|
15
|
+
|
16
|
+
##### RVM
|
17
|
+
```bash
|
18
|
+
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
|
19
|
+
\curl -sSL https://get.rvm.io | bash
|
20
|
+
source /home/vagrant/.rvm/scripts/rvm
|
21
|
+
```
|
22
|
+
|
23
|
+
#### Git
|
24
|
+
```bash
|
25
|
+
sudo apt-get install git
|
26
|
+
```
|
27
|
+
|
28
|
+
#### JDK
|
29
|
+
```bash
|
30
|
+
sudo apt-get install default-jdk
|
31
|
+
```
|
32
|
+
|
33
|
+
#### JRuby
|
34
|
+
```bash
|
35
|
+
rvm install jruby
|
36
|
+
```
|
37
|
+
|
38
|
+
### Clone project
|
39
|
+
|
40
|
+
```bash
|
41
|
+
git clone https://github.com/FujitsuEnablingSoftwareTechnologyGmbH/logstash-output-monasca_api.git
|
42
|
+
```
|
43
|
+
|
44
|
+
### Use rvm jruby
|
45
|
+
```bash
|
46
|
+
rvm use jruby
|
47
|
+
```
|
48
|
+
|
49
|
+
### Install bundler
|
50
|
+
```bash
|
51
|
+
gem install bundler
|
52
|
+
```
|
53
|
+
|
54
|
+
### Fetch dependencies
|
55
|
+
```bash
|
56
|
+
bundle install
|
57
|
+
```
|
58
|
+
|
59
|
+
## Unit tests
|
60
|
+
|
61
|
+
### Run unit tests with:
|
62
|
+
```bash
|
63
|
+
bundle exec rspec
|
64
|
+
```
|
65
|
+
|
66
|
+
### Run specified test
|
67
|
+
```bash
|
68
|
+
bundle exec rspec spec/outputs/monasca/monasca_log_api_client_spec.rb
|
69
|
+
```
|
70
|
+
|
71
|
+
### Run coverage
|
72
|
+
```bash
|
73
|
+
JRUBY_OPTS="-Xcli.debug=true --debug" bundle exec rspec
|
74
|
+
```
|
75
|
+
|
76
|
+
Coverage report can be found in ./coverage
|
77
|
+
|
78
|
+
## Deploy Plugin to logstash
|
79
|
+
|
80
|
+
### Build Gemfile
|
81
|
+
First we need to create a Gemfile.
|
82
|
+
|
83
|
+
What is a Gemfile? Gems are packages for the Ruby programming language. A Gemfile defines all dependencies which are neccessary to build the product.
|
84
|
+
|
85
|
+
How to build a Gemfile? Run this:
|
86
|
+
```bash
|
87
|
+
gem build logstash-output-monasca_log_api.gemspec
|
88
|
+
```
|
89
|
+
|
90
|
+
### Deploy Gemfile to logstash
|
91
|
+
|
92
|
+
* [Download logstash](http://download.elastic.co/logstash/logstash/logstash-1.5.0.tar.gz) (>=1.5.0)
|
93
|
+
* Extract logstash and navigate into the folder
|
94
|
+
* Add this line to the Gemfile
|
95
|
+
|
96
|
+
```bash
|
97
|
+
gem "logstash-output-monasca_log_api", :path => "/vagrant_home/cloudmonitor/logstash-output-monasca_log_api"
|
98
|
+
```
|
99
|
+
|
100
|
+
* __logstash-output-monasca_log_api__ = name of the gem
|
101
|
+
* __/vagrant_home/cloudmonitor/logstash-output-monasca_log_api__ = Path to git workspace
|
102
|
+
|
103
|
+
Run this command from logstash folder to install the plugin
|
104
|
+
```bash
|
105
|
+
bin/plugin install --no-verify
|
106
|
+
```
|
107
|
+
|
108
|
+
Verify installed plugins:
|
109
|
+
With ``bin/plugin list`` you can check installed plugins. There should be ``logstash-output-monasca_log_api``.
|
110
|
+
|
111
|
+
## Start logstash output plugin
|
112
|
+
|
113
|
+
### Configuration
|
114
|
+
|
115
|
+
Save the configfile wherever you like. For example ~/logstash.conf
|
116
|
+
|
117
|
+
| name | description | required | example |
|
118
|
+
| - | - | - | - |
|
119
|
+
| monasca_log_api | monasca log api url | yes | http://192.168.10.4:8080 |
|
120
|
+
| keystone_api | keystone api url | yes | http://192.168.10.5:5000 |
|
121
|
+
| project_name | User-credentials: keystone project name | yes | mini-mon |
|
122
|
+
| username | User-credentials: keystone username | yes | admin-agent |
|
123
|
+
| password | User-credentials: keystone user password | yes | password |
|
124
|
+
| domain_id | User-credentials: keystone user domain-id | yes | default |
|
125
|
+
| dimensions | Dictionary of key-value pairs to describe logs | no | hostname: monasca, ip: 192.168.10.4 |
|
126
|
+
| application_type_key | Application name | no | monasca |
|
127
|
+
|
128
|
+
#### Example file
|
129
|
+
```bash
|
130
|
+
input {
|
131
|
+
stdin { }
|
132
|
+
}
|
133
|
+
output {
|
134
|
+
monasca_log_api {
|
135
|
+
monasca_log_api => "http://192.168.10.4:8080"
|
136
|
+
keystone_api => "http://192.168.10.5:5000"
|
137
|
+
project_name => "mini-mon"
|
138
|
+
username => "admin-agent"
|
139
|
+
password => "password"
|
140
|
+
domain_id => "default"
|
141
|
+
dimensions => "hostname: elkstack, ip: 192.168.10.4"
|
142
|
+
application_type_key => "monasca"
|
143
|
+
}
|
144
|
+
}
|
145
|
+
```
|
146
|
+
|
147
|
+
Run
|
148
|
+
```bash
|
149
|
+
bin/logstash -f ~/logstash.conf
|
150
|
+
```
|
151
|
+
|
152
|
+
Run in debug mode
|
153
|
+
```bash
|
154
|
+
bin/logstash -f ~/logstash.conf --debug
|
155
|
+
```
|
156
|
+
|
157
|
+
Specify log output file
|
158
|
+
```bash
|
159
|
+
bin/logstash -f ~/logstash.conf -l /var/log/monasca/log/agent/test-log-agent.log
|
160
|
+
```
|
161
|
+
### Logstash Input plugins
|
162
|
+
https://www.elastic.co/guide/en/logstash/current/input-plugins.html
|
163
|
+
|
164
|
+
## Open tasks
|
165
|
+
* Language translations (Replace hardcoded String messages with a configuration/language file)
|
166
|
+
* Exception handling (monasca-api requests)
|
167
|
+
* Contribute to logstash http://www.elastic.co/guide/en/logstash/master/_how_to_write_a_logstash_output_plugin.html#_contributing_your_source_code_to_ulink_url_https_github_com_logstash_plugins_logstash_plugins_ulink_4
|
@@ -0,0 +1,28 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2015 FUJITSU LIMITED
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
5
|
+
in compliance with the License. You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License
|
10
|
+
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
11
|
+
or implied. See the License for the specific language governing permissions and limitations under
|
12
|
+
the License.
|
13
|
+
=end
|
14
|
+
|
15
|
+
# encoding: utf-8
|
16
|
+
|
17
|
+
require 'uri'
|
18
|
+
|
19
|
+
module LogStash::Outputs
|
20
|
+
module Helper
|
21
|
+
class UrlHelper
|
22
|
+
def self.generate_url(host, path)
|
23
|
+
uri = URI.parse(host)
|
24
|
+
URI::HTTP.new(uri.scheme, nil, uri.host, uri.port, nil, path, nil, nil, nil)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2015 FUJITSU LIMITED
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
5
|
+
in compliance with the License. You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License
|
10
|
+
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
11
|
+
or implied. See the License for the specific language governing permissions and limitations under
|
12
|
+
the License.
|
13
|
+
=end
|
14
|
+
|
15
|
+
# encoding: utf-8
|
16
|
+
|
17
|
+
require 'logstash/environment'
|
18
|
+
require 'logger'
|
19
|
+
|
20
|
+
require_relative '../helper/url_helper'
|
21
|
+
require_relative './token'
|
22
|
+
|
23
|
+
# This class connects to keystone and authenticates an user.
|
24
|
+
# If successful authenticated, the class returns a token object
|
25
|
+
module LogStash::Outputs
|
26
|
+
module Keystone
|
27
|
+
class KeystoneClient
|
28
|
+
|
29
|
+
@client = nil
|
30
|
+
|
31
|
+
def initialize(host)
|
32
|
+
@logger = Cabin::Channel.get(LogStash)
|
33
|
+
@client = get_client(host, '/v3/auth/tokens')
|
34
|
+
end
|
35
|
+
|
36
|
+
def authenticate(domain_id, username, password, project_name)
|
37
|
+
auth_hash = generate_hash(domain_id, username, password, project_name)
|
38
|
+
response = request(auth_hash)
|
39
|
+
handle_response(response)
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def request(auth_hash)
|
45
|
+
@client.post(auth_hash, :content_type => 'application/json', :accept => 'application/json')
|
46
|
+
end
|
47
|
+
|
48
|
+
def get_client(host, path)
|
49
|
+
RestClient::Resource.new(LogStash::Outputs::Helper::UrlHelper.generate_url(host, path).to_s)
|
50
|
+
end
|
51
|
+
|
52
|
+
def generate_hash(domain_id, username, password, project_name)
|
53
|
+
"{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"domain\":{\"id\":\"#{domain_id}\"},\"name\":\"#{username}\",\"password\":\"#{password}\"}}},\"scope\":{\"project\":{\"domain\":{\"id\":\"#{domain_id}\"},\"name\":\"#{project_name}\"}}}}"
|
54
|
+
end
|
55
|
+
|
56
|
+
def handle_response(response)
|
57
|
+
case response.code
|
58
|
+
when 201
|
59
|
+
expires_at = DateTime.parse(JSON.parse(response.body)["token"]["expires_at"])
|
60
|
+
@logger.debug("Authentication succeed: code=#{response.code}, auth-token=#{response.headers[:x_subject_token]}, expires_at=#{expires_at.to_time}")
|
61
|
+
Token.new(response.headers[:x_subject_token], expires_at)
|
62
|
+
else
|
63
|
+
@logger.info("Authentication failed. Response=#{response}")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2015 FUJITSU LIMITED
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
5
|
+
in compliance with the License. You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License
|
10
|
+
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
11
|
+
or implied. See the License for the specific language governing permissions and limitations under
|
12
|
+
the License.
|
13
|
+
=end
|
14
|
+
|
15
|
+
# encoding: utf-8
|
16
|
+
|
17
|
+
module LogStash::Outputs
|
18
|
+
module Keystone
|
19
|
+
class Token
|
20
|
+
attr_accessor :id, :expire_at
|
21
|
+
def initialize id, expire_at
|
22
|
+
@id = id
|
23
|
+
@expire_at = expire_at
|
24
|
+
end
|
25
|
+
|
26
|
+
def ==(another_token)
|
27
|
+
self.id == another_token.id && self.expire_at == another_token.expire_at
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2015 FUJITSU LIMITED
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
5
|
+
in compliance with the License. You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License
|
10
|
+
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
11
|
+
or implied. See the License for the specific language governing permissions and limitations under
|
12
|
+
the License.
|
13
|
+
=end
|
14
|
+
|
15
|
+
# encoding: utf-8
|
16
|
+
|
17
|
+
require 'rest-client'
|
18
|
+
require 'logger'
|
19
|
+
|
20
|
+
# relative requirements
|
21
|
+
require_relative '../helper/url_helper'
|
22
|
+
|
23
|
+
# This class creates a connection to monasca-api
|
24
|
+
module LogStash::Outputs
|
25
|
+
module Monasca
|
26
|
+
class MonascaLogApiClient
|
27
|
+
|
28
|
+
SUPPORTED_API_VERSION = %w(2.0)
|
29
|
+
|
30
|
+
def initialize(host, version)
|
31
|
+
@logger = Cabin::Channel.get(LogStash)
|
32
|
+
@rest_client_url = LogStash::Outputs::Helper::UrlHelper.generate_url(host, '/' + check_version(version)).to_s
|
33
|
+
@rest_client = RestClient::Resource.new(@rest_client_url)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Send log events to monasca-api, requires token
|
37
|
+
def send_event(event, data, token, dimensions, application_type=nil)
|
38
|
+
begin
|
39
|
+
request(event, data, token, dimensions, application_type)
|
40
|
+
@logger.debug("Successfully send event=#{event}, with token=#{token} and dimensions=#{dimensions} to monasca-api")
|
41
|
+
rescue => e
|
42
|
+
@logger.warn('Sending event to monasca-log-api threw exception', :exceptionew => e)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def request(event, data, token, dimensions, application_type)
|
49
|
+
post_headers = {
|
50
|
+
:x_auth_token => token,
|
51
|
+
:content_type => 'application/json',
|
52
|
+
}
|
53
|
+
if dimensions
|
54
|
+
post_headers[:x_dimensions] = dimensions
|
55
|
+
end
|
56
|
+
|
57
|
+
if application_type
|
58
|
+
post_headers[:x_application_type] = application_type
|
59
|
+
end
|
60
|
+
|
61
|
+
@logger.debug('Sending data to ', :url => @rest_client_url)
|
62
|
+
@rest_client['log']['single'].post(data, post_headers)
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def check_version(version)
|
67
|
+
tmp_version = version.sub('v','')
|
68
|
+
|
69
|
+
unless SUPPORTED_API_VERSION.include? tmp_version
|
70
|
+
raise "#{tmp_version} is not supported, supported versions are #{SUPPORTED_API_VERSION}"
|
71
|
+
end
|
72
|
+
|
73
|
+
version
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2015 FUJITSU LIMITED
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
5
|
+
in compliance with the License. You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License
|
10
|
+
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
11
|
+
or implied. See the License for the specific language governing permissions and limitations under
|
12
|
+
the License.
|
13
|
+
=end
|
14
|
+
|
15
|
+
# encoding: utf-8
|
16
|
+
|
17
|
+
require 'logstash/outputs/base'
|
18
|
+
require 'logstash/namespace'
|
19
|
+
require 'vine'
|
20
|
+
|
21
|
+
# relative requirements
|
22
|
+
require_relative 'monasca/monasca_log_api_client'
|
23
|
+
require_relative 'keystone/keystone_client'
|
24
|
+
|
25
|
+
# This Logstash Output plugin, sends events to monasca-api.
|
26
|
+
# It authenticates against keystone and gets a token.
|
27
|
+
# The token is used to authenticate against the monasca-api and send log events.
|
28
|
+
class LogStash::Outputs::MonascaLogApi < LogStash::Outputs::Base
|
29
|
+
config_name 'monasca_log_api'
|
30
|
+
|
31
|
+
# monasca-api host and port configuration
|
32
|
+
config :monasca_log_api, :validate => :string, :required => true
|
33
|
+
config :monasca_log_api_version, :validate => :string, :required => false, :default => "v2.0"
|
34
|
+
|
35
|
+
# keystone host and port configuration
|
36
|
+
config :keystone_api, :validate => :string, :required => true
|
37
|
+
# keystone user configuration
|
38
|
+
config :project_name, :validate => :string, :required => true
|
39
|
+
config :username, :validate => :string, :required => true
|
40
|
+
config :password, :validate => :string, :required => true
|
41
|
+
config :domain_id, :validate => :string, :required => true
|
42
|
+
|
43
|
+
config :dimensions, :validate => :string, :default => nil
|
44
|
+
config :application_type_key, :validate => :string, :default => 'type'
|
45
|
+
|
46
|
+
attr_accessor :token
|
47
|
+
|
48
|
+
default :codec, 'json'
|
49
|
+
|
50
|
+
public
|
51
|
+
def register
|
52
|
+
@keystone_client = LogStash::Outputs::Keystone::KeystoneClient.new keystone_api
|
53
|
+
@monasca_log_api_client = LogStash::Outputs::Monasca::MonascaLogApiClient.new monasca_log_api, monasca_log_api_version
|
54
|
+
@token = get_token
|
55
|
+
|
56
|
+
@logger.info('Registering keystone user', :username => @username, :project_name => @project_name)
|
57
|
+
|
58
|
+
@codec.on_event do |event, data|
|
59
|
+
check_token
|
60
|
+
send_event(event, data, dimensions)
|
61
|
+
end
|
62
|
+
|
63
|
+
end # def register
|
64
|
+
|
65
|
+
def receive(event)
|
66
|
+
return unless output?(event)
|
67
|
+
if event == LogStash::SHUTDOWN
|
68
|
+
finished
|
69
|
+
return
|
70
|
+
end
|
71
|
+
@codec.encode(event)
|
72
|
+
end # def receive
|
73
|
+
|
74
|
+
def finished
|
75
|
+
if @shutdown_queue
|
76
|
+
@logger.info('Sending shutdown event to agent queue', :plugin => self.class.config_name)
|
77
|
+
@shutdown_queue << self
|
78
|
+
end
|
79
|
+
if @plugin_state != :finished
|
80
|
+
@logger.info('Plugin is finished', :plugin => self.class.config_name)
|
81
|
+
@plugin_state = :finished
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def shutdown(queue)
|
86
|
+
teardown
|
87
|
+
@logger.info('Received shutdown signal', :plugin => self.class.config_name)
|
88
|
+
|
89
|
+
@shutdown_queue = queue
|
90
|
+
if @plugin_state == :finished
|
91
|
+
finished
|
92
|
+
else
|
93
|
+
@plugin_state = :terminating
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
def check_token
|
99
|
+
now = DateTime.now + Rational(1, 1440)
|
100
|
+
if now >= @token.expire_at
|
101
|
+
@token = get_token
|
102
|
+
@logger.info('Token expired. New token requested')
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def send_event(event, data, dimensions)
|
107
|
+
@monasca_log_api_client.send_event(event, data, @token.id, dimensions, get_application_type(event)) if event and @token.id and data
|
108
|
+
end
|
109
|
+
|
110
|
+
def get_application_type(event)
|
111
|
+
|
112
|
+
# support for nested.keys.with.lists.0
|
113
|
+
if @application_type_key.include? '.'
|
114
|
+
split_key = @application_type_key.split('.')
|
115
|
+
event_value = event[split_key[0]]
|
116
|
+
access_key = split_key.slice(1..-1).join('.')
|
117
|
+
|
118
|
+
app_type = event_value.access(access_key)
|
119
|
+
|
120
|
+
else
|
121
|
+
app_type = event[@application_type_key]
|
122
|
+
end
|
123
|
+
|
124
|
+
@logger.debug(
|
125
|
+
'Retrieved application_type', :application_type => app_type, :application_type_key => @application_type_key
|
126
|
+
)
|
127
|
+
app_type
|
128
|
+
end
|
129
|
+
|
130
|
+
def get_token
|
131
|
+
@keystone_client.authenticate(domain_id, username, password, project_name)
|
132
|
+
end
|
133
|
+
|
134
|
+
end # class LogStash::Outputs::Example
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'logstash-output-monasca_log_api'
|
3
|
+
s.version = '0.3.3'
|
4
|
+
s.licenses = ['Apache License 2.0']
|
5
|
+
s.summary = 'This gem is a logstash output plugin to connect via http to monasca-log-api.'
|
6
|
+
s.description = 'This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program'
|
7
|
+
s.authors = ['Fujitsu Enabling Software Technology GmbH']
|
8
|
+
s.email = 'kamil.choroba@est.fujitsu.com,tomasz.trebski@ts.fujitsu.com'
|
9
|
+
s.require_paths = ['lib']
|
10
|
+
s.homepage = 'https://github.com/FujitsuEnablingSoftwareTechnologyGmbH/logstash-output-monasca_api'
|
11
|
+
|
12
|
+
# Files
|
13
|
+
s.files = Dir["lib/**/*", "spec/**/*", "*.gemspec", "*.md", "Gemfile", "LICENSE"]
|
14
|
+
|
15
|
+
# Tests
|
16
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
17
|
+
|
18
|
+
# Special flag to let us know this is actually a logstash plugin
|
19
|
+
s.metadata = { 'logstash_plugin' => 'true', 'logstash_group' => 'output' }
|
20
|
+
|
21
|
+
# Gem dependencies
|
22
|
+
s.add_runtime_dependency 'logstash-core', '~> 1.5'
|
23
|
+
s.add_runtime_dependency 'logstash-codec-plain', '~> 0.1.6'
|
24
|
+
s.add_runtime_dependency 'logstash-codec-json', '~> 0.1.6'
|
25
|
+
s.add_runtime_dependency 'rest-client', '~> 1.8'
|
26
|
+
s.add_runtime_dependency 'vine', '~> 0.2'
|
27
|
+
s.add_development_dependency 'logstash-devutils', '~> 0.0.14'
|
28
|
+
s.add_development_dependency 'simplecov', '~> 0.10'
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2015 FUJITSU LIMITED
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
5
|
+
in compliance with the License. You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License
|
10
|
+
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
11
|
+
or implied. See the License for the specific language governing permissions and limitations under
|
12
|
+
the License.
|
13
|
+
=end
|
14
|
+
|
15
|
+
# encoding: utf-8
|
16
|
+
|
17
|
+
require_relative '../spec_helper'
|
18
|
+
|
19
|
+
describe LogStash::Outputs::Helper::UrlHelper do
|
20
|
+
|
21
|
+
describe ".generate_url" do
|
22
|
+
it "generates a URI::HTTP object" do
|
23
|
+
expect(LogStash::Outputs::Helper::UrlHelper.generate_url('http://192.168.10.5:8080', '/v2.0')).to be_a URI::HTTP
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should match a http url" do
|
27
|
+
expect(LogStash::Outputs::Helper::UrlHelper.generate_url('http://192.168.10.5:8080', '/v2.0').to_s).to eq('http://192.168.10.5:8080/v2.0')
|
28
|
+
expect(LogStash::Outputs::Helper::UrlHelper.generate_url('http://est.fujitsu:40', nil).to_s).to eq('http://est.fujitsu:40')
|
29
|
+
expect(LogStash::Outputs::Helper::UrlHelper.generate_url('http://est.fujitsu:80', nil).to_s).to eq('http://est.fujitsu')
|
30
|
+
expect(LogStash::Outputs::Helper::UrlHelper.generate_url('https://192.168.10.5:8080', '/v2.0').to_s).to eq('https://192.168.10.5:8080/v2.0')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2015 FUJITSU LIMITED
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
5
|
+
in compliance with the License. You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License
|
10
|
+
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
11
|
+
or implied. See the License for the specific language governing permissions and limitations under
|
12
|
+
the License.
|
13
|
+
=end
|
14
|
+
|
15
|
+
# encoding: utf-8
|
16
|
+
|
17
|
+
require_relative '../spec_helper'
|
18
|
+
|
19
|
+
describe LogStash::Outputs::Keystone::KeystoneClient do
|
20
|
+
|
21
|
+
let (:auth_hash) { "{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"domain\":{\"id\":\"1051bd27b9394120b26d8b08847325c0\"},\"name\":\"csi-operator\",\"password\":\"password\"}}},\"scope\":{\"project\":{\"domain\":{\"id\":\"1051bd27b9394120b26d8b08847325c0\"},\"name\":\"csi\"}}}}" }
|
22
|
+
|
23
|
+
let (:ok_response) { stub_response(201, {:x_subject_token => "f8cdafb7dce94444ad781a53ddaff693"}, "{\"token\":{\"methods\":[\"password\"],\"roles\":[{\"id\":\"9fe2ff9ee4384b1894a90878d3e92bab\",\"name\":\"_member_\"},{\"id\":\"4e9ef1ffe73446c6b02f8fce0585c307\",\"name\":\"monasca-user\"}],\"expires_at\":\"2015-05-26T08:55:36.774122Z\",\"project\":{\"domain\":{\"id\":\"default\",\"name\":\"Default\"},\"id\":\"1051bd27b9394120b26d8b08847325c0\",\"name\":\"mini-mon\"},\"user\":{\"domain\":{\"id\":\"default\",\"name\":\"Default\"},\"id\":\"06ecc9869b8e4846b2fce3e5759ba4af\",\"name\":\"mini-mon\"},\"audit_ids\":[\"ORap7R56S2S-p6tFVeMkpg\"],\"issued_at\":\"2015-05-26T07:55:36.774146Z\"}}") }
|
24
|
+
|
25
|
+
let (:failed_response) { stub_response(401, {:x_subject_token => "f8cdafb7dce94444ad781a53ddaff693"}, "{\"error\": {\"message\": \"Could not find project: f8cdafb7dce94444ad781a53ddaff693 (Disable debug mode to suppress these details.)\", \"code\": 401, \"title\": \"Unauthorized\"}}") }
|
26
|
+
|
27
|
+
context 'when initializing' do
|
28
|
+
it 'then it should register without exceptions' do
|
29
|
+
expect {LogStash::Outputs::Keystone::KeystoneClient.new('hostname:8080')}.to_not raise_error
|
30
|
+
end
|
31
|
+
|
32
|
+
it "returns a failure if arguments are missing" do
|
33
|
+
expect {LogStash::Outputs::Keystone::KeystoneClient.new}.to raise_exception(ArgumentError)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when authenticates' do
|
38
|
+
it 'then it should request to keystone' do
|
39
|
+
expect_any_instance_of(RestClient::Resource).to receive(:post)
|
40
|
+
.with(auth_hash, :content_type => 'application/json', :accept => 'application/json')
|
41
|
+
keystone_client = LogStash::Outputs::Keystone::KeystoneClient.new('hostname:8080')
|
42
|
+
allow(keystone_client).to receive(:handle_response).and_return(LogStash::Outputs::Keystone::Token.new('abc', DateTime.now + Rational(5, 1440)))
|
43
|
+
keystone_client.authenticate('1051bd27b9394120b26d8b08847325c0', 'csi-operator', 'password', 'csi')
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'then it should create a new token' do
|
47
|
+
keystone_client = LogStash::Outputs::Keystone::KeystoneClient.new('hostname:8080')
|
48
|
+
allow(keystone_client).to receive(:request).and_return(ok_response)
|
49
|
+
expected = LogStash::Outputs::Keystone::Token.new('f8cdafb7dce94444ad781a53ddaff693', DateTime.parse("2015-05-26T08:55:36.774122Z"))
|
50
|
+
actual = keystone_client.authenticate('1051bd27b9394120b26d8b08847325c0', 'csi-operator', 'password', 'csi')
|
51
|
+
expect(actual).to eq(expected)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'when authentication failed' do
|
56
|
+
it 'then it should not create a new token' do
|
57
|
+
expect_any_instance_of(Cabin::Channel).to receive(:info)
|
58
|
+
keystone_client = LogStash::Outputs::Keystone::KeystoneClient.new('hostname:8080')
|
59
|
+
allow(keystone_client).to receive(:request).and_return(failed_response)
|
60
|
+
actual = keystone_client.authenticate('1051bd27b9394120b26d8b08847325c0', 'csi-operator', 'password', 'csi')
|
61
|
+
expect(actual).to eq(nil)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'then it should log an information' do
|
65
|
+
expect_any_instance_of(Cabin::Channel).to receive(:info)
|
66
|
+
keystone_client = LogStash::Outputs::Keystone::KeystoneClient.new('hostname:8080')
|
67
|
+
allow(keystone_client).to receive(:request).and_return(failed_response)
|
68
|
+
keystone_client.authenticate('1051bd27b9394120b26d8b08847325c0', 'csi-operator', 'password', 'csi')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def stub_response(code, headers, body)
|
75
|
+
response = double
|
76
|
+
allow(response).to receive(:code) { code }
|
77
|
+
allow(response).to receive(:headers) { headers }
|
78
|
+
allow(response).to receive(:body) { body }
|
79
|
+
response
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2015 FUJITSU LIMITED
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
5
|
+
in compliance with the License. You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License
|
10
|
+
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
11
|
+
or implied. See the License for the specific language governing permissions and limitations under
|
12
|
+
the License.
|
13
|
+
=end
|
14
|
+
|
15
|
+
# encoding: utf-8
|
16
|
+
|
17
|
+
require_relative '../spec_helper'
|
18
|
+
|
19
|
+
describe LogStash::Outputs::Keystone::Token do
|
20
|
+
|
21
|
+
describe "#new" do
|
22
|
+
it "takes two parameters and returns a Token object" do
|
23
|
+
token = LogStash::Outputs::Keystone::Token.new('token-id', DateTime.now)
|
24
|
+
expect(token).to be_a(LogStash::Outputs::Keystone::Token)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#==" do
|
29
|
+
it "should equal to another token instance" do
|
30
|
+
token = LogStash::Outputs::Keystone::Token.new('token-id', DateTime.parse("2015-05-26T08:55:36.774122Z"))
|
31
|
+
second_token = LogStash::Outputs::Keystone::Token.new('token-id', DateTime.parse("2015-05-26T08:55:36.774122Z"))
|
32
|
+
third_token = LogStash::Outputs::Keystone::Token.new('token-id', DateTime.parse("2015-05-30T08:55:36.774122Z"))
|
33
|
+
|
34
|
+
expect(token).to eq(second_token)
|
35
|
+
expect(third_token).to_not eq(second_token)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2015 FUJITSU LIMITED
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
5
|
+
in compliance with the License. You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License
|
10
|
+
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
11
|
+
or implied. See the License for the specific language governing permissions and limitations under
|
12
|
+
the License.
|
13
|
+
=end
|
14
|
+
|
15
|
+
# encoding: utf-8
|
16
|
+
|
17
|
+
require_relative '../spec_helper'
|
18
|
+
|
19
|
+
describe LogStash::Outputs::Monasca::MonascaLogApiClient do
|
20
|
+
let (:version) { "v2.0" }
|
21
|
+
|
22
|
+
let (:auth_hash) { "{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":{\"user\":{\"domain\":{\"id\":\"1051bd27b9394120b26d8b08847325c0\"},\"name\":\"csi-operator\",\"password\":\"password\"}}},\"scope\":{\"project\":{\"domain\":{\"id\":\"1051bd27b9394120b26d8b08847325c0\"},\"name\":\"csi\"}}}}" }
|
23
|
+
|
24
|
+
let (:ok_response) { stub_response(201, {:x_subject_token => "f8cdafb7dce94444ad781a53ddaff693"}, "{\"token\":{\"methods\":[\"password\"],\"roles\":[{\"id\":\"9fe2ff9ee4384b1894a90878d3e92bab\",\"name\":\"_member_\"},{\"id\":\"4e9ef1ffe73446c6b02f8fce0585c307\",\"name\":\"monasca-user\"}],\"expires_at\":\"2015-05-26T08:55:36.774122Z\",\"project\":{\"domain\":{\"id\":\"default\",\"name\":\"Default\"},\"id\":\"1051bd27b9394120b26d8b08847325c0\",\"name\":\"mini-mon\"},\"user\":{\"domain\":{\"id\":\"default\",\"name\":\"Default\"},\"id\":\"06ecc9869b8e4846b2fce3e5759ba4af\",\"name\":\"mini-mon\"},\"audit_ids\":[\"ORap7R56S2S-p6tFVeMkpg\"],\"issued_at\":\"2015-05-26T07:55:36.774146Z\"}}") }
|
25
|
+
|
26
|
+
let (:failed_response) { stub_response(401, {:x_subject_token => "f8cdafb7dce94444ad781a53ddaff693"}, "{\"error\": {\"message\": \"Could not find project: f8cdafb7dce94444ad781a53ddaff693 (Disable debug mode to suppress these details.)\", \"code\": 401, \"title\": \"Unauthorized\"}}") }
|
27
|
+
|
28
|
+
let (:data) { LogStash::Event.new({'message' => '2015-08-13 08:36:59,316 INFO monasca_notification.main Received signal 17, beginning graceful shutdown.',
|
29
|
+
'@version' => '1',
|
30
|
+
'@timestamp' => '2015-08-13T08:37:00.287Z',
|
31
|
+
'type' => 'notification',
|
32
|
+
'service' => 'notification',
|
33
|
+
'host' => 'monasca',
|
34
|
+
'path' => '/var/log/monasca/notification/notification.log'}) }
|
35
|
+
|
36
|
+
let (:token) { LogStash::Outputs::Keystone::Token.new('abc', DateTime.now + Rational(5, 1440)) }
|
37
|
+
|
38
|
+
let (:dimensions) { { 'hostname' => 'monasca' } }
|
39
|
+
|
40
|
+
context 'when initializing' do
|
41
|
+
it 'then it should register without exceptions' do
|
42
|
+
expect {LogStash::Outputs::Monasca::MonascaLogApiClient.new('hostname:8080', version)}.to_not raise_error
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns a failure if arguments are missing" do
|
46
|
+
# noinspection RubyArgCount
|
47
|
+
expect {LogStash::Outputs::Monasca::MonascaLogApiClient.new}.to raise_exception(ArgumentError)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'when sending events' do
|
52
|
+
it 'with dimensions then it should request monasca' do
|
53
|
+
expect_any_instance_of(RestClient::Resource).to receive(:post)
|
54
|
+
.with(data, :x_auth_token => token, :content_type => 'application/json', :x_dimensions => dimensions)
|
55
|
+
monasca_log_api_client = LogStash::Outputs::Monasca::MonascaLogApiClient.new('hostname:8080', version)
|
56
|
+
monasca_log_api_client.send_event(nil, data, token, dimensions)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'without dimensions then it should request monasca' do
|
60
|
+
expect_any_instance_of(RestClient::Resource).to receive(:post)
|
61
|
+
.with(data, :x_auth_token => token, :content_type => 'application/json')
|
62
|
+
monasca_log_api_client = LogStash::Outputs::Monasca::MonascaLogApiClient.new('hostname:8080', version)
|
63
|
+
monasca_log_api_client.send_event(nil, data, token, nil)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'with application_type then it should request monasca with that value' do
|
67
|
+
app_type = 'someapp'
|
68
|
+
expect_any_instance_of(RestClient::Resource).to receive(:post)
|
69
|
+
.with(data, :x_auth_token => token, :content_type => 'application/json', :x_application_type => app_type)
|
70
|
+
monasca_log_api_client = LogStash::Outputs::Monasca::MonascaLogApiClient.new('hostname:8080', version)
|
71
|
+
monasca_log_api_client.send_event(nil, data, token, nil, app_type)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'when sending events failes' do
|
76
|
+
it 'then it should be rescued and a warn log printed' do
|
77
|
+
expect_any_instance_of(Cabin::Channel).to receive(:warn)
|
78
|
+
monasca_log_api_client = LogStash::Outputs::Monasca::MonascaLogApiClient.new('hostname:8080', version)
|
79
|
+
allow(monasca_log_api_client).to receive(:request).and_raise('an_error')
|
80
|
+
monasca_log_api_client.send_event(nil, data, token, dimensions)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'api version checking' do
|
85
|
+
|
86
|
+
let (:supported_version) { %w(v2.0) }
|
87
|
+
|
88
|
+
it 'should pass for correct version' do
|
89
|
+
supported_version.each { |ver|
|
90
|
+
expect {LogStash::Outputs::Monasca::MonascaLogApiClient.new('hostname:8080', ver)}.to_not raise_error
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should pass if version does not specify v' do
|
95
|
+
ver = '2.0'
|
96
|
+
expect {LogStash::Outputs::Monasca::MonascaLogApiClient.new('hostname:8080', ver)}.to_not raise_error
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should fail for unsupported version' do
|
100
|
+
ver = 'v4.0'
|
101
|
+
expect {LogStash::Outputs::Monasca::MonascaLogApiClient.new('hostname:8080', ver)}.to raise_exception
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2015 FUJITSU LIMITED
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
5
|
+
in compliance with the License. You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License
|
10
|
+
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
11
|
+
or implied. See the License for the specific language governing permissions and limitations under
|
12
|
+
the License.
|
13
|
+
=end
|
14
|
+
|
15
|
+
# encoding: utf-8
|
16
|
+
|
17
|
+
require_relative 'spec_helper'
|
18
|
+
|
19
|
+
describe 'outputs/monasca_log_api' do
|
20
|
+
|
21
|
+
let (:expected_application_type) { 'notification' }
|
22
|
+
|
23
|
+
let (:event) { LogStash::Event.new({'message' => '2015-08-13 08:36:59,316 INFO monasca_notification.main Received signal 17, beginning graceful shutdown.',
|
24
|
+
'@version' => '1',
|
25
|
+
'@timestamp' => '2015-08-13T08:37:00.287Z',
|
26
|
+
'type' => expected_application_type,
|
27
|
+
'service' => 'notification',
|
28
|
+
'host' => 'monasca',
|
29
|
+
'path' => '/var/log/monasca/notification/notification.log'}) }
|
30
|
+
|
31
|
+
let (:shutdown_event) { LogStash::SHUTDOWN }
|
32
|
+
|
33
|
+
let (:simple_config) { {'monasca_log_api' => 'http://192.168.10.4:8080',
|
34
|
+
'keystone_api' => 'http://192.168.10.5:5000',
|
35
|
+
'domain_id' => 'abadcf984cf7401e88579d393317b0d9',
|
36
|
+
'username' => 'username',
|
37
|
+
'password' => 'password',
|
38
|
+
'project_name' => 'project_name'} }
|
39
|
+
|
40
|
+
let (:token_id) { LogStash::Outputs::Keystone::Token.new('abc', DateTime.now + Rational(5, 1440)) }
|
41
|
+
|
42
|
+
let (:old_token_id) { LogStash::Outputs::Keystone::Token.new('def', DateTime.now - Rational(5, 1440)) }
|
43
|
+
|
44
|
+
context 'when initializing' do
|
45
|
+
it 'then it should register without exceptions' do
|
46
|
+
monasca_log_api = LogStash::Plugin.lookup('output', 'monasca_log_api').new(simple_config)
|
47
|
+
allow(monasca_log_api).to receive(:get_token).and_return(token_id)
|
48
|
+
expect {monasca_log_api.register}.to_not raise_error
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should set a default application_type_key to \"type\"" do
|
52
|
+
monasca_log_api = LogStash::Plugin.lookup('output', 'monasca_log_api').new(simple_config)
|
53
|
+
expect(monasca_log_api.instance_variable_get('@application_type_key')).to eq("type")
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should use passed variable from config as application_type_key' do
|
57
|
+
expected_key = 'mountain_dew'
|
58
|
+
simple_config_copy = simple_config.clone
|
59
|
+
simple_config_copy['application_type_key'] = expected_key
|
60
|
+
monasca_log_api = LogStash::Plugin.lookup('output', 'monasca_log_api').new(simple_config_copy)
|
61
|
+
|
62
|
+
expect(monasca_log_api.instance_variable_get('@application_type_key')).to eq(expected_key)
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'when receiving messages' do
|
68
|
+
it 'then it should be send to monasca-log-api' do
|
69
|
+
expect_any_instance_of(LogStash::Outputs::Monasca::MonascaLogApiClient).to receive(:send_event)
|
70
|
+
.with(event, event.to_hash.to_json, token_id.id, nil, expected_application_type)
|
71
|
+
monasca_log_api = LogStash::Outputs::MonascaLogApi.new(simple_config)
|
72
|
+
|
73
|
+
allow(monasca_log_api).to receive(:get_token).and_return(token_id)
|
74
|
+
allow(monasca_log_api).to receive(:get_application_type).and_call_original
|
75
|
+
|
76
|
+
monasca_log_api.register
|
77
|
+
monasca_log_api.receive(event)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'then it should check the token_id and renew it when its deprecated' do
|
81
|
+
expect_any_instance_of(LogStash::Outputs::Keystone::KeystoneClient).to receive(:authenticate)
|
82
|
+
.with(simple_config['domain_id'], simple_config['username'], simple_config['password'], simple_config['project_name'])
|
83
|
+
monasca_log_api = LogStash::Outputs::MonascaLogApi.new(simple_config)
|
84
|
+
allow(monasca_log_api).to receive(:get_token).and_return(old_token_id)
|
85
|
+
monasca_log_api.register
|
86
|
+
allow(monasca_log_api).to receive(:get_token).and_call_original
|
87
|
+
allow(monasca_log_api).to receive(:send_event)
|
88
|
+
monasca_log_api.receive(event)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'when given dictionary as type in received message' do
|
93
|
+
it 'should read application_type from it properly' do
|
94
|
+
type_dict = {
|
95
|
+
"application_type" => 'notification'
|
96
|
+
}
|
97
|
+
config = simple_config.merge({"application_type_key" => 'type.application_type'})
|
98
|
+
|
99
|
+
event = LogStash::Event.new({"message" => '2015-08-13 08:36:59,316 INFO monasca_notification.main Received signal 17, beginning graceful shutdown.',
|
100
|
+
"@version" => '1',
|
101
|
+
"@timestamp" => '2015-08-13T08:37:00.287Z',
|
102
|
+
"type" => type_dict,
|
103
|
+
"service" => 'notification',
|
104
|
+
"host" => 'monasca',
|
105
|
+
"path" => '/var/log/monasca/notification/notification.log',
|
106
|
+
})
|
107
|
+
expect_any_instance_of(LogStash::Outputs::Monasca::MonascaLogApiClient).to receive(:send_event)
|
108
|
+
.with(event, event.to_hash.to_json, token_id.id, nil, expected_application_type)
|
109
|
+
monasca_log_api = LogStash::Outputs::MonascaLogApi.new(config)
|
110
|
+
|
111
|
+
allow(monasca_log_api).to receive(:get_token).and_return(token_id)
|
112
|
+
allow(monasca_log_api).to receive(:get_application_type).and_call_original
|
113
|
+
|
114
|
+
monasca_log_api.register
|
115
|
+
monasca_log_api.receive(event)
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'when receiving SHUTDOWN message' do
|
121
|
+
it 'then it should be send to monasca-log-api' do
|
122
|
+
expect_any_instance_of(LogStash::Outputs::Monasca::MonascaLogApiClient).to_not receive(:send_event)
|
123
|
+
.with(shutdown_event, nil, token_id.id, nil)
|
124
|
+
monasca_log_api = LogStash::Outputs::MonascaLogApi.new(simple_config)
|
125
|
+
allow(monasca_log_api).to receive(:get_token).and_return(token_id)
|
126
|
+
monasca_log_api.register
|
127
|
+
monasca_log_api.receive(shutdown_event)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright 2015 FUJITSU LIMITED
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
5
|
+
in compliance with the License. You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License
|
10
|
+
is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
11
|
+
or implied. See the License for the specific language governing permissions and limitations under
|
12
|
+
the License.
|
13
|
+
=end
|
14
|
+
|
15
|
+
# encoding: utf-8
|
16
|
+
|
17
|
+
require 'simplecov'
|
18
|
+
SimpleCov.start do
|
19
|
+
add_filter '/test/'
|
20
|
+
add_filter '/config/'
|
21
|
+
add_filter '/vendor/'
|
22
|
+
add_filter '/spec/'
|
23
|
+
end
|
24
|
+
|
25
|
+
require_relative '../../lib/logstash/outputs/monasca_log_api'
|
26
|
+
require_relative '../../lib/logstash/outputs/keystone/keystone_client'
|
27
|
+
require_relative '../../lib/logstash/outputs/keystone/token'
|
28
|
+
require_relative '../../lib/logstash/outputs/monasca/monasca_log_api_client'
|
29
|
+
require_relative '../../lib/logstash/outputs/helper/url_helper'
|
30
|
+
|
31
|
+
require 'yaml'
|
32
|
+
require 'rest-client'
|
metadata
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: logstash-output-monasca_log_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Fujitsu Enabling Software Technology GmbH
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-12-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: logstash-core
|
15
|
+
version_requirements: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
requirement: !ruby/object:Gem::Requirement
|
21
|
+
requirements:
|
22
|
+
- - ~>
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: '1.5'
|
25
|
+
prerelease: false
|
26
|
+
type: :runtime
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: logstash-codec-plain
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.1.6
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ~>
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 0.1.6
|
39
|
+
prerelease: false
|
40
|
+
type: :runtime
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: logstash-codec-json
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.1.6
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ~>
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 0.1.6
|
53
|
+
prerelease: false
|
54
|
+
type: :runtime
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rest-client
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.8'
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ~>
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '1.8'
|
67
|
+
prerelease: false
|
68
|
+
type: :runtime
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: vine
|
71
|
+
version_requirements: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.2'
|
76
|
+
requirement: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ~>
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0.2'
|
81
|
+
prerelease: false
|
82
|
+
type: :runtime
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: logstash-devutils
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.0.14
|
90
|
+
requirement: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ~>
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: 0.0.14
|
95
|
+
prerelease: false
|
96
|
+
type: :development
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
version_requirements: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ~>
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.10'
|
104
|
+
requirement: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ~>
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0.10'
|
109
|
+
prerelease: false
|
110
|
+
type: :development
|
111
|
+
description: This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program
|
112
|
+
email: kamil.choroba@est.fujitsu.com,tomasz.trebski@ts.fujitsu.com
|
113
|
+
executables: []
|
114
|
+
extensions: []
|
115
|
+
extra_rdoc_files: []
|
116
|
+
files:
|
117
|
+
- Gemfile
|
118
|
+
- LICENSE
|
119
|
+
- README.md
|
120
|
+
- lib/logstash/outputs/helper/url_helper.rb
|
121
|
+
- lib/logstash/outputs/keystone/keystone_client.rb
|
122
|
+
- lib/logstash/outputs/keystone/token.rb
|
123
|
+
- lib/logstash/outputs/monasca/monasca_log_api_client.rb
|
124
|
+
- lib/logstash/outputs/monasca_log_api.rb
|
125
|
+
- logstash-output-monasca_log_api.gemspec
|
126
|
+
- spec/outputs/helper/url_helper_spec.rb
|
127
|
+
- spec/outputs/keystone/keystone_client_spec.rb
|
128
|
+
- spec/outputs/keystone/token_spec.rb
|
129
|
+
- spec/outputs/monasca/monasca_api_client_spec.rb
|
130
|
+
- spec/outputs/monasca_api_spec.rb
|
131
|
+
- spec/outputs/spec_helper.rb
|
132
|
+
homepage: https://github.com/FujitsuEnablingSoftwareTechnologyGmbH/logstash-output-monasca_api
|
133
|
+
licenses:
|
134
|
+
- Apache License 2.0
|
135
|
+
metadata:
|
136
|
+
logstash_plugin: 'true'
|
137
|
+
logstash_group: output
|
138
|
+
post_install_message:
|
139
|
+
rdoc_options: []
|
140
|
+
require_paths:
|
141
|
+
- lib
|
142
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - '>='
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - '>='
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
requirements: []
|
153
|
+
rubyforge_project:
|
154
|
+
rubygems_version: 2.4.5
|
155
|
+
signing_key:
|
156
|
+
specification_version: 4
|
157
|
+
summary: This gem is a logstash output plugin to connect via http to monasca-log-api.
|
158
|
+
test_files:
|
159
|
+
- spec/outputs/helper/url_helper_spec.rb
|
160
|
+
- spec/outputs/keystone/keystone_client_spec.rb
|
161
|
+
- spec/outputs/keystone/token_spec.rb
|
162
|
+
- spec/outputs/monasca/monasca_api_client_spec.rb
|
163
|
+
- spec/outputs/monasca_api_spec.rb
|
164
|
+
- spec/outputs/spec_helper.rb
|