logstash-input-qingstor 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +2 -0
- data/CODE_OF_CONDUCT.md +44 -0
- data/CONTRIBUTING.md +43 -0
- data/CONTRIBUTORS +10 -0
- data/DEVELOPER.md +2 -0
- data/Gemfile +3 -0
- data/LICENSE +11 -0
- data/README.md +168 -0
- data/lib/logstash/inputs/qingstor.rb +262 -0
- data/lib/logstash/inputs/qingstor/qingstor_validator.rb +30 -0
- data/logstash-input-qingstor.gemspec +27 -0
- data/spec/fixtures/logstash.log +100 -0
- data/spec/fixtures/logstash.log.gz +0 -0
- data/spec/inputs/qingstor_spec.rb +58 -0
- data/spec/inputs/qingstor_spec_validator_spec.rb +37 -0
- data/spec/inputs/qs_access_helper.rb +43 -0
- metadata +142 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4a30583b85c2e846709cecde14a016f28f1907b3
|
4
|
+
data.tar.gz: 7834fd79bf3ad2c7de3e971faf42e347fe38f769
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e63c11974c60a1fa33525c5b758ebbe7d80202d0e534605060bdbc7833df608d87db40e92c4cc4775be37ae78373df264ed6d96b226feab083bee8a658ec35f5
|
7
|
+
data.tar.gz: 0723a8e49fd65c445d5546030f8fc4130794cc96148ebeebd8e517b9280f00f2db732416a90eff7d8dbe3b7d499f2a9e166978bace5b2a624075cb51f4fbad0a
|
data/CHANGELOG.md
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
6
|
+
|
7
|
+
## Our Standards
|
8
|
+
|
9
|
+
Examples of behavior that contributes to creating a positive environment
|
10
|
+
include:
|
11
|
+
|
12
|
+
* Using welcoming and inclusive language
|
13
|
+
* Being respectful of differing viewpoints and experiences
|
14
|
+
* Gracefully accepting constructive criticism
|
15
|
+
* Focusing on what is best for the community
|
16
|
+
* Showing empathy towards other community members
|
17
|
+
|
18
|
+
Examples of unacceptable behavior by participants include:
|
19
|
+
|
20
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
21
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
22
|
+
* Public or private harassment
|
23
|
+
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
24
|
+
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
25
|
+
|
26
|
+
## Our Responsibilities
|
27
|
+
|
28
|
+
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
29
|
+
|
30
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
31
|
+
|
32
|
+
## Scope
|
33
|
+
|
34
|
+
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
35
|
+
|
36
|
+
## Enforcement
|
37
|
+
|
38
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at pengsrc@yunify.com. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
39
|
+
|
40
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
41
|
+
|
42
|
+
## Attribution
|
43
|
+
|
44
|
+
This Code of Conduct is adapted from the [Contributor Covenant][http://contributor-covenant.org], version 1.4, available at [http://contributor-covenant.org/version/1/4][http://contributor-covenant.org/version/1/4].
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# Contributing Guidelines
|
2
|
+
|
3
|
+
We love contributions from everyone. By participating in this project, you agree to abide by the [_`Contributor Covenant Code of Conduct`_](./CODE_OF_CONDUCT.md) and the conventions described in this documentation.
|
4
|
+
|
5
|
+
## Getting Started
|
6
|
+
|
7
|
+
### Reporting Issues
|
8
|
+
|
9
|
+
A great way to contribute to the project is to send a detailed report when you encounter an issue. We always appreciate a well-written, thorough bug report, and will thank you for it!
|
10
|
+
|
11
|
+
Check that [our issues list](https://github.com/Tacinight/logstash-output-qingstor/issues) doesn't already include that problem or suggestion before submitting an issue. If you find a match, you can use the "subscribe" button to get notified on updates. Do not leave random "+1" or "I have this too" comments, as they only clutter the discussion, and don't help resolving it. However, if you have ways to reproduce the issue or have additional information that may help resolving the issue, please leave a comment.
|
12
|
+
|
13
|
+
When reporting issues, please describe what happened clearly, and include the steps required to reproduce the problem if possible and applicable. This information will help us review and fix your issue faster. When sending lengthy log-files, consider posting them as a gist (https://gist.github.com). Don't forget to remove sensitive data from your log files before posting (you can replace those parts with "CONFIDENTIAL").
|
14
|
+
|
15
|
+
### Sending Pull Request
|
16
|
+
|
17
|
+
Pull requests are always welcome, we will appreciate it.
|
18
|
+
|
19
|
+
Any significant improvement should be documented as a GitHub [issue](https://github.com/Tacinight/logstash-output-qingstor/issues) before anybody starts working on it.
|
20
|
+
|
21
|
+
1. Fork it ( https://github.com/Tacinight/logstash-output-qingstor/fork )
|
22
|
+
2. Create your feature branch (`git checkout -b new-feature`)
|
23
|
+
3. Commit your changes (`git commit -asm 'Add some feature'`)
|
24
|
+
4. Push to the branch (`git push origin new-feature`)
|
25
|
+
5. Create a new Pull Request
|
26
|
+
|
27
|
+
## Conventions
|
28
|
+
|
29
|
+
### Patch Content
|
30
|
+
|
31
|
+
* Always remove the trailing whitespace
|
32
|
+
* Keep a newline at the end of text files
|
33
|
+
* Exclude irrelevant files, such as `*.a`, `.bundle`, and `.DS_Store`
|
34
|
+
* Always pass all the tests before submitting
|
35
|
+
* Let the propose of each patch simple and clear
|
36
|
+
|
37
|
+
### Commit Message
|
38
|
+
|
39
|
+
* Capitalize the subject line
|
40
|
+
* Limit the subject line to 50 characters
|
41
|
+
* Do not end the subject line with a period
|
42
|
+
* Wrap the body at 72 characters
|
43
|
+
* Use the body to explain what happened
|
data/CONTRIBUTORS
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
The following is a list of people who have contributed ideas, code, bug
|
2
|
+
reports, or in general have helped logstash along its way.
|
3
|
+
|
4
|
+
Contributors:
|
5
|
+
* Evan Zhao - tacingiht@gmail.com
|
6
|
+
|
7
|
+
Note: If you've sent us patches, bug reports, or otherwise contributed to
|
8
|
+
Logstash, and you aren't on the list above and want to be, please let us know
|
9
|
+
and we'll make sure you're here. Contributions from folks like you are what make
|
10
|
+
open source awesome.
|
data/DEVELOPER.md
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
2
|
+
you may not use this file except in compliance with the License.
|
3
|
+
You may obtain a copy of the License at
|
4
|
+
|
5
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
|
7
|
+
Unless required by applicable law or agreed to in writing, software
|
8
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
9
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
See the License for the specific language governing permissions and
|
11
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
# Logstash Input Plugin for Qingstor
|
2
|
+
|
3
|
+
这是一个适配了[Qingstor](https://www.qingcloud.com/products/storage#qingstor), 工作在logstash中的input插件. Qingstor是[Qingcloud](https://www.qingcloud.com/)推出的对象存储服务.
|
4
|
+
作为一个input插件, 它能下载存储在Qingstor上的日志文件, 读入到logstash中进行进一步处理.
|
5
|
+
详细功能参考下面配置说明.
|
6
|
+
|
7
|
+
目前代码尚未提交至官方插件库, 需要手动安装, 安装方法参考下文.
|
8
|
+
|
9
|
+
## 1. 配置说明
|
10
|
+
|
11
|
+
#### 1.1 最小运行配置
|
12
|
+
- 使用'-f' 接受一个*.conf文件或者使用'-e'参数最小运行配置时, 至少需要以下三项
|
13
|
+
```sh
|
14
|
+
input {
|
15
|
+
qingstor {
|
16
|
+
access_key_id => 'your_access_key_id' #required
|
17
|
+
secret_access_key => 'your_secret_access_key' #required
|
18
|
+
bucket => 'bucket_name' #required
|
19
|
+
# region => "pek3a" #optional, default value "pek3a"
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
```
|
24
|
+
|
25
|
+
#### 1.2 其他可选参数说明
|
26
|
+
```sh
|
27
|
+
input {
|
28
|
+
qingstor {
|
29
|
+
......
|
30
|
+
# 指定下载文件的前缀.
|
31
|
+
# 默认nil,
|
32
|
+
prefix => 'aprefix'
|
33
|
+
|
34
|
+
# 本地保存临时文件的目录.
|
35
|
+
# 默认: 系统临时文件目录下的qingstor2logstash文件夹, 例如linux下 "/tmp/qingstor2logstash".
|
36
|
+
tmpdir => '/local/temporary/directory'
|
37
|
+
|
38
|
+
# 是否在处理之后, 删除远程bucket中的文件.
|
39
|
+
# 默认: false
|
40
|
+
delete_later => true
|
41
|
+
|
42
|
+
# 如果指定一个本地目录, 那么在处理完之后将文件备份至该位置.
|
43
|
+
# 默认: nil
|
44
|
+
local_dir => 'your/local/directory'
|
45
|
+
|
46
|
+
# 如果指定了该值, 那么在处理完之后将文件上传到Qingstor指定的bucket中.
|
47
|
+
# 默认: nil
|
48
|
+
backup_bucket => 'backupbucket'
|
49
|
+
|
50
|
+
# 配合上一项使用, 指定备份bucket所在的region.
|
51
|
+
# 默认: "pek3a", 可选枚举值: ["pek3a", "sh1a"]
|
52
|
+
backup_region => "sh1a"
|
53
|
+
|
54
|
+
# 备份文件的前缀
|
55
|
+
# 默认: nil
|
56
|
+
backup_prefix => "logstash/backup"
|
57
|
+
|
58
|
+
# 指定一个sincedb的保存位置, sincedb用于记录上一次抓取文件的时间
|
59
|
+
# 没有指定时默认在用户HOME目录下创建
|
60
|
+
# 默认: nil
|
61
|
+
sincedb_path => "~/qingstor/.sincedb"
|
62
|
+
|
63
|
+
# 每次抓取的时间间隔, 单位秒
|
64
|
+
# 默认: 10(s)
|
65
|
+
interval => 30
|
66
|
+
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
```
|
71
|
+
|
72
|
+
## 2. 安装插件
|
73
|
+
|
74
|
+
#### 2.1 直接运行本地的插件
|
75
|
+
|
76
|
+
- 编辑Logstash目录下的Genfile, 添加插件的路径, 例如
|
77
|
+
```ruby
|
78
|
+
gem "logstash-input-qingstor", :path => "/your/local/logstash-input-qingstor"
|
79
|
+
```
|
80
|
+
- 安装插件
|
81
|
+
```sh
|
82
|
+
bin/logstash-plugin install --no-verify
|
83
|
+
```
|
84
|
+
- 使用插件运行
|
85
|
+
```sh
|
86
|
+
bin/logstash -e "input {qingstor { access_key_id => 'your_access_key_id'
|
87
|
+
secret_access_key => 'your_secret_access_key'
|
88
|
+
bucket => 'bucket_name' }}'
|
89
|
+
```
|
90
|
+
此时你对插件所做的任意的代码上的修改都会直接生效.
|
91
|
+
|
92
|
+
#### 2.2 安装一个本地插件然后运行
|
93
|
+
|
94
|
+
这一步你需要生成一个插件的gem包, 然后通过logstash来安装到logstash的插件目录下
|
95
|
+
- 在logstash-input-qingstor项目目录下生成gem
|
96
|
+
```sh
|
97
|
+
gem build logstash-input-qingstor.gemspec
|
98
|
+
```
|
99
|
+
- 在Logstash的目录下使用logstash-plugin安装
|
100
|
+
```sh
|
101
|
+
bin/logstash-plugin install /your/local/plugin/logstash-input-qingstor.gem
|
102
|
+
```
|
103
|
+
- 安装完毕之后, 就可以使用Logstash运行开始测试了.
|
104
|
+
|
105
|
+
|
106
|
+
# Logstash Output Plugin for Qingstor
|
107
|
+
|
108
|
+
As an input plugin, it can download the log files from [Qingstor](https://www.qingcloud.com/products/storage#qingstor), and read them into logstash.
|
109
|
+
Qingstor is a remarkable object storage service provided by [Qingcloud](https://www.qingcloud.com/).
|
110
|
+
|
111
|
+
For now, We haven't submitted this to official plugin repository. If you want to have a try, please refer to the following guide to install it manually.
|
112
|
+
|
113
|
+
## 1. Configuration Guide
|
114
|
+
|
115
|
+
#### 1.1 Run in minimal Configuration Items
|
116
|
+
```sh
|
117
|
+
input {
|
118
|
+
qingstor {
|
119
|
+
access_key_id => 'your_access_key_id' #required
|
120
|
+
secret_access_key => 'your_secret_access_key' #required
|
121
|
+
bucket => 'bucket_name' #required
|
122
|
+
# region => "pek3a" #optional, default value "pek3a"
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
```
|
127
|
+
|
128
|
+
More configuration details please refer to [code part](lib/logstash/inputs/qingstor.rb).
|
129
|
+
|
130
|
+
## 2. Running your unpublished Plugin in Logstash
|
131
|
+
|
132
|
+
#### 2.1 Run in a local Logstash clone
|
133
|
+
|
134
|
+
- Edit Logstash `Gemfile` and add the local plugin path, for example:
|
135
|
+
```ruby
|
136
|
+
gem "logstash-input-qingstor", :path => "/your/local/logstash-input-qingstor"
|
137
|
+
```
|
138
|
+
- Install plugin
|
139
|
+
```sh
|
140
|
+
bin/logstash-plugin install --no-verify
|
141
|
+
```
|
142
|
+
- Run Logstash with your plugin
|
143
|
+
```sh
|
144
|
+
bin/logstash -e "input {qingstor { access_key_id => 'your_access_key_id'
|
145
|
+
secret_access_key => 'your_secret_access_key'
|
146
|
+
bucket => 'bucket_name' }}"
|
147
|
+
```
|
148
|
+
At this point any modifications to the plugin code will be applied to this local Logstash setup. After modifying the plugin, simply rerun Logstash.
|
149
|
+
|
150
|
+
#### 2.2 Run in an installed Logstash
|
151
|
+
|
152
|
+
You can use the same **2.1** method to run your plugin in an installed Logstash by editing its `Gemfile` and pointing the `:path` to your local plugin development directory or you can build the gem and install it using:
|
153
|
+
|
154
|
+
- Build your plugin gem
|
155
|
+
```sh
|
156
|
+
gem build logstash-input-qingstor.gemspec
|
157
|
+
```
|
158
|
+
- Install the plugin from the Logstash home
|
159
|
+
```sh
|
160
|
+
bin/logstash-plugin install /your/local/plugin/logstash-input-qingstor.gem
|
161
|
+
```
|
162
|
+
- Start Logstash and proceed to test the plugin
|
163
|
+
|
164
|
+
## Contributing
|
165
|
+
Please see [Contributing Guidelines](./CONTRIBUTING.md) of this project before submitting patches.
|
166
|
+
|
167
|
+
## LICENSE
|
168
|
+
The Apache License (Version 2.0, January 2004).
|
@@ -0,0 +1,262 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/inputs/base"
|
3
|
+
require "logstash/namespace"
|
4
|
+
require "stud/interval"
|
5
|
+
require "qingstor/sdk"
|
6
|
+
require "fileutils"
|
7
|
+
require "tmpdir"
|
8
|
+
|
9
|
+
class LogStash::Inputs::Qingstor < LogStash::Inputs::Base
|
10
|
+
require "logstash/inputs/qingstor/qingstor_validator"
|
11
|
+
config_name "qingstor"
|
12
|
+
|
13
|
+
default :codec, "plain"
|
14
|
+
|
15
|
+
# The key id to access your QingStor
|
16
|
+
config :access_key_id, :validate => :string, :required => true
|
17
|
+
|
18
|
+
# The key to access your QingStor
|
19
|
+
config :secret_access_key, :validate => :string, :required => true
|
20
|
+
|
21
|
+
# The name of the qingstor bucket
|
22
|
+
config :bucket, :validate => :string, :required => true
|
23
|
+
|
24
|
+
# The region of the QingStor bucket
|
25
|
+
config :region, :validate => ["pek3a", "sh1a"], :default => "pek3a"
|
26
|
+
|
27
|
+
# If specified, it would only download the files with the specified prefix.
|
28
|
+
config :prefix, :validate => :string, :default => nil
|
29
|
+
|
30
|
+
# Set the directory where logstash store the tmp files before
|
31
|
+
# sending it to logstash, default directory in linux /tmp/logstash2qingstor
|
32
|
+
config :tmpdir, :validate => :string, :default => File.join(Dir.tmpdir, "qingstor2logstash")
|
33
|
+
|
34
|
+
# If this set to true, the remote file will be deleted after processed
|
35
|
+
config :delete_later, :validate => :boolean, :default => false
|
36
|
+
|
37
|
+
# If this set to true, the file will backup to a local dir,
|
38
|
+
# please make sure you can access to this dir.
|
39
|
+
config :local_dir, :validate => :string, :default => File.expand_path("~/")
|
40
|
+
|
41
|
+
# If specified, the file will be upload to this bucket of the given region
|
42
|
+
config :backup_bucket, :validate => :string, :default => nil
|
43
|
+
|
44
|
+
# Specified the backup region in Qingstor.
|
45
|
+
config :backup_region, :validate => ["pek3a", "sh1a"], :default => "pek3a"
|
46
|
+
|
47
|
+
# This prefix will add before backup filename.
|
48
|
+
config :backup_prefix, :validate => :string, :default => nil
|
49
|
+
|
50
|
+
# Use sincedb to record the last download time
|
51
|
+
config :sincedb_path, :validate => :string, :default => nil
|
52
|
+
|
53
|
+
# Set how frequently messages should be sent.
|
54
|
+
# The default, `10`, means send a message every 10 seconds.
|
55
|
+
config :interval, :validate => :number, :default => 10
|
56
|
+
|
57
|
+
public
|
58
|
+
def register
|
59
|
+
|
60
|
+
if !@tmpdir.nil? && !directory_valid?(@tmpdir)
|
61
|
+
raise LogStash::ConfigurationError, "Logstash must have the permissions to write to the temporary directory: #{@tmpdir}"
|
62
|
+
end
|
63
|
+
|
64
|
+
if !@local_dir.nil? && !directory_valid?(@local_dir)
|
65
|
+
raise LogStash::ConfigurationError, "Logstash must have the permissions to write to the temporary directory: #{@local_dir}"
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
@logger.info "Registering QingStor plugin", :bucket => @bucket, :region => @region
|
70
|
+
|
71
|
+
@qs_config = QingStor::SDK::Config.init @access_key_id, @secret_access_key
|
72
|
+
@qs_service = QingStor::SDK::Service.new @qs_config
|
73
|
+
@qs_bucket = @qs_service.bucket @bucket, @region
|
74
|
+
|
75
|
+
QingstorValidator.bucket_valid?(@qs_bucket)
|
76
|
+
QingstorValidator.prefix_valid?(@backup_prefix)
|
77
|
+
|
78
|
+
end # def register
|
79
|
+
|
80
|
+
def run(queue)
|
81
|
+
@logger.info "starting processing"
|
82
|
+
@current_thread = Thread.current
|
83
|
+
Stud.interval(@interval) do
|
84
|
+
process_files(queue)
|
85
|
+
end
|
86
|
+
end # def run
|
87
|
+
|
88
|
+
|
89
|
+
def process_files(queue)
|
90
|
+
objects = list_new_files
|
91
|
+
|
92
|
+
# For each record in objects, it will be download and read
|
93
|
+
# into logstash. Then it will do deletion or backup job
|
94
|
+
# according to preset flags.
|
95
|
+
objects.each do |key, time|
|
96
|
+
process_log(queue, key)
|
97
|
+
backup_to_bucket key unless @backup_bucket.nil?
|
98
|
+
backup_to_local_dir unless @local_dir.nil?
|
99
|
+
@qs_bucket.delete_object key if @delete_later
|
100
|
+
end
|
101
|
+
|
102
|
+
# if fetched nothing, just return
|
103
|
+
return if objects.empty?
|
104
|
+
_time = objects.values.max
|
105
|
+
sincedb.write(Time.at(_time))
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
def list_new_files
|
110
|
+
objects = {}
|
111
|
+
@logger.info "starting fetching objects"
|
112
|
+
res = @qs_bucket.list_objects({'prefix' => @prefix})
|
113
|
+
res[:keys].each do |log|
|
114
|
+
next unless is_desired?(log[:key])
|
115
|
+
next unless sincedb.newer?(log[:modified])
|
116
|
+
objects[log[:key]] = log[:modified]
|
117
|
+
@logger.info("QingStor input: Adding to object:", :key => log[:key])
|
118
|
+
end
|
119
|
+
return objects
|
120
|
+
end
|
121
|
+
|
122
|
+
def process_log(queue, key)
|
123
|
+
# a global var, for the next possible upload and copy job
|
124
|
+
@tmp_file_path = File.join(@tmpdir, File.basename(key))
|
125
|
+
|
126
|
+
File.open(@tmp_file_path, 'wb') do |logfile|
|
127
|
+
logfile.write @qs_bucket.get_object(key)[:body]
|
128
|
+
end
|
129
|
+
process_local_log(queue, @tmp_file_path)
|
130
|
+
end
|
131
|
+
|
132
|
+
def backup_to_bucket(key)
|
133
|
+
properties = {'bucket-name' => @backup_bucket, 'zone' => @backup_region}
|
134
|
+
bucket = QingStor::SDK::Bucket.new @qs_config, properties
|
135
|
+
|
136
|
+
if bucket.head[:status_code] != 200
|
137
|
+
res = bucket.put
|
138
|
+
if res[:status_code] != 201
|
139
|
+
@logger.error("ERROR : cannot create the bucket ", res[:message])
|
140
|
+
raise LogStash::ConfigurationError, "cannot create the bucket"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
md5_string = Digest::MD5.file(@tmp_file_path).to_s
|
145
|
+
|
146
|
+
new_key = if backup_prefix.end_with?('/')
|
147
|
+
backup_prefix + key
|
148
|
+
else
|
149
|
+
backup_prefix + '/' + key
|
150
|
+
end
|
151
|
+
|
152
|
+
bucket.put_object new_key, {
|
153
|
+
'content_md5' => md5_string,
|
154
|
+
'body' => File.open(@tmp_file_path)
|
155
|
+
}
|
156
|
+
end
|
157
|
+
|
158
|
+
def backup_to_local_dir
|
159
|
+
FileUtils.mkdir_p @local_dir unless File.exist? @local_dir
|
160
|
+
FileUtils.cp @tmp_file_path, @local_dir
|
161
|
+
end
|
162
|
+
|
163
|
+
def process_local_log(queue, filename)
|
164
|
+
read_file(filename) do |line|
|
165
|
+
@codec.decode(line) do |event|
|
166
|
+
decorate(event)
|
167
|
+
queue << event
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def read_file(filename, &block)
|
173
|
+
if gzip?(filename)
|
174
|
+
read_gzip_file(filename, block)
|
175
|
+
else
|
176
|
+
read_plain_file(filename, block)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def read_gzip_file(filename, block)
|
181
|
+
begin
|
182
|
+
Zlib::GzipReader.open(filename) do |decoder|
|
183
|
+
decoder.each_line { |line| block.call(line) }
|
184
|
+
end
|
185
|
+
rescue Zlib::Error, Zlib::GzipFile::Error => e
|
186
|
+
@logger.error("Gzip codec: Cannot uncompress the file", :filename => filename)
|
187
|
+
raise e
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def read_plain_file(filename, block)
|
192
|
+
File.open(filename, 'rb') do |file|
|
193
|
+
file.each(&block)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
def is_desired?(filename)
|
198
|
+
return logger?(filename) || gzip?(filename)
|
199
|
+
end
|
200
|
+
|
201
|
+
def logger?(filename)
|
202
|
+
return filename.end_with?('.log')
|
203
|
+
end
|
204
|
+
|
205
|
+
def gzip?(filename)
|
206
|
+
return filename.end_with?('.gz')
|
207
|
+
end
|
208
|
+
|
209
|
+
def sincedb
|
210
|
+
@sincedb ||= if @sincedb_path.nil?
|
211
|
+
@logger.info("Using default path for the sincedb", :filename => sincedb_file)
|
212
|
+
SinceDB::File.new(sincedb_file)
|
213
|
+
else
|
214
|
+
@logger.info("Using the provided sincedb_path")
|
215
|
+
SinceDB::File.new(@sincedb_path)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def sincedb_file
|
220
|
+
File.join(ENV["HOME"], ".sincedb_" + Digest::MD5.hexdigest("#{@bucket}+#{@prefix}"))
|
221
|
+
end
|
222
|
+
|
223
|
+
module SinceDB
|
224
|
+
class File
|
225
|
+
def initialize(file)
|
226
|
+
@sincedb_path = file
|
227
|
+
end
|
228
|
+
|
229
|
+
def newer?(date)
|
230
|
+
Time.at(date) > read
|
231
|
+
end
|
232
|
+
|
233
|
+
def read
|
234
|
+
if ::File.exist?(@sincedb_path)
|
235
|
+
content = ::File.read(@sincedb_path).chomp.strip
|
236
|
+
return content.empty? ? Time.new(0) : Time.parse(content)
|
237
|
+
else
|
238
|
+
return Time.new(0)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def write(since = nil)
|
243
|
+
since = Time.now() if since.nil?
|
244
|
+
::File.open(@sincedb_path, 'w') { |file| file.write(since.to_s) }
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
public
|
250
|
+
def stop
|
251
|
+
Stud.stop!(@current_thread)
|
252
|
+
end
|
253
|
+
|
254
|
+
def directory_valid?(path)
|
255
|
+
begin
|
256
|
+
FileUtils.mkdir_p(path) unless Dir.exist?(path)
|
257
|
+
::File.writable?(path)
|
258
|
+
rescue
|
259
|
+
false
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end # class LogStash::Inputs::Qingstor
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "qingstor/sdk"
|
3
|
+
require "fileutils"
|
4
|
+
|
5
|
+
module LogStash
|
6
|
+
module Inputs
|
7
|
+
class Qingstor
|
8
|
+
class QingstorValidator
|
9
|
+
|
10
|
+
def bucket_valid?(bucket)
|
11
|
+
res = bucket.head
|
12
|
+
case res[:status_code]
|
13
|
+
when 401
|
14
|
+
raise LogStash::ConfigurationError, "Incorrect key id or access key."
|
15
|
+
when 404
|
16
|
+
raise LogStash::ConfigurationError, "Incorrect bucket/region name."
|
17
|
+
end
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def prefix_valid?(prefix)
|
22
|
+
if prefix.start_with?("/") || prefix.length >= 1024
|
23
|
+
raise LogStash::ConfigurationError, "Prefix must not start with '/' with length less than 1024 "
|
24
|
+
end
|
25
|
+
true
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'logstash-input-qingstor'
|
3
|
+
s.version = '0.1.0'
|
4
|
+
s.licenses = ['Apache License (2.0)']
|
5
|
+
s.summary = 'logstash input plugin for QingStor'
|
6
|
+
s.description = 'Use this plugin to fetch file as a input of logstash from QingStor'
|
7
|
+
s.homepage = 'https://github.com/Tacinight/logstash-input-qingstor'
|
8
|
+
s.authors = ['Evan Zhao']
|
9
|
+
s.email = 'tacingiht@gmail.com'
|
10
|
+
s.require_paths = ['lib']
|
11
|
+
|
12
|
+
# Files
|
13
|
+
s.files = Dir['lib/**/*','spec/**/*','vendor/**/*','*.gemspec','*.md','CONTRIBUTORS','Gemfile','LICENSE','NOTICE.TXT']
|
14
|
+
# Tests
|
15
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
16
|
+
|
17
|
+
# Special flag to let us know this is actually a logstash plugin
|
18
|
+
s.metadata = { "logstash_plugin" => "true", "logstash_group" => "input" }
|
19
|
+
|
20
|
+
# Gem dependencies
|
21
|
+
s.add_runtime_dependency "logstash-core-plugin-api", ">=1.6", "<=2.99"
|
22
|
+
s.add_runtime_dependency 'logstash-codec-plain'
|
23
|
+
s.add_runtime_dependency 'stud', '>= 0.0.22'
|
24
|
+
s.add_runtime_dependency "qingstor-sdk", "=1.9.2"
|
25
|
+
|
26
|
+
s.add_development_dependency 'logstash-devutils'
|
27
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
83.149.9.216 - - [04/Jan/2015:05:13:42 +0000] "GET /presentations/logstash-monitorama-2013/images/kibana-search.png HTTP/1.1" 200 203023 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
2
|
+
83.149.9.216 - - [04/Jan/2015:05:13:42 +0000] "GET /presentations/logstash-monitorama-2013/images/kibana-dashboard3.png HTTP/1.1" 200 171717 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
3
|
+
83.149.9.216 - - [04/Jan/2015:05:13:44 +0000] "GET /presentations/logstash-monitorama-2013/plugin/highlight/highlight.js HTTP/1.1" 200 26185 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
4
|
+
83.149.9.216 - - [04/Jan/2015:05:13:44 +0000] "GET /presentations/logstash-monitorama-2013/plugin/zoom-js/zoom.js HTTP/1.1" 200 7697 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
5
|
+
83.149.9.216 - - [04/Jan/2015:05:13:45 +0000] "GET /presentations/logstash-monitorama-2013/plugin/notes/notes.js HTTP/1.1" 200 2892 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
6
|
+
83.149.9.216 - - [04/Jan/2015:05:13:42 +0000] "GET /presentations/logstash-monitorama-2013/images/sad-medic.png HTTP/1.1" 200 430406 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
7
|
+
83.149.9.216 - - [04/Jan/2015:05:13:45 +0000] "GET /presentations/logstash-monitorama-2013/css/fonts/Roboto-Bold.ttf HTTP/1.1" 200 38720 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
8
|
+
83.149.9.216 - - [04/Jan/2015:05:13:45 +0000] "GET /presentations/logstash-monitorama-2013/css/fonts/Roboto-Regular.ttf HTTP/1.1" 200 41820 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
9
|
+
83.149.9.216 - - [04/Jan/2015:05:13:45 +0000] "GET /presentations/logstash-monitorama-2013/images/frontend-response-codes.png HTTP/1.1" 200 52878 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
10
|
+
83.149.9.216 - - [04/Jan/2015:05:13:43 +0000] "GET /presentations/logstash-monitorama-2013/images/kibana-dashboard.png HTTP/1.1" 200 321631 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
11
|
+
83.149.9.216 - - [04/Jan/2015:05:13:46 +0000] "GET /presentations/logstash-monitorama-2013/images/Dreamhost_logo.svg HTTP/1.1" 200 2126 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
12
|
+
83.149.9.216 - - [04/Jan/2015:05:13:43 +0000] "GET /presentations/logstash-monitorama-2013/images/kibana-dashboard2.png HTTP/1.1" 200 394967 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
13
|
+
83.149.9.216 - - [04/Jan/2015:05:13:46 +0000] "GET /presentations/logstash-monitorama-2013/images/apache-icon.gif HTTP/1.1" 200 8095 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
14
|
+
83.149.9.216 - - [04/Jan/2015:05:13:46 +0000] "GET /presentations/logstash-monitorama-2013/images/nagios-sms5.png HTTP/1.1" 200 78075 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
15
|
+
83.149.9.216 - - [04/Jan/2015:05:13:46 +0000] "GET /presentations/logstash-monitorama-2013/images/redis.png HTTP/1.1" 200 25230 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
16
|
+
83.149.9.216 - - [04/Jan/2015:05:13:47 +0000] "GET /presentations/logstash-monitorama-2013/images/elasticsearch.png HTTP/1.1" 200 8026 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
17
|
+
83.149.9.216 - - [04/Jan/2015:05:13:47 +0000] "GET /presentations/logstash-monitorama-2013/images/logstashbook.png HTTP/1.1" 200 54662 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
18
|
+
83.149.9.216 - - [04/Jan/2015:05:13:47 +0000] "GET /presentations/logstash-monitorama-2013/images/github-contributions.png HTTP/1.1" 200 34245 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
19
|
+
83.149.9.216 - - [04/Jan/2015:05:13:47 +0000] "GET /presentations/logstash-monitorama-2013/css/print/paper.css HTTP/1.1" 200 4254 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
20
|
+
83.149.9.216 - - [04/Jan/2015:05:13:47 +0000] "GET /presentations/logstash-monitorama-2013/images/1983_delorean_dmc-12-pic-38289.jpeg HTTP/1.1" 200 220562 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
21
|
+
83.149.9.216 - - [04/Jan/2015:05:13:46 +0000] "GET /presentations/logstash-monitorama-2013/images/simple-inputs-filters-outputs.jpg HTTP/1.1" 200 1168622 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
22
|
+
83.149.9.216 - - [04/Jan/2015:05:13:46 +0000] "GET /presentations/logstash-monitorama-2013/images/tiered-outputs-to-inputs.jpg HTTP/1.1" 200 1079983 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
23
|
+
83.149.9.216 - - [04/Jan/2015:05:13:53 +0000] "GET /favicon.ico HTTP/1.1" 200 3638 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"
|
24
|
+
24.236.252.67 - - [04/Jan/2015:05:14:10 +0000] "GET /favicon.ico HTTP/1.1" 200 3638 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:26.0) Gecko/20100101 Firefox/26.0"
|
25
|
+
93.114.45.13 - - [04/Jan/2015:05:14:32 +0000] "GET /articles/dynamic-dns-with-dhcp/ HTTP/1.1" 200 18848 "http://www.google.ro/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=0CCwQFjAB&url=http%3A%2F%2Fwww.semicomplete.com%2Farticles%2Fdynamic-dns-with-dhcp%2F&ei=W88AU4n9HOq60QXbv4GwBg&usg=AFQjCNEF1X4Rs52UYQyLiySTQxa97ozM4g&bvm=bv.61535280,d.d2k" "Mozilla/5.0 (X11; Linux x86_64; rv:25.0) Gecko/20100101 Firefox/25.0"
|
26
|
+
93.114.45.13 - - [04/Jan/2015:05:14:32 +0000] "GET /reset.css HTTP/1.1" 200 1015 "http://www.semicomplete.com/articles/dynamic-dns-with-dhcp/" "Mozilla/5.0 (X11; Linux x86_64; rv:25.0) Gecko/20100101 Firefox/25.0"
|
27
|
+
93.114.45.13 - - [04/Jan/2015:05:14:33 +0000] "GET /style2.css HTTP/1.1" 200 4877 "http://www.semicomplete.com/articles/dynamic-dns-with-dhcp/" "Mozilla/5.0 (X11; Linux x86_64; rv:25.0) Gecko/20100101 Firefox/25.0"
|
28
|
+
93.114.45.13 - - [04/Jan/2015:05:14:33 +0000] "GET /favicon.ico HTTP/1.1" 200 3638 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:25.0) Gecko/20100101 Firefox/25.0"
|
29
|
+
93.114.45.13 - - [04/Jan/2015:05:14:33 +0000] "GET /images/jordan-80.png HTTP/1.1" 200 6146 "http://www.semicomplete.com/articles/dynamic-dns-with-dhcp/" "Mozilla/5.0 (X11; Linux x86_64; rv:25.0) Gecko/20100101 Firefox/25.0"
|
30
|
+
93.114.45.13 - - [04/Jan/2015:05:14:33 +0000] "GET /images/web/2009/banner.png HTTP/1.1" 200 52315 "http://www.semicomplete.com/style2.css" "Mozilla/5.0 (X11; Linux x86_64; rv:25.0) Gecko/20100101 Firefox/25.0"
|
31
|
+
66.249.73.135 - - [04/Jan/2015:05:15:03 +0000] "GET /blog/tags/ipv6 HTTP/1.1" 200 12251 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
|
32
|
+
50.16.19.13 - - [04/Jan/2015:05:15:15 +0000] "GET /blog/tags/puppet?flav=rss20 HTTP/1.1" 200 14872 "http://www.semicomplete.com/blog/tags/puppet?flav=rss20" "Tiny Tiny RSS/1.11 (http://tt-rss.org/)"
|
33
|
+
66.249.73.185 - - [04/Jan/2015:05:15:23 +0000] "GET / HTTP/1.1" 200 37932 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
|
34
|
+
110.136.166.128 - - [04/Jan/2015:05:16:11 +0000] "GET /projects/xdotool/ HTTP/1.1" 200 12292 "http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=5&cad=rja&sqi=2&ved=0CFYQFjAE&url=http%3A%2F%2Fwww.semicomplete.com%2Fprojects%2Fxdotool%2F&ei=6cwAU_bRHo6urAeI0YD4Ag&usg=AFQjCNE3V_aCf3-gfNcbS924S6jZ6FqffA&bvm=bv.61535280,d.bmk" "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0"
|
35
|
+
46.105.14.53 - - [04/Jan/2015:05:16:17 +0000] "GET /blog/tags/puppet?flav=rss20 HTTP/1.1" 200 14872 "-" "UniversalFeedParser/4.2-pre-314-svn +http://feedparser.org/"
|
36
|
+
110.136.166.128 - - [04/Jan/2015:05:16:22 +0000] "GET /reset.css HTTP/1.1" 200 1015 "http://www.semicomplete.com/projects/xdotool/" "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0"
|
37
|
+
110.136.166.128 - - [04/Jan/2015:05:16:22 +0000] "GET /style2.css HTTP/1.1" 200 4877 "http://www.semicomplete.com/projects/xdotool/" "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0"
|
38
|
+
110.136.166.128 - - [04/Jan/2015:05:16:22 +0000] "GET /favicon.ico HTTP/1.1" 200 3638 "-" "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0"
|
39
|
+
110.136.166.128 - - [04/Jan/2015:05:16:22 +0000] "GET /images/jordan-80.png HTTP/1.1" 200 6146 "http://www.semicomplete.com/projects/xdotool/" "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0"
|
40
|
+
123.125.71.35 - - [04/Jan/2015:05:16:31 +0000] "GET /blog/tags/release HTTP/1.1" 200 40693 "-" "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"
|
41
|
+
110.136.166.128 - - [04/Jan/2015:05:16:22 +0000] "GET /images/web/2009/banner.png HTTP/1.1" 200 52315 "http://www.semicomplete.com/style2.css" "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0"
|
42
|
+
50.150.204.184 - - [04/Jan/2015:05:17:06 +0000] "GET /images/googledotcom.png HTTP/1.1" 200 65748 "http://www.google.com/search?q=https//:google.com&source=lnms&tbm=isch&sa=X&ei=4-r8UvDrKZOgkQe7x4CICw&ved=0CAkQ_AUoAA&biw=320&bih=441" "Mozilla/5.0 (Linux; U; Android 4.0.4; en-us; LG-MS770 Build/IMM76I) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30"
|
43
|
+
207.241.237.225 - - [04/Jan/2015:05:17:35 +0000] "GET /blog/tags/examples HTTP/1.0" 200 9208 "http://www.semicomplete.com/blog/tags/C" "Mozilla/5.0 (compatible; archive.org_bot +http://www.archive.org/details/archive.org_bot)"
|
44
|
+
200.49.190.101 - - [04/Jan/2015:05:17:39 +0000] "GET /reset.css HTTP/1.1" 200 1015 "-" "-"
|
45
|
+
200.49.190.100 - - [04/Jan/2015:05:17:37 +0000] "GET /blog/tags/web HTTP/1.1" 200 44019 "-" "QS304 Profile/MIDP-2.0 Configuration/CLDC-1.1"
|
46
|
+
200.49.190.101 - - [04/Jan/2015:05:17:41 +0000] "GET /style2.css HTTP/1.1" 200 4877 "-" "-"
|
47
|
+
200.49.190.101 - - [04/Jan/2015:05:17:48 +0000] "GET /images/jordan-80.png HTTP/1.1" 200 6146 "-" "QS304 Profile/MIDP-2.0 Configuration/CLDC-1.1"
|
48
|
+
66.249.73.185 - - [04/Jan/2015:05:18:48 +0000] "GET /reset.css HTTP/1.1" 200 1015 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
|
49
|
+
66.249.73.135 - - [04/Jan/2015:05:18:55 +0000] "GET /blog/tags/munin HTTP/1.1" 200 9746 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
|
50
|
+
66.249.73.135 - - [04/Jan/2015:05:19:16 +0000] "GET /blog/tags/firefox?flav=rss20 HTTP/1.1" 200 16021 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
|
51
|
+
66.249.73.135 - - [04/Jan/2015:05:20:03 +0000] "GET /blog/geekery/eventdb-ideas.html HTTP/1.1" 200 11418 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
|
52
|
+
67.214.178.190 - - [04/Jan/2015:05:20:48 +0000] "GET / HTTP/1.0" 200 37932 "http://www.semicomplete.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:21.0) Gecko/20100101 Firefox/21.0"
|
53
|
+
67.214.178.190 - - [04/Jan/2015:05:20:59 +0000] "GET /blog/geekery/installing-windows-8-consumer-preview.html HTTP/1.0" 200 8948 "http://www.semicomplete.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:21.0) Gecko/20100101 Firefox/21.0"
|
54
|
+
207.241.237.220 - - [04/Jan/2015:05:21:16 +0000] "GET /blog/tags/projects HTTP/1.0" 200 28370 "http://www.semicomplete.com/blog/tags/C" "Mozilla/5.0 (compatible; archive.org_bot +http://www.archive.org/details/archive.org_bot)"
|
55
|
+
46.105.14.53 - - [04/Jan/2015:05:21:17 +0000] "GET /blog/tags/puppet?flav=rss20 HTTP/1.1" 200 14872 "-" "UniversalFeedParser/4.2-pre-314-svn +http://feedparser.org/"
|
56
|
+
207.241.237.227 - - [04/Jan/2015:05:21:19 +0000] "GET /blog/geekery/soekris-gpio.html HTTP/1.0" 200 9587 "http://www.semicomplete.com/blog/tags/C" "Mozilla/5.0 (compatible; archive.org_bot +http://www.archive.org/details/archive.org_bot)"
|
57
|
+
91.177.205.119 - - [04/Jan/2015:05:22:03 +0000] "GET /blog/geekery/xvfb-firefox.html HTTP/1.1" 200 10975 "http://en.wikipedia.org/wiki/Xvfb" "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
|
58
|
+
91.177.205.119 - - [04/Jan/2015:05:22:03 +0000] "GET /reset.css HTTP/1.1" 200 1015 "http://semicomplete.com/blog/geekery/xvfb-firefox.html" "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
|
59
|
+
91.177.205.119 - - [04/Jan/2015:05:22:03 +0000] "GET /style2.css HTTP/1.1" 200 4877 "http://semicomplete.com/blog/geekery/xvfb-firefox.html" "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
|
60
|
+
91.177.205.119 - - [04/Jan/2015:05:22:03 +0000] "GET /images/jordan-80.png HTTP/1.1" 200 6146 "http://semicomplete.com/blog/geekery/xvfb-firefox.html" "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
|
61
|
+
91.177.205.119 - - [04/Jan/2015:05:22:03 +0000] "GET /images/web/2009/banner.png HTTP/1.1" 200 52315 "http://semicomplete.com/blog/geekery/xvfb-firefox.html" "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"
|
62
|
+
91.177.205.119 - - [04/Jan/2015:05:22:04 +0000] "GET /favicon.ico HTTP/1.1" 200 3638 "-" "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Win64; x64; Trident/6.0)"
|
63
|
+
66.249.73.185 - - [04/Jan/2015:05:22:13 +0000] "GET /doc/index.html?org/elasticsearch/action/search/SearchResponse.html HTTP/1.1" 404 294 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
|
64
|
+
207.241.237.228 - - [04/Jan/2015:05:22:23 +0000] "GET /blog/tags/defcon HTTP/1.0" 200 24142 "http://www.semicomplete.com/blog/tags/C" "Mozilla/5.0 (compatible; archive.org_bot +http://www.archive.org/details/archive.org_bot)"
|
65
|
+
207.241.237.101 - - [04/Jan/2015:05:22:27 +0000] "GET /blog/tags/regex HTTP/1.0" 200 14888 "http://www.semicomplete.com/blog/tags/C" "Mozilla/5.0 (compatible; archive.org_bot +http://www.archive.org/details/archive.org_bot)"
|
66
|
+
87.169.99.232 - - [04/Jan/2015:05:23:41 +0000] "GET /presentations/puppet-at-loggly/puppet-at-loggly.pdf.html HTTP/1.1" 200 24747 "https://www.google.de/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
|
67
|
+
209.85.238.199 - - [04/Jan/2015:05:23:47 +0000] "GET /blog/tags/firefox?flav=rss20 HTTP/1.1" 200 16021 "-" "Feedfetcher-Google; (+http://www.google.com/feedfetcher.html; 3 subscribers; feed-id=14171215010336145331)"
|
68
|
+
209.85.238.199 - - [04/Jan/2015:05:24:00 +0000] "GET /test.xml HTTP/1.1" 200 1370 "-" "Feedfetcher-Google; (+http://www.google.com/feedfetcher.html; 1 subscribers; feed-id=11390274670024826467)"
|
69
|
+
81.220.24.207 - - [04/Jan/2015:05:24:57 +0000] "GET /blog/geekery/ssl-latency.html HTTP/1.1" 200 17147 "http://www.google.fr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=5&ved=0CE4QFjAE&url=http%3A%2F%2Fwww.semicomplete.com%2Fblog%2Fgeekery%2Fssl-latency.html&ei=ZdEAU9mGGuWX1AW09IDoBw&usg=AFQjCNHw6zioJpizqX8Q0YpKKaF4zdCSEg&bvm=bv.61535280,d.d2k" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.73.11 (KHTML, like Gecko) Version/7.0.1 Safari/537.73.11"
|
70
|
+
81.220.24.207 - - [04/Jan/2015:05:24:57 +0000] "GET /reset.css HTTP/1.1" 200 1015 "http://www.semicomplete.com/blog/geekery/ssl-latency.html" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.73.11 (KHTML, like Gecko) Version/7.0.1 Safari/537.73.11"
|
71
|
+
81.220.24.207 - - [04/Jan/2015:05:24:57 +0000] "GET /images/jordan-80.png HTTP/1.1" 200 6146 "http://www.semicomplete.com/blog/geekery/ssl-latency.html" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.73.11 (KHTML, like Gecko) Version/7.0.1 Safari/537.73.11"
|
72
|
+
81.220.24.207 - - [04/Jan/2015:05:24:57 +0000] "GET /style2.css HTTP/1.1" 200 4877 "http://www.semicomplete.com/blog/geekery/ssl-latency.html" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.73.11 (KHTML, like Gecko) Version/7.0.1 Safari/537.73.11"
|
73
|
+
81.220.24.207 - - [04/Jan/2015:05:24:57 +0000] "GET /images/web/2009/banner.png HTTP/1.1" 200 52315 "http://www.semicomplete.com/blog/geekery/ssl-latency.html" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.73.11 (KHTML, like Gecko) Version/7.0.1 Safari/537.73.11"
|
74
|
+
81.220.24.207 - - [04/Jan/2015:05:24:58 +0000] "GET /favicon.ico HTTP/1.1" 200 3638 "http://www.semicomplete.com/blog/geekery/ssl-latency.html" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.73.11 (KHTML, like Gecko) Version/7.0.1 Safari/537.73.11"
|
75
|
+
66.249.73.135 - - [04/Jan/2015:05:25:05 +0000] "GET /blog/geekery/vmware-cpu-performance.html HTTP/1.1" 200 12908 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
|
76
|
+
46.105.14.53 - - [04/Jan/2015:05:26:17 +0000] "GET /blog/tags/puppet?flav=rss20 HTTP/1.1" 200 14872 "-" "UniversalFeedParser/4.2-pre-314-svn +http://feedparser.org/"
|
77
|
+
218.30.103.62 - - [04/Jan/2015:05:27:05 +0000] "GET /robots.txt HTTP/1.1" 200 - "-" "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)"
|
78
|
+
218.30.103.62 - - [04/Jan/2015:05:27:10 +0000] "GET /robots.txt HTTP/1.1" 200 - "-" "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)"
|
79
|
+
218.30.103.62 - - [04/Jan/2015:05:27:15 +0000] "GET /projects/fex/ HTTP/1.1" 200 14352 "-" "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)"
|
80
|
+
74.125.40.20 - - [04/Jan/2015:05:27:22 +0000] "GET /?flav=rss20 HTTP/1.1" 200 29941 "-" "FeedBurner/1.0 (http://www.FeedBurner.com)"
|
81
|
+
71.212.224.97 - - [04/Jan/2015:05:27:34 +0000] "GET /projects/xdotool/ HTTP/1.1" 200 12292 "http://suckless.org/rocks" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
|
82
|
+
71.212.224.97 - - [04/Jan/2015:05:27:34 +0000] "GET /reset.css HTTP/1.1" 200 1015 "http://www.semicomplete.com/projects/xdotool/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
|
83
|
+
71.212.224.97 - - [04/Jan/2015:05:27:35 +0000] "GET /style2.css HTTP/1.1" 200 4877 "http://www.semicomplete.com/projects/xdotool/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
|
84
|
+
71.212.224.97 - - [04/Jan/2015:05:27:35 +0000] "GET /images/jordan-80.png HTTP/1.1" 200 6146 "http://www.semicomplete.com/projects/xdotool/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
|
85
|
+
71.212.224.97 - - [04/Jan/2015:05:27:35 +0000] "GET /images/web/2009/banner.png HTTP/1.1" 200 52315 "http://www.semicomplete.com/projects/xdotool/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
|
86
|
+
218.30.103.62 - - [04/Jan/2015:05:27:36 +0000] "GET /projects/xdotool/xdotool.xhtml HTTP/1.1" 304 - "-" "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)"
|
87
|
+
108.174.55.234 - - [04/Jan/2015:05:27:45 +0000] "GET /?flav=rss20 HTTP/1.1" 200 29941 "-" "-"
|
88
|
+
218.30.103.62 - - [04/Jan/2015:05:27:57 +0000] "GET /blog/geekery/c-vs-python-bdb.html HTTP/1.1" 200 11388 "-" "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)"
|
89
|
+
121.107.188.202 - - [04/Jan/2015:05:27:57 +0000] "GET /presentations/logstash-monitorama-2013/images/kibana-dashboard3.png HTTP/1.1" 200 171717 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36"
|
90
|
+
218.30.103.62 - - [04/Jan/2015:05:28:21 +0000] "GET /blog/productivity/better-zsh-xterm-title-fix.html HTTP/1.1" 200 10185 "-" "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)"
|
91
|
+
218.30.103.62 - - [04/Jan/2015:05:28:43 +0000] "GET /blog/geekery/xvfb-firefox.html HTTP/1.1" 200 10975 "-" "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)"
|
92
|
+
218.30.103.62 - - [04/Jan/2015:05:29:06 +0000] "GET /blog/geekery/puppet-facts-into-mcollective.html HTTP/1.1" 200 9872 "-" "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)"
|
93
|
+
198.46.149.143 - - [04/Jan/2015:05:29:13 +0000] "GET /blog/geekery/disabling-battery-in-ubuntu-vms.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+semicomplete%2Fmain+%28semicomplete.com+-+Jordan+Sissel%29 HTTP/1.1" 200 9316 "-" "Tiny Tiny RSS/1.11 (http://tt-rss.org/)"
|
94
|
+
198.46.149.143 - - [04/Jan/2015:05:29:13 +0000] "GET /blog/geekery/solving-good-or-bad-problems.html?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+semicomplete%2Fmain+%28semicomplete.com+-+Jordan+Sissel%29 HTTP/1.1" 200 10756 "-" "Tiny Tiny RSS/1.11 (http://tt-rss.org/)"
|
95
|
+
218.30.103.62 - - [04/Jan/2015:05:29:26 +0000] "GET /blog/geekery/jquery-interface-puffer.html%20target= HTTP/1.1" 200 202 "-" "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)"
|
96
|
+
218.30.103.62 - - [04/Jan/2015:05:29:48 +0000] "GET /blog/geekery/ec2-reserved-vs-ondemand.html HTTP/1.1" 200 11834 "-" "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)"
|
97
|
+
66.249.73.135 - - [04/Jan/2015:05:30:06 +0000] "GET /blog/web/firefox-scrolling-fix.html HTTP/1.1" 200 8956 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
|
98
|
+
86.1.76.62 - - [04/Jan/2015:05:30:37 +0000] "GET /projects/xdotool/ HTTP/1.1" 200 12292 "http://www.haskell.org/haskellwiki/Xmonad/Frequently_asked_questions" "Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20140205 Firefox/24.0 Iceweasel/24.3.0"
|
99
|
+
86.1.76.62 - - [04/Jan/2015:05:30:37 +0000] "GET /reset.css HTTP/1.1" 200 1015 "http://www.semicomplete.com/projects/xdotool/" "Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20140205 Firefox/24.0 Iceweasel/24.3.0"
|
100
|
+
86.1.76.62 - - [04/Jan/2015:05:30:37 +0000] "GET /style2.css HTTP/1.1" 200 4877 "http://www.semicomplete.com/projects/xdotool/" "Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20140205 Firefox/24.0 Iceweasel/24.3.0"
|
Binary file
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/devutils/rspec/spec_helper"
|
3
|
+
require "logstash/inputs/qingstor"
|
4
|
+
require_relative "./qs_access_helper"
|
5
|
+
require "tmpdir"
|
6
|
+
|
7
|
+
describe LogStash::Inputs::Qingstor do
|
8
|
+
|
9
|
+
before do
|
10
|
+
Thread.abort_on_exception = true
|
11
|
+
|
12
|
+
upload_file("../fixtures/logstash.log", "log3.log")
|
13
|
+
upload_file("../fixtures/logstash.log.gz", "log3.log.gz")
|
14
|
+
end
|
15
|
+
|
16
|
+
after do
|
17
|
+
delete_remote_file "log3.log"
|
18
|
+
delete_remote_file "log3.log.gz"
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:config) { {
|
22
|
+
"access_key_id" => ENV['access_key_id'],
|
23
|
+
"secret_access_key" => ENV['secret_access_key'],
|
24
|
+
"bucket" => ENV['bucket'],
|
25
|
+
"region" => ENV['region']
|
26
|
+
} }
|
27
|
+
let(:key1) { "log3.log" }
|
28
|
+
let(:key2) { "log3.log.gz" }
|
29
|
+
let(:backup) { "logstash-backup" }
|
30
|
+
let(:local_backup_dir) { File.join(Dir.tmpdir, backup) }
|
31
|
+
|
32
|
+
context "local backup" do
|
33
|
+
it "backup to local dir" do
|
34
|
+
fetch_events(config.merge({"local_dir" => local_backup_dir }))
|
35
|
+
expect(File.exists?(File.join(local_backup_dir, key1))).to be_truthy
|
36
|
+
expect(File.exists?(File.join(local_backup_dir, key2))).to be_truthy
|
37
|
+
end
|
38
|
+
|
39
|
+
after do
|
40
|
+
FileUtils.rm_r(File.join(local_backup_dir, key1))
|
41
|
+
FileUtils.rm_r(File.join(local_backup_dir, key2))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "remote backup" do
|
46
|
+
it "backup to another bucket" do
|
47
|
+
fetch_events(config.merge({"backup_bucket" => backup}))
|
48
|
+
expect(list_remote_file(backup).size).to eq(2)
|
49
|
+
end
|
50
|
+
|
51
|
+
after do
|
52
|
+
delete_bucket(backup)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context ""
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/devutils/rspec/spec_helper"
|
3
|
+
require "logstash/inputs/qingstor"
|
4
|
+
|
5
|
+
describe LogStash::Inputs::Qingstor do
|
6
|
+
let(:config) { {
|
7
|
+
"access_key_id" => ENV['access_key_id'],
|
8
|
+
"secret_access_key" => ENV['secret_access_key'],
|
9
|
+
"bucket" => ENV['bucket'],
|
10
|
+
"region" => ENV['region']
|
11
|
+
} }
|
12
|
+
|
13
|
+
it "raise error if it has incorrect key id or access key" do
|
14
|
+
config["access_key_id"] = "wrongid"
|
15
|
+
expect{ described_class.new(config).register }.to raise_error(LogStash::ConfigurationError)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "raise error if it has incorrect key id or access key" do
|
19
|
+
config["secret_access_key"] = "wrongaccesskey"
|
20
|
+
expect{ described_class.new(config).register }.to raise_error(LogStash::ConfigurationError)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "raise error if it has incorrect bucket/region name" do
|
24
|
+
config["bucket"] = "wrongbucket"
|
25
|
+
expect{ described_class.new(config).register }.to raise_error(LogStash::ConfigurationError)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "raise error if it has incorrect bucket/region name" do
|
29
|
+
config["region"] = "wrongregion"
|
30
|
+
expect{ described_class.new(config).register }.to raise_error(LogStash::ConfigurationError)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "use default region if it is not set" do
|
34
|
+
config.delete("region")
|
35
|
+
expect(described_class.new(config).register ).to be_truthy
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
def fetch_events(settings)
|
2
|
+
queue = []
|
3
|
+
qs = LogStash::Inputs::Qingstor.new(settings)
|
4
|
+
qs.register
|
5
|
+
qs.process_files(queue)
|
6
|
+
queue
|
7
|
+
end
|
8
|
+
|
9
|
+
def qs_init_config(access_key_id = ENV['access_key_id'],
|
10
|
+
secret_access_key = ENV['secret_access_key'])
|
11
|
+
return QingStor::SDK::Config.init access_key_id, secret_access_key
|
12
|
+
end
|
13
|
+
|
14
|
+
def qs_init_bucket(bucket = ENV['bucket'], region = ENV['region'])
|
15
|
+
config = qs_init_config
|
16
|
+
properties = {'bucket-name' => bucket, 'zone' => region }
|
17
|
+
return QingStor::SDK::Bucket.new(config, properties)
|
18
|
+
end
|
19
|
+
|
20
|
+
def upload_file(local_file, remote_file)
|
21
|
+
bucket = qs_init_bucket
|
22
|
+
file = File.expand_path(File.join(File.dirname(__FILE__), local_file))
|
23
|
+
md5_string = Digest::MD5.file(file).to_s
|
24
|
+
bucket.put_object remote_file, {
|
25
|
+
'content_md5' => md5_string,
|
26
|
+
'body' => File.open(file)
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def delete_remote_file(key)
|
31
|
+
bucket = qs_init_bucket
|
32
|
+
bucket.delete_object key
|
33
|
+
end
|
34
|
+
|
35
|
+
def list_remote_file(bucket = ENV['bucket'], region = ENV['region'])
|
36
|
+
bucket = qs_init_bucket(bucket, region)
|
37
|
+
return bucket.list_objects[:keys]
|
38
|
+
end
|
39
|
+
|
40
|
+
def delete_bucket(bucket)
|
41
|
+
bucket = qs_init_bucket(bucket)
|
42
|
+
bucket.delete
|
43
|
+
end
|
metadata
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: logstash-input-qingstor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Evan Zhao
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-03-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '1.6'
|
19
|
+
- - "<="
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.99'
|
22
|
+
name: logstash-core-plugin-api
|
23
|
+
prerelease: false
|
24
|
+
type: :runtime
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.6'
|
30
|
+
- - "<="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.99'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
name: logstash-codec-plain
|
40
|
+
prerelease: false
|
41
|
+
type: :runtime
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 0.0.22
|
53
|
+
name: stud
|
54
|
+
prerelease: false
|
55
|
+
type: :runtime
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 0.0.22
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - '='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 1.9.2
|
67
|
+
name: qingstor-sdk
|
68
|
+
prerelease: false
|
69
|
+
type: :runtime
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - '='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 1.9.2
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
requirement: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
name: logstash-devutils
|
82
|
+
prerelease: false
|
83
|
+
type: :development
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
description: Use this plugin to fetch file as a input of logstash from QingStor
|
90
|
+
email: tacingiht@gmail.com
|
91
|
+
executables: []
|
92
|
+
extensions: []
|
93
|
+
extra_rdoc_files: []
|
94
|
+
files:
|
95
|
+
- CHANGELOG.md
|
96
|
+
- CODE_OF_CONDUCT.md
|
97
|
+
- CONTRIBUTING.md
|
98
|
+
- CONTRIBUTORS
|
99
|
+
- DEVELOPER.md
|
100
|
+
- Gemfile
|
101
|
+
- LICENSE
|
102
|
+
- README.md
|
103
|
+
- lib/logstash/inputs/qingstor.rb
|
104
|
+
- lib/logstash/inputs/qingstor/qingstor_validator.rb
|
105
|
+
- logstash-input-qingstor.gemspec
|
106
|
+
- spec/fixtures/logstash.log
|
107
|
+
- spec/fixtures/logstash.log.gz
|
108
|
+
- spec/inputs/qingstor_spec.rb
|
109
|
+
- spec/inputs/qingstor_spec_validator_spec.rb
|
110
|
+
- spec/inputs/qs_access_helper.rb
|
111
|
+
homepage: https://github.com/Tacinight/logstash-input-qingstor
|
112
|
+
licenses:
|
113
|
+
- Apache License (2.0)
|
114
|
+
metadata:
|
115
|
+
logstash_plugin: 'true'
|
116
|
+
logstash_group: input
|
117
|
+
post_install_message:
|
118
|
+
rdoc_options: []
|
119
|
+
require_paths:
|
120
|
+
- lib
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
requirements: []
|
132
|
+
rubyforge_project:
|
133
|
+
rubygems_version: 2.4.8
|
134
|
+
signing_key:
|
135
|
+
specification_version: 4
|
136
|
+
summary: logstash input plugin for QingStor
|
137
|
+
test_files:
|
138
|
+
- spec/fixtures/logstash.log
|
139
|
+
- spec/fixtures/logstash.log.gz
|
140
|
+
- spec/inputs/qingstor_spec.rb
|
141
|
+
- spec/inputs/qingstor_spec_validator_spec.rb
|
142
|
+
- spec/inputs/qs_access_helper.rb
|