logstash-output-oss 0.1.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +2 -0
  3. data/CONTRIBUTORS +10 -0
  4. data/DEVELOPER.md +10 -0
  5. data/Gemfile +2 -0
  6. data/LICENSE +11 -0
  7. data/README.md +149 -0
  8. data/lib/com/aliyun/aliyun-java-sdk-core/3.4.0/aliyun-java-sdk-core-3.4.0.jar +0 -0
  9. data/lib/com/aliyun/aliyun-java-sdk-ecs/4.2.0/aliyun-java-sdk-ecs-4.2.0.jar +0 -0
  10. data/lib/com/aliyun/aliyun-java-sdk-ram/3.0.0/aliyun-java-sdk-ram-3.0.0.jar +0 -0
  11. data/lib/com/aliyun/aliyun-java-sdk-sts/3.0.0/aliyun-java-sdk-sts-3.0.0.jar +0 -0
  12. data/lib/com/aliyun/oss/aliyun-sdk-oss/3.4.0/aliyun-sdk-oss-3.4.0.jar +0 -0
  13. data/lib/com/sun/jersey/jersey-core/1.9/jersey-core-1.9.jar +0 -0
  14. data/lib/com/sun/jersey/jersey-json/1.9/jersey-json-1.9.jar +0 -0
  15. data/lib/com/sun/xml/bind/jaxb-impl/2.2.3-1/jaxb-impl-2.2.3-1.jar +0 -0
  16. data/lib/commons-codec/commons-codec/1.9/commons-codec-1.9.jar +0 -0
  17. data/lib/commons-logging/commons-logging/1.2/commons-logging-1.2.jar +0 -0
  18. data/lib/javax/activation/activation/1.1/activation-1.1.jar +0 -0
  19. data/lib/javax/xml/bind/jaxb-api/2.2.2/jaxb-api-2.2.2.jar +0 -0
  20. data/lib/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2.jar +0 -0
  21. data/lib/logstash-output-oss_jars.rb +52 -0
  22. data/lib/logstash/outputs/oss.rb +288 -0
  23. data/lib/logstash/outputs/oss/file_generator.rb +69 -0
  24. data/lib/logstash/outputs/oss/file_manager.rb +87 -0
  25. data/lib/logstash/outputs/oss/file_uploader.rb +69 -0
  26. data/lib/logstash/outputs/oss/gzip_file.rb +36 -0
  27. data/lib/logstash/outputs/oss/rotations/hybrid_rotation.rb +24 -0
  28. data/lib/logstash/outputs/oss/rotations/size_based_rotation.rb +25 -0
  29. data/lib/logstash/outputs/oss/rotations/time_based_rotation.rb +25 -0
  30. data/lib/logstash/outputs/oss/temporary_file.rb +59 -0
  31. data/lib/logstash/outputs/oss/version.rb +14 -0
  32. data/lib/org/apache/httpcomponents/httpclient/4.4.1/httpclient-4.4.1.jar +0 -0
  33. data/lib/org/apache/httpcomponents/httpcore/4.4.1/httpcore-4.4.1.jar +0 -0
  34. data/lib/org/codehaus/jackson/jackson-core-asl/1.8.3/jackson-core-asl-1.8.3.jar +0 -0
  35. data/lib/org/codehaus/jackson/jackson-jaxrs/1.8.3/jackson-jaxrs-1.8.3.jar +0 -0
  36. data/lib/org/codehaus/jackson/jackson-mapper-asl/1.8.3/jackson-mapper-asl-1.8.3.jar +0 -0
  37. data/lib/org/codehaus/jackson/jackson-xc/1.8.3/jackson-xc-1.8.3.jar +0 -0
  38. data/lib/org/codehaus/jettison/jettison/1.1/jettison-1.1.jar +0 -0
  39. data/lib/org/jdom/jdom/1.1/jdom-1.1.jar +0 -0
  40. data/lib/stax/stax-api/1.0.1/stax-api-1.0.1.jar +0 -0
  41. data/logstash-output-oss.gemspec +30 -0
  42. data/spec/integration/common.rb +42 -0
  43. data/spec/integration/encoding_spec.rb +92 -0
  44. data/spec/integration/oss_spec.rb +47 -0
  45. data/spec/integration/recover_spec.rb +43 -0
  46. data/spec/outputs/oss/generator_spec.rb +67 -0
  47. data/spec/outputs/oss/rotation_spec.rb +69 -0
  48. data/spec/outputs/oss_spec.rb +58 -0
  49. 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
@@ -0,0 +1,2 @@
1
+ ## 0.1.1
2
+ - First release to support OSS
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
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
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.
@@ -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