logstash-output-oss 0.1.1-java
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/CONTRIBUTORS +10 -0
- data/DEVELOPER.md +10 -0
- data/Gemfile +2 -0
- data/LICENSE +11 -0
- data/README.md +149 -0
- data/lib/com/aliyun/aliyun-java-sdk-core/3.4.0/aliyun-java-sdk-core-3.4.0.jar +0 -0
- data/lib/com/aliyun/aliyun-java-sdk-ecs/4.2.0/aliyun-java-sdk-ecs-4.2.0.jar +0 -0
- data/lib/com/aliyun/aliyun-java-sdk-ram/3.0.0/aliyun-java-sdk-ram-3.0.0.jar +0 -0
- data/lib/com/aliyun/aliyun-java-sdk-sts/3.0.0/aliyun-java-sdk-sts-3.0.0.jar +0 -0
- data/lib/com/aliyun/oss/aliyun-sdk-oss/3.4.0/aliyun-sdk-oss-3.4.0.jar +0 -0
- data/lib/com/sun/jersey/jersey-core/1.9/jersey-core-1.9.jar +0 -0
- data/lib/com/sun/jersey/jersey-json/1.9/jersey-json-1.9.jar +0 -0
- data/lib/com/sun/xml/bind/jaxb-impl/2.2.3-1/jaxb-impl-2.2.3-1.jar +0 -0
- data/lib/commons-codec/commons-codec/1.9/commons-codec-1.9.jar +0 -0
- data/lib/commons-logging/commons-logging/1.2/commons-logging-1.2.jar +0 -0
- data/lib/javax/activation/activation/1.1/activation-1.1.jar +0 -0
- data/lib/javax/xml/bind/jaxb-api/2.2.2/jaxb-api-2.2.2.jar +0 -0
- data/lib/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2.jar +0 -0
- data/lib/logstash-output-oss_jars.rb +52 -0
- data/lib/logstash/outputs/oss.rb +288 -0
- data/lib/logstash/outputs/oss/file_generator.rb +69 -0
- data/lib/logstash/outputs/oss/file_manager.rb +87 -0
- data/lib/logstash/outputs/oss/file_uploader.rb +69 -0
- data/lib/logstash/outputs/oss/gzip_file.rb +36 -0
- data/lib/logstash/outputs/oss/rotations/hybrid_rotation.rb +24 -0
- data/lib/logstash/outputs/oss/rotations/size_based_rotation.rb +25 -0
- data/lib/logstash/outputs/oss/rotations/time_based_rotation.rb +25 -0
- data/lib/logstash/outputs/oss/temporary_file.rb +59 -0
- data/lib/logstash/outputs/oss/version.rb +14 -0
- data/lib/org/apache/httpcomponents/httpclient/4.4.1/httpclient-4.4.1.jar +0 -0
- data/lib/org/apache/httpcomponents/httpcore/4.4.1/httpcore-4.4.1.jar +0 -0
- data/lib/org/codehaus/jackson/jackson-core-asl/1.8.3/jackson-core-asl-1.8.3.jar +0 -0
- data/lib/org/codehaus/jackson/jackson-jaxrs/1.8.3/jackson-jaxrs-1.8.3.jar +0 -0
- data/lib/org/codehaus/jackson/jackson-mapper-asl/1.8.3/jackson-mapper-asl-1.8.3.jar +0 -0
- data/lib/org/codehaus/jackson/jackson-xc/1.8.3/jackson-xc-1.8.3.jar +0 -0
- data/lib/org/codehaus/jettison/jettison/1.1/jettison-1.1.jar +0 -0
- data/lib/org/jdom/jdom/1.1/jdom-1.1.jar +0 -0
- data/lib/stax/stax-api/1.0.1/stax-api-1.0.1.jar +0 -0
- data/logstash-output-oss.gemspec +30 -0
- data/spec/integration/common.rb +42 -0
- data/spec/integration/encoding_spec.rb +92 -0
- data/spec/integration/oss_spec.rb +47 -0
- data/spec/integration/recover_spec.rb +43 -0
- data/spec/outputs/oss/generator_spec.rb +67 -0
- data/spec/outputs/oss/rotation_spec.rb +69 -0
- data/spec/outputs/oss_spec.rb +58 -0
- metadata +206 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1d607407845973f61ed5a1db2e22fbf3d99f160131ce6d5b82b769ed2befc137
|
4
|
+
data.tar.gz: 3735dd4691fd97ee642bab10479ee08a574659c3658f99f620851d64d5e0710d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8bb4fd199bf14b90c6091256b2ce517ba9ebf41ebd9bee90d167489f4d80bfd54d9c94e13207b2391f0edb42d7cfc04067b27c6a190eda7d17976a56274e0c4e
|
7
|
+
data.tar.gz: d2113870411fe783374e66d20c5eb43ddd91f0bfdb94cda80bd329d767140c229a221a951f4be5dc0ba658ce3ac7bccaf22d1b977d802bf40c85f56f1dee1777
|
data/CHANGELOG.md
ADDED
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
|
+
* jinhu.wu - jinhu.wu.nju@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
@@ -0,0 +1,10 @@
|
|
1
|
+
# Running the tests
|
2
|
+
```bash
|
3
|
+
bundle install
|
4
|
+
bundle exec rspec
|
5
|
+
```
|
6
|
+
|
7
|
+
If you want to run the integration tests against a real bucket you need to pass your Aliyun credentials to the test runner or declare it in your environment.
|
8
|
+
```bash
|
9
|
+
OSS_ENDPOINT="Aliyun OSS endpoint to connect to" OSS_ACCESS_KEY="Your access key id" OSS_SECRET_KEY="Your access secret" OSS_BUCKET="Your bucket" bundle exec rspec spec/integration --tag integration
|
10
|
+
```
|
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,149 @@
|
|
1
|
+
# Logstash OSS Output Plugin
|
2
|
+
|
3
|
+
This is a plugin for [Logstash](https://github.com/elastic/logstash).
|
4
|
+
|
5
|
+
It is fully free and fully open source. The license is Apache 2.0, meaning you are pretty much free to use it however you want in whatever way.
|
6
|
+
|
7
|
+
## Documentation
|
8
|
+
This plugin batches and uploads logstash events into Aliyun Object Storage Service (Aliyun OSS).
|
9
|
+
|
10
|
+
First, you should have a writable bucket and OSS access permissions((Typically access_key_id and access_key_secret)).
|
11
|
+
|
12
|
+
OSS output plugin creates temporary files into the OS' temporary directory(You can set this configuration by **temporary_directory** option) before uploading them to OSS.
|
13
|
+
|
14
|
+
OSS output plugin output files have the following format
|
15
|
+
```bash
|
16
|
+
/tmp/logstash/oss/eaced620-e972-0136-2a14-02b7449ba0a9/logstash/1/ls.oss.eaced620-e972-0136-2a14-02b7449ba0a9.2018-12-24T14.27.part-0.data
|
17
|
+
```
|
18
|
+
|
19
|
+
|||
|
20
|
+
|---|---|
|
21
|
+
|/tmp/logstash/oss| OS' temporary directory specified by **temporary_directory** option |
|
22
|
+
|eaced620-e972-0136-2a14-02b7449ba0a9 | random uuid |
|
23
|
+
|logstash/1|OSS object prefix|
|
24
|
+
|ls.oss|indicate Logstash OSS output plugin|
|
25
|
+
|eaced620-e972-0136-2a14-02b7449ba0a9 | random uuid |
|
26
|
+
|2018-12-24T14.27 | represents the file created time |
|
27
|
+
|part-0|This is the nth file of this prefix|
|
28
|
+
|.data|output suffix, if you set `encoding` to gzip , it will ends with .gz, else ends with .data|
|
29
|
+
|
30
|
+
|
31
|
+
This plugin also supports crash recovery, you can set configuration **recover** to true if you want to recover from abnormal crash.
|
32
|
+
|
33
|
+
### Usage:
|
34
|
+
This is an example of logstash config:
|
35
|
+
```ruby
|
36
|
+
input {
|
37
|
+
file {
|
38
|
+
path => "/etc/logstash-6.5.3/sample.data"
|
39
|
+
codec => json {
|
40
|
+
charset => "UTF-8"
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
output {
|
46
|
+
oss {
|
47
|
+
"endpoint" => "oss-cn-zhangjiakou.aliyuncs.com" (required)
|
48
|
+
"bucket" => "Your bucket name" (required)
|
49
|
+
"access_key_id" => "Your access key id" (required)
|
50
|
+
"access_key_secret" => "Your access secret key" (required)
|
51
|
+
"prefix" => "logstash/%{index}" (optional, default = "")
|
52
|
+
"recover" => true (optional, default = true)
|
53
|
+
"rotation_strategy" => "size_and_time" (optional, default = "size_and_time")
|
54
|
+
"time_rotate" => 15 (optional, default = 15) - Minutes
|
55
|
+
"size_rotate" => 31457280 (optional, default = 31457280) - Bytes
|
56
|
+
"encoding" => "gzip" (optional, default = "none")
|
57
|
+
"additional_oss_settings" => {
|
58
|
+
"max_connections_to_oss" => 1024 (optional, default = 1024)
|
59
|
+
"secure_connection_enabled" => false (optional, default = true)
|
60
|
+
}
|
61
|
+
codec => json {
|
62
|
+
charset => "UTF-8"
|
63
|
+
}
|
64
|
+
}
|
65
|
+
}
|
66
|
+
```
|
67
|
+
|
68
|
+
### Logstash OSS Output Configuration Options
|
69
|
+
This plugin supports the following configuration options
|
70
|
+
|
71
|
+
|Configuration|Type|Required|Comments|
|
72
|
+
|:---:|:---:|:---:|:---|
|
73
|
+
|endpoint|string|Yes|OSS endpoint to connect|
|
74
|
+
|bucket|string|Yes|Your OSS bucket name|
|
75
|
+
|access_key_id|string|Yes|Your access key id|
|
76
|
+
|access_key_secret|string|Yes|Your access secret key|
|
77
|
+
|prefix|string|No|Prefix that added to the generated file name(WARNING: this option supports string interpolation, so it may create a lot of temporary local files)|
|
78
|
+
|additional_oss_settings|hash|No|Additional oss client configurations, valid keys are: `server_side_encryption_algorithm`, `secure_connection_enabled` and `max_connections_to_oss`|
|
79
|
+
|temporary_directory|string|No|Temporary directory that used to cache events before uploading to OSS, default is /{OS' tmp dir}/logstash/oss|
|
80
|
+
|rotation_strategy|string|No|File rotation strategy. Options are `size`, `time` and `size_and_time`|
|
81
|
+
|size_rotate|number|No|Rotate this file if its size greater than or equal to `size_rotate`(depends on `rotation_strategy`)|
|
82
|
+
|time_rotate|number|No|Rotate this file if its life time greater than or equal to `time_rotate`(depends on `rotation_strategy`)|
|
83
|
+
|upload_workers_count|number|No|Concurrent number of upload threads|
|
84
|
+
|upload_queue_size|number|No|Upload queue size|
|
85
|
+
|encoding|string|No|Support plain and gzip compression before uploading files to OSS. Options are `gzip` and `none`|
|
86
|
+
|
87
|
+
## Need Help?
|
88
|
+
|
89
|
+
Need help? Try #logstash on freenode IRC or the https://discuss.elastic.co/c/logstash discussion forum.
|
90
|
+
|
91
|
+
## Developing
|
92
|
+
|
93
|
+
### 1. Plugin Developement and Testing
|
94
|
+
|
95
|
+
#### Code
|
96
|
+
- To get started, you'll need JRuby with the Bundler gem installed.
|
97
|
+
|
98
|
+
- Install dependencies
|
99
|
+
```sh
|
100
|
+
bundle install
|
101
|
+
```
|
102
|
+
|
103
|
+
#### Test
|
104
|
+
|
105
|
+
- Update your dependencies
|
106
|
+
|
107
|
+
```sh
|
108
|
+
bundle install
|
109
|
+
```
|
110
|
+
|
111
|
+
- Run tests
|
112
|
+
|
113
|
+
```sh
|
114
|
+
bundle exec rspec
|
115
|
+
```
|
116
|
+
|
117
|
+
### 2. Running your unpublished Plugin in Logstash
|
118
|
+
|
119
|
+
#### 2.1 Run in an installed Logstash
|
120
|
+
|
121
|
+
you can build the gem and install it using:
|
122
|
+
|
123
|
+
- Build your plugin gem
|
124
|
+
|
125
|
+
```sh
|
126
|
+
gem build logstash-output-oss.gemspec
|
127
|
+
```
|
128
|
+
|
129
|
+
- Install the plugin from the Logstash home
|
130
|
+
|
131
|
+
```sh
|
132
|
+
bin/logstash-plugin install /path/to/logstash-output-oss-0.1.0-java.gem
|
133
|
+
```
|
134
|
+
|
135
|
+
- Start Logstash and proceed to test the plugin
|
136
|
+
|
137
|
+
```bash
|
138
|
+
./bin/logstash -f config/logstash-sample.conf
|
139
|
+
```
|
140
|
+
|
141
|
+
## Contributing
|
142
|
+
|
143
|
+
All contributions are welcome: ideas, patches, documentation, bug reports, complaints, and even something you drew up on a napkin.
|
144
|
+
|
145
|
+
Programming is not a required skill. Whatever you've seen about open source and maintainers or community members saying "send patches or die" - you will not see that here.
|
146
|
+
|
147
|
+
It is more important to the community that you are able to contribute.
|
148
|
+
|
149
|
+
For more information about contributing, see the [CONTRIBUTING](https://github.com/elastic/logstash/blob/master/CONTRIBUTING.md) file.
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# this is a generated file, to avoid over-writing it just delete this comment
|
2
|
+
begin
|
3
|
+
require 'jar_dependencies'
|
4
|
+
rescue LoadError
|
5
|
+
require 'org/apache/httpcomponents/httpcore/4.4.1/httpcore-4.4.1.jar'
|
6
|
+
require 'com/aliyun/oss/aliyun-sdk-oss/3.4.0/aliyun-sdk-oss-3.4.0.jar'
|
7
|
+
require 'commons-codec/commons-codec/1.9/commons-codec-1.9.jar'
|
8
|
+
require 'org/codehaus/jackson/jackson-xc/1.8.3/jackson-xc-1.8.3.jar'
|
9
|
+
require 'com/aliyun/aliyun-java-sdk-ram/3.0.0/aliyun-java-sdk-ram-3.0.0.jar'
|
10
|
+
require 'org/apache/httpcomponents/httpclient/4.4.1/httpclient-4.4.1.jar'
|
11
|
+
require 'javax/xml/bind/jaxb-api/2.2.2/jaxb-api-2.2.2.jar'
|
12
|
+
require 'com/sun/jersey/jersey-json/1.9/jersey-json-1.9.jar'
|
13
|
+
require 'org/codehaus/jettison/jettison/1.1/jettison-1.1.jar'
|
14
|
+
require 'com/sun/jersey/jersey-core/1.9/jersey-core-1.9.jar'
|
15
|
+
require 'javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2.jar'
|
16
|
+
require 'com/aliyun/aliyun-java-sdk-core/3.4.0/aliyun-java-sdk-core-3.4.0.jar'
|
17
|
+
require 'commons-logging/commons-logging/1.2/commons-logging-1.2.jar'
|
18
|
+
require 'org/codehaus/jackson/jackson-jaxrs/1.8.3/jackson-jaxrs-1.8.3.jar'
|
19
|
+
require 'javax/activation/activation/1.1/activation-1.1.jar'
|
20
|
+
require 'com/sun/xml/bind/jaxb-impl/2.2.3-1/jaxb-impl-2.2.3-1.jar'
|
21
|
+
require 'org/jdom/jdom/1.1/jdom-1.1.jar'
|
22
|
+
require 'org/codehaus/jackson/jackson-mapper-asl/1.8.3/jackson-mapper-asl-1.8.3.jar'
|
23
|
+
require 'org/codehaus/jackson/jackson-core-asl/1.8.3/jackson-core-asl-1.8.3.jar'
|
24
|
+
require 'com/aliyun/aliyun-java-sdk-ecs/4.2.0/aliyun-java-sdk-ecs-4.2.0.jar'
|
25
|
+
require 'com/aliyun/aliyun-java-sdk-sts/3.0.0/aliyun-java-sdk-sts-3.0.0.jar'
|
26
|
+
require 'stax/stax-api/1.0.1/stax-api-1.0.1.jar'
|
27
|
+
end
|
28
|
+
|
29
|
+
if defined? Jars
|
30
|
+
require_jar 'org.apache.httpcomponents', 'httpcore', '4.4.1'
|
31
|
+
require_jar 'com.aliyun.oss', 'aliyun-sdk-oss', '3.4.0'
|
32
|
+
require_jar 'commons-codec', 'commons-codec', '1.9'
|
33
|
+
require_jar 'org.codehaus.jackson', 'jackson-xc', '1.8.3'
|
34
|
+
require_jar 'com.aliyun', 'aliyun-java-sdk-ram', '3.0.0'
|
35
|
+
require_jar 'org.apache.httpcomponents', 'httpclient', '4.4.1'
|
36
|
+
require_jar 'javax.xml.bind', 'jaxb-api', '2.2.2'
|
37
|
+
require_jar 'com.sun.jersey', 'jersey-json', '1.9'
|
38
|
+
require_jar 'org.codehaus.jettison', 'jettison', '1.1'
|
39
|
+
require_jar 'com.sun.jersey', 'jersey-core', '1.9'
|
40
|
+
require_jar 'javax.xml.stream', 'stax-api', '1.0-2'
|
41
|
+
require_jar 'com.aliyun', 'aliyun-java-sdk-core', '3.4.0'
|
42
|
+
require_jar 'commons-logging', 'commons-logging', '1.2'
|
43
|
+
require_jar 'org.codehaus.jackson', 'jackson-jaxrs', '1.8.3'
|
44
|
+
require_jar 'javax.activation', 'activation', '1.1'
|
45
|
+
require_jar 'com.sun.xml.bind', 'jaxb-impl', '2.2.3-1'
|
46
|
+
require_jar 'org.jdom', 'jdom', '1.1'
|
47
|
+
require_jar 'org.codehaus.jackson', 'jackson-mapper-asl', '1.8.3'
|
48
|
+
require_jar 'org.codehaus.jackson', 'jackson-core-asl', '1.8.3'
|
49
|
+
require_jar 'com.aliyun', 'aliyun-java-sdk-ecs', '4.2.0'
|
50
|
+
require_jar 'com.aliyun', 'aliyun-java-sdk-sts', '3.0.0'
|
51
|
+
require_jar 'stax', 'stax-api', '1.0.1'
|
52
|
+
end
|
@@ -0,0 +1,288 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "logstash/outputs/base"
|
3
|
+
require 'logstash-output-oss_jars'
|
4
|
+
require 'concurrent'
|
5
|
+
|
6
|
+
java_import "com.aliyun.oss.OSS"
|
7
|
+
java_import "com.aliyun.oss.OSSClientBuilder"
|
8
|
+
java_import "com.aliyun.oss.ClientBuilderConfiguration"
|
9
|
+
|
10
|
+
#
|
11
|
+
# Logstash OSS Output Plugin
|
12
|
+
#
|
13
|
+
# Usage:
|
14
|
+
# In order to write output data to OSS, you should add configurations like below to logstash
|
15
|
+
# output {
|
16
|
+
# oss {
|
17
|
+
# "endpoint" => "oss-cn-zhangjiakou.aliyuncs.com" (required)
|
18
|
+
# "bucket" => "Your bucket name" (required)
|
19
|
+
# "access_key_id" => "Your access key id" (required)
|
20
|
+
# "access_key_secret" => "Your access secret key" (required)
|
21
|
+
# "prefix" => "logstash/%{index}" (optional, default = "")
|
22
|
+
# "recover" => true (optional, default = true)
|
23
|
+
# "rotation_strategy" => "size_and_time" (optional, default = "size_and_time")
|
24
|
+
# "time_rotate" => 15 (optional, default = 15) - Minutes
|
25
|
+
# "size_rotate" => 31457280 (optional, default = 31457280) - Bytes
|
26
|
+
# "encoding" => "none" (optional, default = "none")
|
27
|
+
# "additional_oss_settings" => {
|
28
|
+
# "max_connections_to_oss" => 1024 (optional, default = 1024)
|
29
|
+
# "secure_connection_enabled" => false (optional, default = true)
|
30
|
+
# }
|
31
|
+
# }
|
32
|
+
# }
|
33
|
+
#
|
34
|
+
class LogStash::Outputs::OSS < LogStash::Outputs::Base
|
35
|
+
require 'logstash/outputs/oss/rotations/hybrid_rotation'
|
36
|
+
require 'logstash/outputs/oss/file_uploader'
|
37
|
+
require 'logstash/outputs/oss/file_manager'
|
38
|
+
require 'logstash/outputs/oss/version'
|
39
|
+
|
40
|
+
ROTATE_CHECK_INTERVAL_IN_SECONDS = 15
|
41
|
+
|
42
|
+
MAX_CONNECTIONS_TO_OSS_KEY = "max_connections_to_oss"
|
43
|
+
|
44
|
+
SERVER_SIDE_ENCRYPTION_ALGORITHM_KEY = "server_side_encryption_algorithm"
|
45
|
+
|
46
|
+
SECURE_CONNECTION_ENABLED_KEY = "secure_connection_enabled"
|
47
|
+
|
48
|
+
config_name "oss"
|
49
|
+
|
50
|
+
concurrency :shared
|
51
|
+
|
52
|
+
default :codec, "line"
|
53
|
+
|
54
|
+
# OSS bucket name
|
55
|
+
config :bucket, :validate => :string, :required => true
|
56
|
+
|
57
|
+
# OSS endpoint to connect
|
58
|
+
config :endpoint, :validate => :string, :required => true
|
59
|
+
|
60
|
+
# access key id
|
61
|
+
config :access_key_id, :validate => :string, :required => true
|
62
|
+
|
63
|
+
# access secret key
|
64
|
+
config :access_key_secret, :validate => :string, :required => true
|
65
|
+
|
66
|
+
# additional oss client configurations, valid keys are:
|
67
|
+
# server_side_encryption_algorithm(server side encryption, only support AES256 now)
|
68
|
+
# secure_connection_enabled(enable https or not)
|
69
|
+
# max_connections_to_oss(max connections to oss)
|
70
|
+
# TODO: add other oss configurations
|
71
|
+
config :additional_oss_settings, :validate => :hash, :required => false
|
72
|
+
|
73
|
+
# rotate this file if its size greater or equal than `size_rotate`
|
74
|
+
config :size_rotate, :validate => :number, :default => 30 * 1024 * 1024
|
75
|
+
|
76
|
+
# rotate this file if its life time greater or equal than `time_rotate`
|
77
|
+
config :time_rotate, :validate => :number, :default => 15
|
78
|
+
|
79
|
+
# if true, OSS plugin will recover files since last crash
|
80
|
+
config :recover, :validate => :boolean, :default => true
|
81
|
+
|
82
|
+
# temporary directory that used to cache event before upload to OSS
|
83
|
+
config :temporary_directory, :validate => :string, :default => File.join(Dir.tmpdir, "logstash/oss")
|
84
|
+
|
85
|
+
# prefix that added to generated file name
|
86
|
+
# sample file name looks like
|
87
|
+
# `prefix`/logstash.oss.{random-uuid}.{%Y-%m-%dT%H.%M}.part-{index}.{extension}
|
88
|
+
# WARNING: this option support string interpolation, so it may create a lot of temporary local files
|
89
|
+
config :prefix, :validate => :string, :default => ''
|
90
|
+
|
91
|
+
# file rotation strategy
|
92
|
+
config :rotation_strategy, :validate => %w(size time size_and_time), :default => "size_and_time"
|
93
|
+
|
94
|
+
# concurrent number of upload threads
|
95
|
+
config :upload_workers_count, :validate => :number, :default => (Concurrent.processor_count * 0.5).ceil
|
96
|
+
|
97
|
+
# upload queue size
|
98
|
+
config :upload_queue_size, :validate => :number, :default => 2 * (Concurrent.processor_count * 0.25).ceil
|
99
|
+
|
100
|
+
# support plain and gzip compression before upload to OSS
|
101
|
+
config :encoding, :validate => %w(none gzip), :default => "none"
|
102
|
+
|
103
|
+
public
|
104
|
+
def register
|
105
|
+
# TODO: check if prefix is valid
|
106
|
+
|
107
|
+
# check if temporary_directory is writable
|
108
|
+
begin
|
109
|
+
FileUtils.mkdir_p(@temporary_directory) unless Dir.exist?(@temporary_directory)
|
110
|
+
::File.writable?(@temporary_directory)
|
111
|
+
rescue
|
112
|
+
raise LogStash::ConfigurationError, "Logstash OSS Output Plugin can not write data to " + @temporary_directory
|
113
|
+
end
|
114
|
+
|
115
|
+
# check rotation configuration
|
116
|
+
if @size_rotate.nil? and @time_rotate.nil? || @size_rotate <= 0 && @time_rotate <= 0
|
117
|
+
raise LogStash::ConfigurationError, "Logstash OSS Output Plugin must have at least one of time_file or size_file set to a value greater than 0"
|
118
|
+
end
|
119
|
+
|
120
|
+
if @upload_workers_count <= 0 || @upload_queue_size <= 0
|
121
|
+
raise LogStash::ConfigurationError, "Logstash OSS Output Plugin must have both upload_workers_count and upload_queue_size are positive"
|
122
|
+
end
|
123
|
+
|
124
|
+
# create upload thread pool
|
125
|
+
executor = Concurrent::ThreadPoolExecutor.new({ :min_threads => 1,
|
126
|
+
:max_threads => @upload_workers_count,
|
127
|
+
:max_queue => @upload_queue_size,
|
128
|
+
:fallback_policy => :caller_runs })
|
129
|
+
|
130
|
+
# get file rotation strategy
|
131
|
+
@rotation = rotation
|
132
|
+
|
133
|
+
# initialize oss client
|
134
|
+
@oss = initialize_oss_client
|
135
|
+
|
136
|
+
# initialize file uploader
|
137
|
+
@file_uploader = FileUploader.new(@oss, @bucket, @additional_oss_settings, @logger, executor)
|
138
|
+
|
139
|
+
# initialize file manager
|
140
|
+
@file_manager = FileManager.new(@logger, @encoding, @temporary_directory)
|
141
|
+
|
142
|
+
# recover from crash
|
143
|
+
recover_from_crash if @recover
|
144
|
+
|
145
|
+
# start rotate check
|
146
|
+
start_rotate_check if @rotation.needs_periodic_check?
|
147
|
+
end # def register
|
148
|
+
|
149
|
+
public
|
150
|
+
def multi_receive_encoded(events_and_encoded)
|
151
|
+
prefixes = Set.new
|
152
|
+
events_and_encoded.each do |event, encoded|
|
153
|
+
prefix = event.sprintf(@prefix)
|
154
|
+
prefixes << prefix
|
155
|
+
|
156
|
+
begin
|
157
|
+
@file_manager.get_file_generator(prefix) { |generator| generator.current_file.write(encoded) }
|
158
|
+
rescue Errno::ENOSPC => e
|
159
|
+
@logger.error("Logstash OSS Output Plugin: No space left in temporary directory", :temporary_directory => @temporary_directory)
|
160
|
+
raise e
|
161
|
+
end
|
162
|
+
end
|
163
|
+
rotate(prefixes)
|
164
|
+
end
|
165
|
+
|
166
|
+
def close
|
167
|
+
@logger.info("Logstash OSS Output Plugin is shutting down...")
|
168
|
+
|
169
|
+
# stop rotate check
|
170
|
+
stop_rotate_check if @rotation.needs_periodic_check?
|
171
|
+
|
172
|
+
prefixes = @file_manager.prefixes
|
173
|
+
prefixes.each do |prefix|
|
174
|
+
@file_manager.get_file_generator(prefix) do |generator|
|
175
|
+
file = generator.current_file
|
176
|
+
file.close
|
177
|
+
if file.size > 0
|
178
|
+
# upload async
|
179
|
+
@file_uploader.upload_async(file, :on_complete => method(:clean_temporary_file))
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
@file_manager.close
|
185
|
+
|
186
|
+
# stop file uploader
|
187
|
+
@file_uploader.close
|
188
|
+
|
189
|
+
# stop oss client
|
190
|
+
@oss.shutdown
|
191
|
+
end
|
192
|
+
|
193
|
+
private
|
194
|
+
def initialize_oss_client
|
195
|
+
clientConf = ClientBuilderConfiguration.new
|
196
|
+
unless @additional_oss_settings.nil?
|
197
|
+
if @additional_oss_settings.include?(SECURE_CONNECTION_ENABLED_KEY)
|
198
|
+
clientConf.setProtocol(@additional_oss_settings[SECURE_CONNECTION_ENABLED_KEY] ?
|
199
|
+
com.aliyun.oss.common.comm.Protocol::HTTPS : com.aliyun.oss.common.comm.Protocol::HTTP)
|
200
|
+
end
|
201
|
+
|
202
|
+
if @additional_oss_settings.include?(MAX_CONNECTIONS_TO_OSS_KEY)
|
203
|
+
if @additional_oss_settings[MAX_CONNECTIONS_TO_OSS_KEY] <= 0
|
204
|
+
raise LogStash::ConfigurationError, "Logstash OSS output plugin must have positive " + MAX_CONNECTIONS_TO_OSS_KEY
|
205
|
+
end
|
206
|
+
clientConf.setMaxConnections(@additional_oss_settings[MAX_CONNECTIONS_TO_OSS_KEY])
|
207
|
+
else
|
208
|
+
clientConf.setMaxConnections(1024)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
clientConf.setUserAgent(clientConf.getUserAgent() + ", Logstash-oss/" + Version.version)
|
213
|
+
OSSClientBuilder.new().build(@endpoint, @access_key_id, @access_key_secret, clientConf)
|
214
|
+
end
|
215
|
+
|
216
|
+
private
|
217
|
+
def rotation
|
218
|
+
case @rotation_strategy
|
219
|
+
when "size"
|
220
|
+
SizeBasedRotation.new(size_rotate)
|
221
|
+
when "time"
|
222
|
+
TimeBasedRotation.new(time_rotate)
|
223
|
+
when "size_and_time"
|
224
|
+
HybridRotation.new(size_rotate, time_rotate)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
private
|
229
|
+
def recover_from_crash
|
230
|
+
@logger.info("Logstash OSS Output Plugin starts to recover from crash and uploading...")
|
231
|
+
Dir.glob(::File.join(@temporary_directory, "**/*"))
|
232
|
+
.select {|file| ::File.file?(file) }
|
233
|
+
.each do |file|
|
234
|
+
temporary_file = TemporaryFile.create_existing_file(file, @temporary_directory)
|
235
|
+
if temporary_file.size > 0
|
236
|
+
@file_uploader.upload_async(temporary_file, :on_complete => method(:clean_temporary_file))
|
237
|
+
else
|
238
|
+
clean_temporary_file(temporary_file)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
private
|
244
|
+
def rotate(prefixes)
|
245
|
+
prefixes.each do |prefix|
|
246
|
+
@file_manager.get_file_generator(prefix) do |file_generator|
|
247
|
+
file = file_generator.current_file
|
248
|
+
if @rotation.rotate?(file)
|
249
|
+
@logger.info("Logstash OSS Output Plugin starts to rotate file",
|
250
|
+
:strategy => @rotation.class.name,
|
251
|
+
:key => file.key,
|
252
|
+
:path => file.path,
|
253
|
+
:size => file.size,
|
254
|
+
:thread => Thread.current.to_s)
|
255
|
+
file.close
|
256
|
+
if file.size > 0
|
257
|
+
# upload async
|
258
|
+
@file_uploader.upload_async(file, :on_complete => method(:clean_temporary_file))
|
259
|
+
end
|
260
|
+
file_generator.rotate
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
private
|
267
|
+
def clean_temporary_file(file)
|
268
|
+
@logger.debug("Logstash OSS Output Plugin: starts to remove temporary file",
|
269
|
+
:file => file.path)
|
270
|
+
file.delete!
|
271
|
+
end
|
272
|
+
|
273
|
+
private
|
274
|
+
def start_rotate_check
|
275
|
+
@rotate_check = Concurrent::TimerTask.new(:execution_interval => ROTATE_CHECK_INTERVAL_IN_SECONDS) do
|
276
|
+
@logger.debug("Logstash OSS Output Plugin: starts rotation check")
|
277
|
+
|
278
|
+
rotate(@file_manager.prefixes)
|
279
|
+
end
|
280
|
+
|
281
|
+
@rotate_check.execute
|
282
|
+
end
|
283
|
+
|
284
|
+
private
|
285
|
+
def stop_rotate_check
|
286
|
+
@rotate_check.shutdown
|
287
|
+
end
|
288
|
+
end # class LogStash::Outputs::OSS
|